annotate vmdav.c @ 4166:eced83504436 libavcodec

mp3 header (de)compression bitstream filter this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output this will only work in containers providing at least packet size, sample_rate and number of channels bugreports about mp3 files for which this fails are welcome and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author michael
date Fri, 10 Nov 2006 01:41:53 +0000
parents c8c591fe26f8
children 17d005bf07f2
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 /**
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
24 * @file vmdvideo.c
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
25 * Sierra VMD audio & video decoders
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
26 * 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
27 * 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
28 * 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
29 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
30 * 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
31 * 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
32 * codec initialization. Each encoded frame that is sent to this decoder
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
33 * 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
34 * 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
35 *
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
36 * 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
37 * 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
38 * 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
39 * 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
40 * normal libavcodec API means.
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
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
43 #include <stdio.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
44 #include <stdlib.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
45 #include <string.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
46 #include <unistd.h>
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
47
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
48 #include "common.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
49 #include "avcodec.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
50 #include "dsputil.h"
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
51
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
52 #define VMD_HEADER_SIZE 0x330
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
53 #define PALETTE_COUNT 256
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
54
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 * Video Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
57 */
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 typedef struct VmdVideoContext {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
60
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
61 AVCodecContext *avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
62 DSPContext dsp;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
63 AVFrame frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
64 AVFrame prev_frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
65
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
66 unsigned char *buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
67 int size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
68
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
69 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
70 unsigned char *unpack_buffer;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
71 int unpack_buffer_size;
1717
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 } VmdVideoContext;
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 #define QUEUE_SIZE 0x1000
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
76 #define QUEUE_MASK 0x0FFF
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
77
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
78 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
79 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
80 unsigned char *s;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
81 unsigned char *d;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
82 unsigned char *d_end;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
83 unsigned char queue[QUEUE_SIZE];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
84 unsigned int qpos;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
85 unsigned int dataleft;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
86 unsigned int chainofs;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
87 unsigned int chainlen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
88 unsigned int speclen;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
89 unsigned char tag;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
90 unsigned int i, j;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
91
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
92 s = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
93 d = dest;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
94 d_end = d + dest_len;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
95 dataleft = LE_32(s);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
96 s += 4;
3562
432ac9dce673 Correct wrong memset invocation.
diego
parents: 3191
diff changeset
97 memset(queue, 0x20, QUEUE_SIZE);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
98 if (LE_32(s) == 0x56781234) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
99 s += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
100 qpos = 0x111;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
101 speclen = 0xF + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
102 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
103 qpos = 0xFEE;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
104 speclen = 100; /* no speclen */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
105 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
106
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
107 while (dataleft > 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
108 tag = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
109 if ((tag == 0xFF) && (dataleft > 8)) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
110 if (d + 8 > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
111 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
112 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
113 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
114 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
115 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
116 dataleft -= 8;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
117 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
118 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
119 if (dataleft == 0)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
120 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
121 if (tag & 0x01) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
122 if (d + 1 > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
123 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
124 queue[qpos++] = *d++ = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
125 qpos &= QUEUE_MASK;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
126 dataleft--;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
127 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
128 chainofs = *s++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
129 chainofs |= ((*s & 0xF0) << 4);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
130 chainlen = (*s++ & 0x0F) + 3;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
131 if (chainlen == speclen)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
132 chainlen = *s++ + 0xF + 3;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
133 if (d + chainlen > d_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
134 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
135 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
136 *d = queue[chainofs++ & QUEUE_MASK];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
137 queue[qpos++] = *d++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
138 qpos &= QUEUE_MASK;
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 dataleft -= chainlen;
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 tag >>= 1;
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 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
146 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
147
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
148 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
149 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
150 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
151 unsigned char *ps;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
152 unsigned char *pd;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
153 int i, l;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
154 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
155
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
156 ps = src;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
157 pd = dest;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
158 if (src_len & 1)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
159 *pd++ = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
160
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
161 src_len >>= 1;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
162 i = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
163 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
164 l = *ps++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
165 if (l & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
166 l = (l & 0x7F) * 2;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
167 if (pd + l > dest_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
168 return (ps - src);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
169 memcpy(pd, ps, l);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
170 ps += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
171 pd += l;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
172 } else {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
173 if (pd + i > dest_end)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
174 return (ps - src);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
175 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
176 *pd++ = ps[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
177 *pd++ = ps[1];
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 ps += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
180 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
181 i += l;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
182 } while (i < src_len);
1717
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 return (ps - src);
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
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
187 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
188 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
189 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
190 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
191 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
192
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
193 /* 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
194 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
195
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
196 unsigned char *pb;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
197 unsigned char meth;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
198 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
199 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
200 unsigned char len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
201 int ofs;
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 int frame_x, frame_y;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
204 int frame_width, frame_height;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
205 int dp_size;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
206
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
207 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
208 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
209 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
210 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
211
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
212 /* 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
213 * frame before the decode */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
214 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
215 (frame_height != s->avctx->height)) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
216
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
217 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
218 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
219 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
220
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
221 /* 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
222 if (s->buf[15] & 0x02) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
223 p += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
224 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
225 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
226 r = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
227 g = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
228 b = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
229 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
230 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
231 s->size -= (256 * 3 + 2);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
232 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
233 if (s->size >= 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
234 /* 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
235 pb = p;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
236 meth = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
237 if (meth & 0x80) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
238 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
239 meth &= 0x7F;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
240 pb = s->unpack_buffer;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
241 }
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 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
244 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
245 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
246 switch (meth) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
247 case 1:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
248 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
249 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
250 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
251 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
252 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
253 len = (len & 0x7F) + 1;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
254 if (ofs + len > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
255 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
256 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
257 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
258 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
259 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
260 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
261 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
262 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
263 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
264 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
265 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
266 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
267 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
268 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
269 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
270 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
271 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
272 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
273 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
274 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
275 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
276
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
277 case 2:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
278 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
279 memcpy(dp, pb, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
280 pb += frame_width;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
281 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
282 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
283 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
284 break;
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 case 3:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
287 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
288 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
289 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
290 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
291 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
292 len = (len & 0x7F) + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
293 if (*pb++ == 0xFF)
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
294 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
295 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
296 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
297 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
298 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
299 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
300 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
301 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
302 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
303 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
304 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
305 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
306 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
307 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
308 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
309 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
310 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
311 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
312 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
313 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
314 break;
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 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
318
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
319 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
320 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
321 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
322 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
323 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
324 int palette_index = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
325 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
326 unsigned char *vmd_header;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
327 unsigned char *raw_palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
328
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
329 s->avctx = avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
330 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
331 avctx->has_b_frames = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
332 dsputil_init(&s->dsp, avctx);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
333
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
334 /* 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
335 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
336 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
337 VMD_HEADER_SIZE);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
338 return -1;
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 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
341
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
342 s->unpack_buffer_size = LE_32(&vmd_header[800]);
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
343 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
344 if (!s->unpack_buffer)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
345 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
346
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
347 /* load up the initial palette */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
348 raw_palette = &vmd_header[28];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
349 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
350 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
351 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
352 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
353 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
354 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
355 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
356
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
357 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
358
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
359 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
360 }
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 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
363 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
364 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
365 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
366 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
367
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
368 s->buf = buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
369 s->size = buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
370
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
371 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
372 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
373
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
374 s->frame.reference = 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
375 if (avctx->get_buffer(avctx, &s->frame)) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
376 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
377 return -1;
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
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
380 vmd_decode(s);
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 /* 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
383 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
384
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
385 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
386 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
387
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
388 /* shuffle frames */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
389 s->prev_frame = s->frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
390
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
391 *data_size = sizeof(AVFrame);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
392 *(AVFrame*)data = s->frame;
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 /* 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
395 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
396 }
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 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
399 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
400 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
401
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
402 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
403 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
404 av_free(s->unpack_buffer);
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 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
407 }
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 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
411 * Audio Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
412 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
413
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
414 typedef struct VmdAudioContext {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
415 AVCodecContext *avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
416 int channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
417 int bits;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
418 int block_align;
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
419 int predictors[2];
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
420 } VmdAudioContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
421
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
422 static uint16_t vmdaudio_table[128] = {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
423 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
424 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
425 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
426 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
427 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
428 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
429 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
430 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
431 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
432 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
433 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
434 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
435 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
436 };
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
437
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
438 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
439 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
440 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
441
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
442 s->avctx = avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
443 s->channels = avctx->channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
444 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
445 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
446
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
447 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
448 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
449
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
450 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
451 }
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 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
454 uint8_t *buf, int stereo)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
455 {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
456 int i;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
457 int chan = 0;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
458 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
459
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
460 for(i = 0; i < s->block_align; i++) {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
461 if(buf[i] & 0x80)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
462 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
463 else
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
464 s->predictors[chan] += vmdaudio_table[buf[i]];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
465 s->predictors[chan] = clip(s->predictors[chan], -32768, 32767);
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
466 out[i] = s->predictors[chan];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
467 chan ^= stereo;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
468 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
469 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
470
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
471 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
472 uint8_t *buf, int silence)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
473 {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
474 int bytes_decoded = 0;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
475 int i;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
476
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
477 // if (silence)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
478 // 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
479 if (s->channels == 2) {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
480
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
481 /* stereo handling */
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
482 if (silence) {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
483 memset(data, 0, s->block_align * 2);
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
484 } else {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
485 if (s->bits == 16)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
486 vmdaudio_decode_audio(s, data, buf, 1);
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
487 else
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
488 /* copy the data but convert it to signed */
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
489 for (i = 0; i < s->block_align; i++)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
490 data[i * 2 + 1] = buf[i] + 0x80;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
491 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
492 } else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
493 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
494
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
495 /* mono handling */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
496 if (silence) {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
497 memset(data, 0, s->block_align * 2);
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
498 } else {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
499 if (s->bits == 16) {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
500 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
501 } else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
502 /* copy the data but convert it to signed */
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
503 for (i = 0; i < s->block_align; i++)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
504 data[i * 2 + 1] = buf[i] + 0x80;
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
505 }
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
506 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
507 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
508
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
509 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
510 }
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 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
513 void *data, int *data_size,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
514 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
515 {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
516 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
517 unsigned int sound_flags;
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 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
523
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
524 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
525 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
526
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
527 if (buf[6] == 1) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
528 /* the chunk contains audio */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
529 *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
530 } else if (buf[6] == 2) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
531 /* 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
532 sound_flags = LE_32(p);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
533 p += 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
534
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
535 /* do something with extrabufs here? */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
536
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
537 while (p < p_end) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
538 if (sound_flags & 0x01)
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
539 /* silence */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
540 *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
541 else {
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
542 /* audio */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
543 *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
544 p += s->block_align;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
545 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
546 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
547 sound_flags >>= 1;
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 } else if (buf[6] == 3) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
550 /* silent chunk */
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
551 *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
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 return buf_size;
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
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 * Public Data Structures
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
560 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
561
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
562 AVCodec vmdvideo_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
563 "vmdvideo",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
564 CODEC_TYPE_VIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
565 CODEC_ID_VMDVIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
566 sizeof(VmdVideoContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
567 vmdvideo_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
568 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
569 vmdvideo_decode_end,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
570 vmdvideo_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
571 CODEC_CAP_DR1,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
572 };
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
573
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
574 AVCodec vmdaudio_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
575 "vmdaudio",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
576 CODEC_TYPE_AUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
577 CODEC_ID_VMDAUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
578 sizeof(VmdAudioContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
579 vmdaudio_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
580 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
581 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
582 vmdaudio_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
583 };