Mercurial > libavcodec.hg
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 |
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 | 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 | 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 | 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 | 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 | 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 | 95 memset(queue, 0x20, QUEUE_SIZE); |
4364 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 205 frame_x = AV_RL16(&s->buf[6]); |
206 frame_y = AV_RL16(&s->buf[8]); | |
207 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; | |
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 426 static const uint16_t vmdaudio_table[128] = { |
3191 | 427 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, |
428 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, | |
429 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, | |
430 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, | |
431 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, | |
432 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, | |
433 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, | |
434 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, | |
435 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, | |
436 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, | |
437 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, | |
438 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, | |
439 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 | |
440 }; | |
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 | 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 | 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 | 452 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", |
2979 | 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 | 460 { |
461 int i; | |
462 int chan = 0; | |
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 | 466 if(buf[i] & 0x80) |
467 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; | |
468 else | |
469 s->predictors[chan] += vmdaudio_table[buf[i]]; | |
5523 | 470 s->predictors[chan] = av_clip_int16(s->predictors[chan]); |
3191 | 471 out[i] = s->predictors[chan]; |
472 chan ^= stereo; | |
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 | 482 // if (silence) |
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 | 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 | 489 } else { |
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 | 492 else { |
3191 | 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 | 495 *data++ = buf[i] + 0x80; |
496 *data++ = buf[i] + 0x80; | |
497 } | |
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 | 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 | 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 | 512 *data++ = buf[i] + 0x80; |
513 *data++ = buf[i] + 0x80; | |
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 | 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 | 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 }; |