annotate vmdav.c @ 5312:2c875e6274d5 libavcodec

AC-3 decoder, soc revision 52, Aug 16 22:45:07 2006 UTC by cloud9 Reset the blksw and dithflag to 0 at the begining of each block. Otherwise blockswitching propagates over multiple frames even if block switching is not enabled for that frame. Also reuse rematflg.
author jbr
date Sat, 14 Jul 2007 15:59:25 +0000
parents 2b72f9bc4f06
children c2ab2ac31edb
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 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
8 * 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
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
13 * 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
14 * 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
15 * 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
16 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3562
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2979
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1717
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 /**
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
23 * @file vmdvideo.c
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
24 * Sierra VMD audio & video decoders
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
25 * 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
26 * 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
27 * 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
28 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
29 * 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
30 * 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
31 * codec initialization. Each encoded frame that is sent to this decoder
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
32 * is expected to be prepended with the appropriate 16-byte frame
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
33 * 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
34 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
35 * 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
36 * 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
37 * 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
38 * 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
39 * normal libavcodec API means.
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
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
42 #include <stdio.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
43 #include <stdlib.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
44 #include <string.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
45 #include <unistd.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
46
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;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
69 int unpack_buffer_size;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
70
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
71 } VmdVideoContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
72
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
73 #define QUEUE_SIZE 0x1000
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
74 #define QUEUE_MASK 0x0FFF
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
75
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
76 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
77 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
78 unsigned char *s;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
79 unsigned char *d;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
80 unsigned char *d_end;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
81 unsigned char queue[QUEUE_SIZE];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
82 unsigned int qpos;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
83 unsigned int dataleft;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
84 unsigned int chainofs;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
85 unsigned int chainlen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
86 unsigned int speclen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
87 unsigned char tag;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
88 unsigned int i, j;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
89
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
90 s = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
91 d = dest;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
92 d_end = d + dest_len;
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
93 dataleft = AV_RL32(s);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
94 s += 4;
3562
432ac9dce673 Correct wrong memset invocation.
diego
parents: 3191
diff changeset
95 memset(queue, 0x20, QUEUE_SIZE);
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
96 if (AV_RL32(s) == 0x56781234) {
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
97 s += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
98 qpos = 0x111;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
99 speclen = 0xF + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
100 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
101 qpos = 0xFEE;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
102 speclen = 100; /* no speclen */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
103 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
104
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
105 while (dataleft > 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
106 tag = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
107 if ((tag == 0xFF) && (dataleft > 8)) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
108 if (d + 8 > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
109 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
110 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
111 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
112 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
113 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
114 dataleft -= 8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
115 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
116 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
117 if (dataleft == 0)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
118 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
119 if (tag & 0x01) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
120 if (d + 1 > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
121 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
122 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
123 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
124 dataleft--;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
125 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
126 chainofs = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
127 chainofs |= ((*s & 0xF0) << 4);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
128 chainlen = (*s++ & 0x0F) + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
129 if (chainlen == speclen)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
130 chainlen = *s++ + 0xF + 3;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
131 if (d + chainlen > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
132 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
133 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
134 *d = queue[chainofs++ & QUEUE_MASK];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
135 queue[qpos++] = *d++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
136 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
137 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
138 dataleft -= chainlen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
139 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
140 tag >>= 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
141 }
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 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
144 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
145
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
146 static int rle_unpack(unsigned char *src, unsigned char *dest,
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
147 int src_len, int dest_len)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
148 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
149 unsigned char *ps;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
150 unsigned char *pd;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
151 int i, l;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
152 unsigned char *dest_end = dest + dest_len;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
153
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
154 ps = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
155 pd = dest;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
156 if (src_len & 1)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
157 *pd++ = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
158
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
159 src_len >>= 1;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
160 i = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
161 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
162 l = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
163 if (l & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
164 l = (l & 0x7F) * 2;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
165 if (pd + l > dest_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
166 return (ps - src);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
167 memcpy(pd, ps, l);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
168 ps += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
169 pd += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
170 } else {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
171 if (pd + i > dest_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
172 return (ps - src);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
173 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
174 *pd++ = ps[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
175 *pd++ = ps[1];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
176 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
177 ps += 2;
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 i += l;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
180 } while (i < src_len);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
181
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
182 return (ps - src);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
183 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
184
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
185 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
186 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
187 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
188 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
189 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
190
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
191 /* 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
192 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
193
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
194 unsigned char *pb;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
195 unsigned char meth;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
196 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
197 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
198 unsigned char len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
199 int ofs;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
200
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
201 int frame_x, frame_y;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
202 int frame_width, frame_height;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
203 int dp_size;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
204
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
205 frame_x = AV_RL16(&s->buf[6]);
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
206 frame_y = AV_RL16(&s->buf[8]);
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
207 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
208 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
209
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
210 /* 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
211 * frame before the decode */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
212 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
213 (frame_height != s->avctx->height)) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
214
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
215 memcpy(s->frame.data[0], s->prev_frame.data[0],
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
216 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
217 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
218
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
219 /* 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
220 if (s->buf[15] & 0x02) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
221 p += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
222 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
223 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
224 r = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
225 g = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
226 b = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
227 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
228 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
229 s->size -= (256 * 3 + 2);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
230 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
231 if (s->size >= 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
232 /* 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
233 pb = p;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
234 meth = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
235 if (meth & 0x80) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
236 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
237 meth &= 0x7F;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
238 pb = s->unpack_buffer;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
239 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
240
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
241 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
242 dp_size = s->frame.linesize[0] * s->avctx->height;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
243 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
244 switch (meth) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
245 case 1:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
246 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
247 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
248 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
249 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
250 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
251 len = (len & 0x7F) + 1;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
252 if (ofs + len > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
253 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
254 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
255 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
256 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
257 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
258 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
259 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
260 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
261 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
262 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
263 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
264 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
265 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
266 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
267 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
268 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
269 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
270 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
271 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
272 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
273 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
274
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
275 case 2:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
276 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
277 memcpy(dp, pb, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
278 pb += frame_width;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
279 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
280 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
281 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
282 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
283
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
284 case 3:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
285 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
286 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
287 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
288 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
289 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
290 len = (len & 0x7F) + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
291 if (*pb++ == 0xFF)
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
292 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
293 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
294 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
295 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
296 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
297 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
298 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
299 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
300 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
301 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
302 ofs += len + 1;
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 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
305 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
306 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
307 ofs, frame_width);
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 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
310 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
311 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
312 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
313 }
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 }
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 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
318 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
319 VmdVideoContext *s = avctx->priv_data;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
320 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
321 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
322 int palette_index = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
323 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
324 unsigned char *vmd_header;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
325 unsigned char *raw_palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
326
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
327 s->avctx = avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
328 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
329 dsputil_init(&s->dsp, avctx);
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 /* 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
332 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
333 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
334 VMD_HEADER_SIZE);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
335 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
336 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
337 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
338
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
339 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
340 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
341 if (!s->unpack_buffer)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
342 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
343
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
344 /* load up the initial palette */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
345 raw_palette = &vmd_header[28];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
346 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
347 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
348 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
349 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
350 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
351 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
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 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
355
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
356 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
357 }
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 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
360 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
361 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
362 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
363 VmdVideoContext *s = avctx->priv_data;
1717
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 s->buf = buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
366 s->size = buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
367
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
368 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
369 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
370
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
371 s->frame.reference = 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
372 if (avctx->get_buffer(avctx, &s->frame)) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
373 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
374 return -1;
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
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
377 vmd_decode(s);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
378
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
379 /* 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
380 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
381
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
382 /* shuffle frames */
5081
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
383 FFSWAP(AVFrame, s->frame, s->prev_frame);
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
384 if (s->frame.data[0])
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
385 avctx->release_buffer(avctx, &s->frame);
1717
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 *data_size = sizeof(AVFrame);
5081
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
388 *(AVFrame*)data = s->prev_frame;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
389
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
390 /* 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
391 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
392 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
393
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
394 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
395 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
396 VmdVideoContext *s = avctx->priv_data;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
397
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
398 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
399 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
400 av_free(s->unpack_buffer);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
401
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
402 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
403 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
404
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
405
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
406 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
407 * Audio Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
408 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
409
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
410 typedef struct VmdAudioContext {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
411 AVCodecContext *avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
412 int channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
413 int bits;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
414 int block_align;
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
415 int predictors[2];
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
416 } VmdAudioContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
417
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
418 static uint16_t vmdaudio_table[128] = {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
419 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
420 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
421 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
422 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
423 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
424 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
425 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
426 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
427 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
428 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
429 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
430 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
431 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
432 };
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
433
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
434 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
435 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
436 VmdAudioContext *s = avctx->priv_data;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
437
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
438 s->avctx = avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
439 s->channels = avctx->channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
440 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
441 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
442
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
443 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
444 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
445
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
446 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
447 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
448
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
449 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
450 uint8_t *buf, int stereo)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
451 {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
452 int i;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
453 int chan = 0;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
454 int16_t *out = (int16_t*)data;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
455
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
456 for(i = 0; i < s->block_align; i++) {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
457 if(buf[i] & 0x80)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
458 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
459 else
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
460 s->predictors[chan] += vmdaudio_table[buf[i]];
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4364
diff changeset
461 s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767);
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
462 out[i] = s->predictors[chan];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
463 chan ^= stereo;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
464 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
465 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
466
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
467 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
468 uint8_t *buf, int silence)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
469 {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
470 int bytes_decoded = 0;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
471 int i;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
472
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
473 // if (silence)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
474 // 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
475 if (s->channels == 2) {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
476
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
477 /* stereo handling */
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
478 if (silence) {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
479 memset(data, 0, s->block_align * 2);
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
480 } else {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
481 if (s->bits == 16)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
482 vmdaudio_decode_audio(s, data, buf, 1);
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
483 else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
484 /* copy the data but convert it to signed */
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
485 for (i = 0; i < s->block_align; i++){
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
486 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
487 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
488 }
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
489 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
490 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
491 } else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
492 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
493
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
494 /* mono handling */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
495 if (silence) {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
496 memset(data, 0, s->block_align * 2);
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
497 } else {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
498 if (s->bits == 16) {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
499 vmdaudio_decode_audio(s, data, buf, 0);
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
500 } else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
501 /* copy the data but convert it to signed */
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
502 for (i = 0; i < s->block_align; i++){
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
503 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
504 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
505 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
506 }
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
507 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
508 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
509
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
510 return s->block_align * 2;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
511 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
512
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
513 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
514 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
515 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
516 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
517 VmdAudioContext *s = avctx->priv_data;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
518 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
519
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
520 /* 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
521 unsigned char *p = buf + 16;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
522
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
523 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
524 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
525
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
526 if (buf[6] == 1) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
527 /* the chunk contains audio */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
528 *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
529 } else if (buf[6] == 2) {
4213
42553b85aa7e Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 4182
diff changeset
530 /* the chunk may contain audio */
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
531 p += 4;
4213
42553b85aa7e Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 4182
diff changeset
532 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
42553b85aa7e Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 4182
diff changeset
533 output_samples += (s->block_align * s->bits / 8);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
534 } else if (buf[6] == 3) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
535 /* silent chunk */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
536 *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
537 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
538
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
539 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
540 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
541
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
542
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 * Public Data Structures
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
545 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
546
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
547 AVCodec vmdvideo_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
548 "vmdvideo",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
549 CODEC_TYPE_VIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
550 CODEC_ID_VMDVIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
551 sizeof(VmdVideoContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
552 vmdvideo_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
553 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
554 vmdvideo_decode_end,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
555 vmdvideo_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
556 CODEC_CAP_DR1,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
557 };
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
558
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
559 AVCodec vmdaudio_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
560 "vmdaudio",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
561 CODEC_TYPE_AUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
562 CODEC_ID_VMDAUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
563 sizeof(VmdAudioContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
564 vmdaudio_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
565 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
566 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
567 vmdaudio_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
568 };