annotate vmdav.c @ 2809:75400dfbe117 libavcodec

fixing colocated mv if colocated block is L1 predicted for the temporal direct case untested (none of the conformance streams laying around on my disk seems affected by this change)
author michael
date Wed, 27 Jul 2005 00:15:55 +0000
parents 4bdd4927d2fc
children 9ff4c2733422
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
1 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
2 * Sierra VMD Audio & Video Decoders
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
3 * Copyright (C) 2004 the ffmpeg project
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
4 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
9 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
13 * Lesser General Public License for more details.
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
14 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
18 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
19 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
20
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
21 /**
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
22 * @file vmdvideo.c
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
23 * Sierra VMD audio & video decoders
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
24 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
25 * for more information on the Sierra VMD format, visit:
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
26 * http://www.pcisys.net/~melanson/codecs/
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
27 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
28 * The video decoder outputs PAL8 colorspace data. The decoder expects
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
29 * a 0x330-byte VMD file header to be transmitted via extradata during
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
30 * codec initialization. Each encoded frame that is sent to this decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
31 * is expected to be prepended with the appropriate 16-byte frame
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
32 * information record from the VMD file.
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
33 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
34 * The audio decoder, like the video decoder, expects each encoded data
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
35 * chunk to be prepended with the appropriate 16-byte frame information
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
36 * record from the VMD file. It does not require the 0x330-byte VMD file
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
37 * header, but it does need the audio setup parameters passed in through
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
38 * normal libavcodec API means.
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
39 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
40
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
41 #include <stdio.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
42 #include <stdlib.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
43 #include <string.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
44 #include <unistd.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
45
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
46 #include "common.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
47 #include "avcodec.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
48 #include "dsputil.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
49
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
50 #define VMD_HEADER_SIZE 0x330
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
51 #define PALETTE_COUNT 256
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
52
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
53 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
54 * Video Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
55 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
56
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
57 typedef struct VmdVideoContext {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
58
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
59 AVCodecContext *avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
60 DSPContext dsp;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
61 AVFrame frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
62 AVFrame prev_frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
63
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
64 unsigned char *buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
65 int size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
66
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
67 unsigned char palette[PALETTE_COUNT * 4];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
68 unsigned char *unpack_buffer;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
69
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
70 } VmdVideoContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
71
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
72 #define QUEUE_SIZE 0x1000
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
73 #define QUEUE_MASK 0x0FFF
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
74
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
75 static void lz_unpack(unsigned char *src, unsigned char *dest)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
76 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
77 unsigned char *s;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
78 unsigned char *d;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
79 unsigned char queue[QUEUE_SIZE];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
80 unsigned int qpos;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
81 unsigned int dataleft;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
82 unsigned int chainofs;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
83 unsigned int chainlen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
84 unsigned int speclen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
85 unsigned char tag;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
86 unsigned int i, j;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
87
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
88 s = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
89 d = dest;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
90 dataleft = LE_32(s);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
91 s += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
92 memset(queue, QUEUE_SIZE, 0x20);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
93 if (LE_32(s) == 0x56781234) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
94 s += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
95 qpos = 0x111;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
96 speclen = 0xF + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
97 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
98 qpos = 0xFEE;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
99 speclen = 100; /* no speclen */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
100 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
101
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
102 while (dataleft > 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
103 tag = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
104 if ((tag == 0xFF) && (dataleft > 8)) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
105 for (i = 0; i < 8; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
106 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
107 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
108 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
109 dataleft -= 8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
110 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
111 for (i = 0; i < 8; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
112 if (dataleft == 0)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
113 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
114 if (tag & 0x01) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
115 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
116 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
117 dataleft--;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
118 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
119 chainofs = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
120 chainofs |= ((*s & 0xF0) << 4);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
121 chainlen = (*s++ & 0x0F) + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
122 if (chainlen == speclen)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
123 chainlen = *s++ + 0xF + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
124 for (j = 0; j < chainlen; j++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
125 *d = queue[chainofs++ & QUEUE_MASK];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
126 queue[qpos++] = *d++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
127 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
128 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
129 dataleft -= chainlen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
130 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
131 tag >>= 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
132 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
133 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
134 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
135 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
136
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
137 static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
138 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
139 unsigned char *ps;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
140 unsigned char *pd;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
141 int i, l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
142
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
143 ps = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
144 pd = dest;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
145 if (len & 1)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
146 *pd++ = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
147
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
148 len >>= 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
149 i = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
150 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
151 l = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
152 if (l & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
153 l = (l & 0x7F) * 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
154 memcpy(pd, ps, l);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
155 ps += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
156 pd += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
157 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
158 for (i = 0; i < l; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
159 *pd++ = ps[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
160 *pd++ = ps[1];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
161 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
162 ps += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
163 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
164 i += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
165 } while (i < len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
166
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
167 return (ps - src);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
168 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
169
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
170 static void vmd_decode(VmdVideoContext *s)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
171 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
172 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
173 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
174 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
175
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
176 /* point to the start of the encoded data */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
177 unsigned char *p = s->buf + 16;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
178
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
179 unsigned char *pb;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
180 unsigned char meth;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
181 unsigned char *dp; /* pointer to current frame */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
182 unsigned char *pp; /* pointer to previous frame */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
183 unsigned char len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
184 int ofs;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
185
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
186 int frame_x, frame_y;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
187 int frame_width, frame_height;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
188
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
189 frame_x = LE_16(&s->buf[6]);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
190 frame_y = LE_16(&s->buf[8]);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
191 frame_width = LE_16(&s->buf[10]) - frame_x + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
192 frame_height = LE_16(&s->buf[12]) - frame_y + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
193
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
194 /* if only a certain region will be updated, copy the entire previous
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
195 * frame before the decode */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
196 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
197 (frame_height != s->avctx->height)) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
198
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
199 memcpy(s->frame.data[0], s->prev_frame.data[0],
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
200 s->avctx->height * s->frame.linesize[0]);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
201 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
202
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
203 /* check if there is a new palette */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
204 if (s->buf[15] & 0x02) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
205 p += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
206 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
207 for (i = 0; i < PALETTE_COUNT; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
208 r = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
209 g = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
210 b = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
211 palette32[i] = (r << 16) | (g << 8) | (b);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
212 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
213 s->size -= (256 * 3 + 2);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
214 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
215 if (s->size >= 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
216 /* originally UnpackFrame in VAG's code */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
217 pb = p;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
218 meth = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
219 if (meth & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
220 lz_unpack(pb, s->unpack_buffer);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
221 meth &= 0x7F;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
222 pb = s->unpack_buffer;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
223 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
224
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
225 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
226 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
227 switch (meth) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
228 case 1:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
229 for (i = 0; i < frame_height; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
230 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
231 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
232 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
233 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
234 len = (len & 0x7F) + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
235 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
236 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
237 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
238 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
239 /* interframe pixel copy */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
240 memcpy(&dp[ofs], &pp[ofs], len + 1);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
241 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
242 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
243 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
244 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
245 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
246 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
247 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
248 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
249 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
250 pp += s->prev_frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
251 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
252 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
253
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
254 case 2:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
255 for (i = 0; i < frame_height; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
256 memcpy(dp, pb, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
257 pb += frame_width;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
258 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
259 pp += s->prev_frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
260 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
261 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
262
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
263 case 3:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
264 for (i = 0; i < frame_height; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
265 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
266 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
267 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
268 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
269 len = (len & 0x7F) + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
270 if (*pb++ == 0xFF)
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
271 len = rle_unpack(pb, &dp[ofs], len);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
272 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
273 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
274 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
275 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
276 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
277 /* interframe pixel copy */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
278 memcpy(&dp[ofs], &pp[ofs], len + 1);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
279 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
280 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
281 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
282 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
283 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
284 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
285 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
286 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
287 pp += s->prev_frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
288 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
289 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
290 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
291 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
292 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
293
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
294 static int vmdvideo_decode_init(AVCodecContext *avctx)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
295 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
296 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
297 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
298 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
299 int palette_index = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
300 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
301 unsigned char *vmd_header;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
302 unsigned char *raw_palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
303
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
304 s->avctx = avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
305 avctx->pix_fmt = PIX_FMT_PAL8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
306 avctx->has_b_frames = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
307 dsputil_init(&s->dsp, avctx);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
308
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
309 /* make sure the VMD header made it */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
310 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
311 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
312 VMD_HEADER_SIZE);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
313 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
314 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
315 vmd_header = (unsigned char *)avctx->extradata;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
316
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
317 s->unpack_buffer = av_malloc(LE_32(&vmd_header[800]));
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
318 if (!s->unpack_buffer)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
319 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
320
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
321 /* load up the initial palette */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
322 raw_palette = &vmd_header[28];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
323 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
324 for (i = 0; i < PALETTE_COUNT; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
325 r = raw_palette[palette_index++] * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
326 g = raw_palette[palette_index++] * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
327 b = raw_palette[palette_index++] * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
328 palette32[i] = (r << 16) | (g << 8) | (b);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
329 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
330
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
331 s->frame.data[0] = s->prev_frame.data[0] = NULL;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
332
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
333 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
334 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
335
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
336 static int vmdvideo_decode_frame(AVCodecContext *avctx,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
337 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
338 uint8_t *buf, int buf_size)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
339 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
340 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
341
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
342 s->buf = buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
343 s->size = buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
344
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
345 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
346 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
347
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
348 s->frame.reference = 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
349 if (avctx->get_buffer(avctx, &s->frame)) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
350 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
351 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
352 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
353
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
354 vmd_decode(s);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
355
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
356 /* make the palette available on the way out */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
357 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
358
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
359 if (s->prev_frame.data[0])
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
360 avctx->release_buffer(avctx, &s->prev_frame);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
361
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
362 /* shuffle frames */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
363 s->prev_frame = s->frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
364
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
365 *data_size = sizeof(AVFrame);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
366 *(AVFrame*)data = s->frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
367
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
368 /* report that the buffer was completely consumed */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
369 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
370 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
371
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
372 static int vmdvideo_decode_end(AVCodecContext *avctx)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
373 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
374 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
375
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
376 if (s->prev_frame.data[0])
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
377 avctx->release_buffer(avctx, &s->prev_frame);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
378 av_free(s->unpack_buffer);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
379
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
380 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
381 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
382
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
383
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
384 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
385 * Audio Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
386 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
387
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
388 typedef struct VmdAudioContext {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
389 AVCodecContext *avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
390 int channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
391 int bits;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
392 int block_align;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
393 unsigned char steps8[16];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
394 unsigned short steps16[16];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
395 unsigned short steps128[256];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
396 short predictors[2];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
397 } VmdAudioContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
398
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
399 static int vmdaudio_decode_init(AVCodecContext *avctx)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
400 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
401 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
402 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
403
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
404 s->avctx = avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
405 s->channels = avctx->channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
406 s->bits = avctx->bits_per_sample;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
407 s->block_align = avctx->block_align;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
408
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
409 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
410 s->channels, s->bits, s->block_align, avctx->sample_rate);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
411
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
412 /* set up the steps8 and steps16 tables */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
413 for (i = 0; i < 8; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
414 if (i < 4)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
415 s->steps8[i] = i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
416 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
417 s->steps8[i] = s->steps8[i - 1] + i - 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
418
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
419 if (i == 0)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
420 s->steps16[i] = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
421 else if (i == 1)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
422 s->steps16[i] = 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
423 else if (i == 2)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
424 s->steps16[i] = 16;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
425 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
426 s->steps16[i] = 1 << (i + 4);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
427 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
428
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
429 /* set up the step128 table */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
430 s->steps128[0] = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
431 s->steps128[1] = 8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
432 for (i = 0x02; i <= 0x20; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
433 s->steps128[i] = (i - 1) << 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
434 for (i = 0x21; i <= 0x60; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
435 s->steps128[i] = (i + 0x1F) << 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
436 for (i = 0x61; i <= 0x70; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
437 s->steps128[i] = (i - 0x51) << 6;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
438 for (i = 0x71; i <= 0x78; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
439 s->steps128[i] = (i - 0x69) << 8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
440 for (i = 0x79; i <= 0x7D; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
441 s->steps128[i] = (i - 0x75) << 10;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
442 s->steps128[0x7E] = 0x3000;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
443 s->steps128[0x7F] = 0x4000;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
444
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
445 /* set up the negative half of each table */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
446 for (i = 0; i < 8; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
447 s->steps8[i + 8] = -s->steps8[i];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
448 s->steps16[i + 8] = -s->steps16[i];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
449 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
450 for (i = 0; i < 128; i++)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
451 s->steps128[i + 128] = -s->steps128[i];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
452
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
453 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
454 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
455
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
456 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
457 uint8_t *buf, int ratio) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
458
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
459 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
460
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
461 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
462 uint8_t *buf, int silence)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
463 {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
464 int bytes_decoded = 0;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
465 int i;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
466
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
467 if (silence)
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
468 av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
469 if (s->channels == 2) {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
470
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
471 /* stereo handling */
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
472 if ((s->block_align & 0x01) == 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
473 if (silence)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
474 memset(data, 0, s->block_align * 2);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
475 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
476 vmdaudio_decode_audio(s, data, buf, 1);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
477 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
478 if (silence)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
479 memset(data, 0, s->block_align * 2);
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
480 else
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
481 vmdaudio_decode_audio(s, data, buf, 1);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
482 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
483 } else {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
484
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
485 /* mono handling */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
486 if (silence) {
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
487 if (s->bits == 16) {
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
488 memset(data, 0, s->block_align * 2);
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
489 bytes_decoded = s->block_align * 2;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
490 } else {
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
491 // memset(data, 0x00, s->block_align);
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
492 // bytes_decoded = s->block_align;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
493 memset(data, 0x00, s->block_align * 2);
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
494 bytes_decoded = s->block_align * 2;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
495 }
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
496 } else {
2274
4bdd4927d2fc if audio is PCM, push it through (sync is not perfect yet)
melanson
parents: 2028
diff changeset
497 /* copy the data but convert it to signed */
4bdd4927d2fc if audio is PCM, push it through (sync is not perfect yet)
melanson
parents: 2028
diff changeset
498 for (i = 0; i < s->block_align; i++)
4bdd4927d2fc if audio is PCM, push it through (sync is not perfect yet)
melanson
parents: 2028
diff changeset
499 data[i * 2 + 1] = buf[i] + 0x80;
4bdd4927d2fc if audio is PCM, push it through (sync is not perfect yet)
melanson
parents: 2028
diff changeset
500 bytes_decoded = s->block_align * 2;
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
501 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
502 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
503
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
504 return bytes_decoded;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
505 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
506
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
507 static int vmdaudio_decode_frame(AVCodecContext *avctx,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
508 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
509 uint8_t *buf, int buf_size)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
510 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
511 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
512 unsigned int sound_flags;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
513 unsigned char *output_samples = (unsigned char *)data;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
514
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
515 /* point to the start of the encoded data */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
516 unsigned char *p = buf + 16;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
517 unsigned char *p_end = buf + buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
518
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
519 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
520 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
521
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
522 if (buf[6] == 1) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
523 /* the chunk contains audio */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
524 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
525 } else if (buf[6] == 2) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
526 /* the chunk contains audio and silence mixed together */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
527 sound_flags = LE_32(p);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
528 p += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
529
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
530 /* do something with extrabufs here? */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
531
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
532 while (p < p_end) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
533 if (sound_flags & 0x01)
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
534 /* silence */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
535 *data_size += vmdaudio_loadsound(s, output_samples, p, 1);
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
536 else {
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
537 /* audio */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
538 *data_size += vmdaudio_loadsound(s, output_samples, p, 0);
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
539 p += s->block_align;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
540 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
541 output_samples += (s->block_align * s->bits / 8);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
542 sound_flags >>= 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
543 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
544 } else if (buf[6] == 3) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
545 /* silent chunk */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
546 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
547 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
548
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
549 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
550 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
551
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
552
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
553 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
554 * Public Data Structures
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
555 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
556
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
557 AVCodec vmdvideo_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
558 "vmdvideo",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
559 CODEC_TYPE_VIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
560 CODEC_ID_VMDVIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
561 sizeof(VmdVideoContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
562 vmdvideo_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
563 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
564 vmdvideo_decode_end,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
565 vmdvideo_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
566 CODEC_CAP_DR1,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
567 };
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
568
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
569 AVCodec vmdaudio_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
570 "vmdaudio",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
571 CODEC_TYPE_AUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
572 CODEC_ID_VMDAUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
573 sizeof(VmdAudioContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
574 vmdaudio_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
575 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
576 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
577 vmdaudio_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
578 };