annotate vmdav.c @ 9830:bd0879f752e6 libavcodec

Express the H.264 parser dependency on the golomb code in configure instead of in the Makefile as it is done for all other parts that depend on golomb.
author diego
date Tue, 09 Jun 2009 20:29:52 +0000
parents 4cab394c16ea
children 5da84f0d0a55
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 /**
8718
e9d9d946f213 Use full internal pathname in doxygen @file directives.
diego
parents: 8673
diff changeset
23 * @file libavcodec/vmdav.c
1717
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
8573
2acf0ae7b041 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 7823
diff changeset
47 #include "libavutil/intreadwrite.h"
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
48 #include "avcodec.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 AVFrame frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
61 AVFrame prev_frame;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
62
6291
michael
parents: 5699
diff changeset
63 const unsigned char *buf;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
64 int size;
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 palette[PALETTE_COUNT * 4];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
67 unsigned char *unpack_buffer;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
68 int unpack_buffer_size;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
69
5699
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
70 int x_off, y_off;
1717
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
6291
michael
parents: 5699
diff changeset
76 static void lz_unpack(const 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 {
6291
michael
parents: 5699
diff changeset
78 const unsigned char *s;
1717
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
6291
michael
parents: 5699
diff changeset
146 static int rle_unpack(const 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 {
6291
michael
parents: 5699
diff changeset
149 const unsigned char *ps;
1717
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)
6750
c93570aeb3eb Remove unnecessary parentheses from return calls.
diego
parents: 6712
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)
6750
c93570aeb3eb Remove unnecessary parentheses from return calls.
diego
parents: 6712
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
6750
c93570aeb3eb Remove unnecessary parentheses from return calls.
diego
parents: 6712
diff changeset
182 return ps - src;
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
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 */
6291
michael
parents: 5699
diff changeset
192 const unsigned char *p = s->buf + 16;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
193
6291
michael
parents: 5699
diff changeset
194 const unsigned char *pb;
1717
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
5699
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
210 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
211 (frame_x || frame_y)) {
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
212
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
213 s->x_off = frame_x;
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
214 s->y_off = frame_y;
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
215 }
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
216 frame_x -= s->x_off;
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
217 frame_y -= s->y_off;
c5c356f38cc4 Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents: 5523
diff changeset
218
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
219 /* 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
220 * frame before the decode */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
221 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
222 (frame_height != s->avctx->height)) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
223
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
224 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
225 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
226 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
227
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
228 /* 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
229 if (s->buf[15] & 0x02) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
230 p += 2;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
231 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
232 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
233 r = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
234 g = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
235 b = *p++ * 4;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
236 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
237 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
238 s->size -= (256 * 3 + 2);
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 if (s->size >= 0) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
241 /* 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
242 pb = p;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
243 meth = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
244 if (meth & 0x80) {
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
245 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
246 meth &= 0x7F;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
247 pb = s->unpack_buffer;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
248 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
249
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
250 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
251 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
252 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
253 switch (meth) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
254 case 1:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
255 for (i = 0; i < frame_height; i++) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
256 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
257 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
258 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
259 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
260 len = (len & 0x7F) + 1;
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
261 if (ofs + len > 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], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
264 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
265 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
266 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
267 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
268 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
269 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
270 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
271 ofs += len + 1;
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 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
274 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
275 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
276 ofs, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
277 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
278 }
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 2:
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 memcpy(dp, pb, frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
287 pb += frame_width;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
288 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
289 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
290 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
291 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
292
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
293 case 3:
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
294 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
295 ofs = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
296 do {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
297 len = *pb++;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
298 if (len & 0x80) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
299 len = (len & 0x7F) + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
300 if (*pb++ == 0xFF)
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
301 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
302 else
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
303 memcpy(&dp[ofs], pb, len);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
304 pb += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
305 ofs += len;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
306 } else {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
307 /* interframe pixel copy */
2829
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
308 if (ofs + len + 1 > frame_width)
9ff4c2733422 tinfoil patch: be more diligent about checking array boundaries before
melanson
parents: 2274
diff changeset
309 return;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
310 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
311 ofs += len + 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
312 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
313 } while (ofs < frame_width);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
314 if (ofs > frame_width) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
315 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
316 ofs, frame_width);
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 dp += s->frame.linesize[0];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
319 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
320 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
321 break;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
322 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
323 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
324 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
325
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
326 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
327 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
328 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
329 int i;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
330 unsigned int *palette32;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
331 int palette_index = 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
332 unsigned char r, g, b;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
333 unsigned char *vmd_header;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
334 unsigned char *raw_palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
335
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
336 s->avctx = avctx;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
337 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
338
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
339 /* 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
340 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2829
diff changeset
341 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
342 VMD_HEADER_SIZE);
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
343 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
344 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
345 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
346
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 4213
diff changeset
347 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
348 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
349 if (!s->unpack_buffer)
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
350 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
351
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
352 /* load up the initial palette */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
353 raw_palette = &vmd_header[28];
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
354 palette32 = (unsigned int *)s->palette;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
355 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
356 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
357 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
358 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
359 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
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 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
363 }
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 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
366 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
367 AVPacket *avpkt)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
368 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
369 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
370 int buf_size = avpkt->size;
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
371 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
372
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
373 s->buf = buf;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
374 s->size = buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
375
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
376 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
377 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
378
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
379 s->frame.reference = 1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
380 if (avctx->get_buffer(avctx, &s->frame)) {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
381 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
382 return -1;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
383 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
384
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
385 vmd_decode(s);
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 /* 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
388 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
389
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
390 /* shuffle frames */
5081
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
391 FFSWAP(AVFrame, s->frame, s->prev_frame);
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
392 if (s->frame.data[0])
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
393 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
394
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
395 *data_size = sizeof(AVFrame);
5081
46c9abb46638 Do proper frame swapping so VMD video decoder works again
kostya
parents: 4962
diff changeset
396 *(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
397
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
398 /* 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
399 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
400 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
401
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
402 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
403 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
404 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
405
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
406 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
407 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
408 av_free(s->unpack_buffer);
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 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
411 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
412
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 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
415 * Audio Decoder
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
416 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
417
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
418 typedef struct VmdAudioContext {
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
419 AVCodecContext *avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
420 int channels;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
421 int bits;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
422 int block_align;
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
423 int predictors[2];
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
424 } VmdAudioContext;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
425
7129
322023e630a6 mark read-only data as const
stefang
parents: 7040
diff changeset
426 static const uint16_t vmdaudio_table[128] = {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
427 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
428 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
429 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
430 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
431 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
432 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
433 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
434 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
435 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
436 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
437 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
438 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
439 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
440 };
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
441
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
442 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
443 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
444 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
445
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
446 s->avctx = avctx;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
447 s->channels = avctx->channels;
7823
4525dcd81357 Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 7451
diff changeset
448 s->bits = avctx->bits_per_coded_sample;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
449 s->block_align = avctx->block_align;
7451
85ab7655ad4d Modify all codecs to report their supported input and output sample format(s).
pross
parents: 7129
diff changeset
450 avctx->sample_fmt = SAMPLE_FMT_S16;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
451
1927
d7505fbe66cb conversion to av_log
alex
parents: 1882
diff changeset
452 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
453 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
454
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
455 return 0;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
456 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
457
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
458 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
459 const uint8_t *buf, int buf_size, int stereo)
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
460 {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
461 int i;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
462 int chan = 0;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
463 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
464
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
465 for(i = 0; i < buf_size; i++) {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
466 if(buf[i] & 0x80)
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
467 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
468 else
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
469 s->predictors[chan] += vmdaudio_table[buf[i]];
5523
c2ab2ac31edb use av_clip_int16() where it makes sense
aurel
parents: 5215
diff changeset
470 s->predictors[chan] = av_clip_int16(s->predictors[chan]);
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
471 out[i] = s->predictors[chan];
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
472 chan ^= stereo;
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
473 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
474 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
475
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
476 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
477 const uint8_t *buf, int silence, int data_size)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
478 {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
479 int bytes_decoded = 0;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
480 int i;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
481
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 // 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
484 if (s->channels == 2) {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
485
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
486 /* stereo handling */
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
487 if (silence) {
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
488 memset(data, 0, data_size * 2);
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
489 } else {
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
490 if (s->bits == 16)
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
491 vmdaudio_decode_audio(s, data, buf, data_size, 1);
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
492 else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
493 /* copy the data but convert it to signed */
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
494 for (i = 0; i < data_size; i++){
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
495 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
496 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
497 }
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
498 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
499 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
500 } else {
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
501 bytes_decoded = data_size * 2;
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
502
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
503 /* mono handling */
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
504 if (silence) {
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
505 memset(data, 0, data_size * 2);
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
506 } else {
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
507 if (s->bits == 16) {
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
508 vmdaudio_decode_audio(s, data, buf, data_size, 0);
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
509 } else {
3191
7acb3ea20b4c 16-bit DPCM and stereo support for Sierra VMD
kostya
parents: 3036
diff changeset
510 /* copy the data but convert it to signed */
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
511 for (i = 0; i < data_size; i++){
4182
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
512 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
513 *data++ = buf[i] + 0x80;
17d005bf07f2 Output proper 16-bit sound (fixes decoding on PPC)
kostya
parents: 3947
diff changeset
514 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
515 }
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
516 }
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
517 }
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
518
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
519 return data_size * 2;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
520 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
521
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
522 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
523 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
524 AVPacket *avpkt)
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
525 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
526 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
527 int buf_size = avpkt->size;
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
528 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
529 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
530
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
531 /* point to the start of the encoded data */
6291
michael
parents: 5699
diff changeset
532 const unsigned char *p = buf + 16;
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
533
1882
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
534 if (buf_size < 16)
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
535 return buf_size;
5456ab242388 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 1823
diff changeset
536
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
537 if (buf[6] == 1) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
538 /* the chunk contains audio */
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
539 *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
540 } else if (buf[6] == 2) {
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
541 /* initial chunk, may contain audio and silence */
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
542 uint32_t flags = AV_RB32(p);
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
543 int raw_block_size = s->block_align * s->bits / 8;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
544 int silent_chunks;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
545 if(flags == 0xFFFFFFFF)
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
546 silent_chunks = 32;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
547 else
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
548 silent_chunks = av_log2(flags + 1);
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
549 if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
550 return -1;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
551 *data_size = 0;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
552 memset(output_samples, 0, raw_block_size * silent_chunks);
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
553 output_samples += raw_block_size * silent_chunks;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
554 *data_size = raw_block_size * silent_chunks;
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
555 *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
556 } else if (buf[6] == 3) {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
557 /* silent chunk */
8634
33912b3ea952 VMD first chunk of audio is not coded as many separate chunks of block_align
kostya
parents: 8573
diff changeset
558 *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0);
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
559 }
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 return buf_size;
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
562 }
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
563
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
564
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
565 /*
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
566 * Public Data Structures
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
567 */
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
568
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
569 AVCodec vmdvideo_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
570 "vmdvideo",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
571 CODEC_TYPE_VIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
572 CODEC_ID_VMDVIDEO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
573 sizeof(VmdVideoContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
574 vmdvideo_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
575 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
576 vmdvideo_decode_end,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
577 vmdvideo_decode_frame,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
578 CODEC_CAP_DR1,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6750
diff changeset
579 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
580 };
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
581
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
582 AVCodec vmdaudio_decoder = {
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
583 "vmdaudio",
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
584 CODEC_TYPE_AUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
585 CODEC_ID_VMDAUDIO,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
586 sizeof(VmdAudioContext),
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
587 vmdaudio_decode_init,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
588 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
589 NULL,
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
590 vmdaudio_decode_frame,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6750
diff changeset
591 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
1717
6a7e68899d8a first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff changeset
592 };