Mercurial > libavcodec.hg
annotate vmdav.c @ 7983:47f50599b368 libavcodec
x264 has removed the b-rdo and bime options, and instead integrated
them into the subme number to attempt to reduce the number of
unnecessary options. subme now scales up to 9.
Patch by Jason Garett-Glaser %darkshikari A gmail P com%
author | gpoirier |
---|---|
date | Thu, 02 Oct 2008 19:05:35 +0000 |
parents | 4525dcd81357 |
children | 2acf0ae7b041 |
rev | line source |
---|---|
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
1 /* |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
2 * Sierra VMD Audio & Video Decoders |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
3 * Copyright (C) 2004 the ffmpeg project |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
16 * |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3562
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
20 */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
21 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
22 /** |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
23 * @file vmdvideo.c |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
24 * Sierra VMD audio & video decoders |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
25 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
26 * for more information on the Sierra VMD format, visit: |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
27 * http://www.pcisys.net/~melanson/codecs/ |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
28 * |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
29 * The video decoder outputs PAL8 colorspace data. The decoder expects |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
30 * a 0x330-byte VMD file header to be transmitted via extradata during |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
31 * codec initialization. Each encoded frame that is sent to this decoder |
2967 | 32 * is expected to be prepended with the appropriate 16-byte frame |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
33 * information record from the VMD file. |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
34 * |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
35 * The audio decoder, like the video decoder, expects each encoded data |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
36 * chunk to be prepended with the appropriate 16-byte frame information |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
37 * record from the VMD file. It does not require the 0x330-byte VMD file |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
38 * header, but it does need the audio setup parameters passed in through |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
39 * normal libavcodec API means. |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
40 */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
41 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
42 #include <stdio.h> |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
43 #include <stdlib.h> |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
44 #include <string.h> |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
45 #include <unistd.h> |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
46 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
47 #include "avcodec.h" |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
48 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
49 #define VMD_HEADER_SIZE 0x330 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
50 #define PALETTE_COUNT 256 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
51 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
52 /* |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
53 * Video Decoder |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
54 */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
55 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
56 typedef struct VmdVideoContext { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
57 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
58 AVCodecContext *avctx; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
59 AVFrame frame; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
60 AVFrame prev_frame; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
61 |
6291 | 62 const unsigned char *buf; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
63 int size; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
64 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
65 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
|
66 unsigned char *unpack_buffer; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
67 int unpack_buffer_size; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
68 |
5699
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
69 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
|
70 } VmdVideoContext; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
71 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
72 #define QUEUE_SIZE 0x1000 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
73 #define QUEUE_MASK 0x0FFF |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
74 |
6291 | 75 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
|
76 { |
6291 | 77 const unsigned char *s; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
78 unsigned char *d; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
79 unsigned char *d_end; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
80 unsigned char queue[QUEUE_SIZE]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
81 unsigned int qpos; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
82 unsigned int dataleft; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
83 unsigned int chainofs; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
84 unsigned int chainlen; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
85 unsigned int speclen; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
86 unsigned char tag; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
87 unsigned int i, j; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
88 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
89 s = src; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
90 d = dest; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
91 d_end = d + dest_len; |
4364 | 92 dataleft = AV_RL32(s); |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
93 s += 4; |
3562 | 94 memset(queue, 0x20, QUEUE_SIZE); |
4364 | 95 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
|
96 s += 4; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
97 qpos = 0x111; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
98 speclen = 0xF + 3; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
99 } else { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
100 qpos = 0xFEE; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
101 speclen = 100; /* no speclen */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
102 } |
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 while (dataleft > 0) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
105 tag = *s++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
106 if ((tag == 0xFF) && (dataleft > 8)) { |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
107 if (d + 8 > d_end) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
108 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
109 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
|
110 queue[qpos++] = *d++ = *s++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
111 qpos &= QUEUE_MASK; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
112 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
113 dataleft -= 8; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
114 } else { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
115 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
|
116 if (dataleft == 0) |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
117 break; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
118 if (tag & 0x01) { |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
119 if (d + 1 > d_end) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
120 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
121 queue[qpos++] = *d++ = *s++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
122 qpos &= QUEUE_MASK; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
123 dataleft--; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
124 } else { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
125 chainofs = *s++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
126 chainofs |= ((*s & 0xF0) << 4); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
127 chainlen = (*s++ & 0x0F) + 3; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
128 if (chainlen == speclen) |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
129 chainlen = *s++ + 0xF + 3; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
130 if (d + chainlen > d_end) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
131 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
132 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
|
133 *d = queue[chainofs++ & QUEUE_MASK]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
134 queue[qpos++] = *d++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
135 qpos &= QUEUE_MASK; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
136 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
137 dataleft -= chainlen; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
138 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
139 tag >>= 1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
140 } |
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 |
6291 | 145 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
|
146 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
|
147 { |
6291 | 148 const unsigned char *ps; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
149 unsigned char *pd; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
150 int i, l; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
151 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
|
152 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
153 ps = src; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
154 pd = dest; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
155 if (src_len & 1) |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
156 *pd++ = *ps++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
157 |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
158 src_len >>= 1; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
159 i = 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
160 do { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
161 l = *ps++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
162 if (l & 0x80) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
163 l = (l & 0x7F) * 2; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
164 if (pd + l > dest_end) |
6750 | 165 return ps - src; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
166 memcpy(pd, ps, l); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
167 ps += l; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
168 pd += l; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
169 } else { |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
170 if (pd + i > dest_end) |
6750 | 171 return ps - src; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
172 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
|
173 *pd++ = ps[0]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
174 *pd++ = ps[1]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
175 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
176 ps += 2; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
177 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
178 i += l; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
179 } while (i < src_len); |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
180 |
6750 | 181 return ps - src; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
182 } |
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 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
|
185 { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
186 int i; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
187 unsigned int *palette32; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
188 unsigned char r, g, b; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
189 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
190 /* point to the start of the encoded data */ |
6291 | 191 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
|
192 |
6291 | 193 const unsigned char *pb; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
194 unsigned char meth; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
195 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
|
196 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
|
197 unsigned char len; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
198 int ofs; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
199 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
200 int frame_x, frame_y; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
201 int frame_width, frame_height; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
202 int dp_size; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
203 |
4364 | 204 frame_x = AV_RL16(&s->buf[6]); |
205 frame_y = AV_RL16(&s->buf[8]); | |
206 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; | |
207 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
|
208 |
5699
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
209 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
|
210 (frame_x || frame_y)) { |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
211 |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
212 s->x_off = frame_x; |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
213 s->y_off = frame_y; |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
214 } |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
215 frame_x -= s->x_off; |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
216 frame_y -= s->y_off; |
c5c356f38cc4
Fix decoding of VMDs representing sprites (Last Dynasty, Woodruff).
kostya
parents:
5523
diff
changeset
|
217 |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
218 /* 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
|
219 * frame before the decode */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
220 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
|
221 (frame_height != s->avctx->height)) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
222 |
2967 | 223 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
|
224 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
|
225 } |
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 /* 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
|
228 if (s->buf[15] & 0x02) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
229 p += 2; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
230 palette32 = (unsigned int *)s->palette; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
231 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
|
232 r = *p++ * 4; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
233 g = *p++ * 4; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
234 b = *p++ * 4; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
235 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
|
236 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
237 s->size -= (256 * 3 + 2); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
238 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
239 if (s->size >= 0) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
240 /* 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
|
241 pb = p; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
242 meth = *pb++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
243 if (meth & 0x80) { |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
244 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
|
245 meth &= 0x7F; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
246 pb = s->unpack_buffer; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
247 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
248 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
249 dp = &s->frame.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
|
250 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
|
251 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
|
252 switch (meth) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
253 case 1: |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
254 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
|
255 ofs = 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
256 do { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
257 len = *pb++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
258 if (len & 0x80) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
259 len = (len & 0x7F) + 1; |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
260 if (ofs + len > frame_width) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
261 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
262 memcpy(&dp[ofs], pb, len); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
263 pb += len; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
264 ofs += len; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
265 } else { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
266 /* interframe pixel copy */ |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
267 if (ofs + len + 1 > frame_width) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
268 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
269 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
|
270 ofs += len + 1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
271 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
272 } while (ofs < frame_width); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
273 if (ofs > frame_width) { |
1927 | 274 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
|
275 ofs, frame_width); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
276 break; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
277 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
278 dp += s->frame.linesize[0]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
279 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
|
280 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
281 break; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
282 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
283 case 2: |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
284 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
|
285 memcpy(dp, pb, frame_width); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
286 pb += frame_width; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
287 dp += s->frame.linesize[0]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
288 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
|
289 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
290 break; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
291 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
292 case 3: |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
293 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
|
294 ofs = 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
295 do { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
296 len = *pb++; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
297 if (len & 0x80) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
298 len = (len & 0x7F) + 1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
299 if (*pb++ == 0xFF) |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
300 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
|
301 else |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
302 memcpy(&dp[ofs], pb, len); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
303 pb += len; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
304 ofs += len; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
305 } else { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
306 /* interframe pixel copy */ |
2829
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
307 if (ofs + len + 1 > frame_width) |
9ff4c2733422
tinfoil patch: be more diligent about checking array boundaries before
melanson
parents:
2274
diff
changeset
|
308 return; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
309 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
|
310 ofs += len + 1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
311 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
312 } while (ofs < frame_width); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
313 if (ofs > frame_width) { |
1927 | 314 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
|
315 ofs, frame_width); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
316 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
317 dp += s->frame.linesize[0]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
318 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
|
319 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
320 break; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
321 } |
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 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6484
diff
changeset
|
325 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
|
326 { |
4827 | 327 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
|
328 int i; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
329 unsigned int *palette32; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
330 int palette_index = 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
331 unsigned char r, g, b; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
332 unsigned char *vmd_header; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
333 unsigned char *raw_palette; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
334 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
335 s->avctx = avctx; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
336 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
|
337 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
338 /* 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
|
339 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { |
2967 | 340 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
|
341 VMD_HEADER_SIZE); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
342 return -1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
343 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
344 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
|
345 |
4364 | 346 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
|
347 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
|
348 if (!s->unpack_buffer) |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
349 return -1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
350 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
351 /* load up the initial palette */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
352 raw_palette = &vmd_header[28]; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
353 palette32 = (unsigned int *)s->palette; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
354 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
|
355 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
|
356 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
|
357 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
|
358 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
|
359 } |
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 s->frame.data[0] = s->prev_frame.data[0] = NULL; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
362 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
363 return 0; |
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 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
366 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
|
367 void *data, int *data_size, |
6291 | 368 const uint8_t *buf, int buf_size) |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
369 { |
4827 | 370 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
|
371 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
372 s->buf = buf; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
373 s->size = buf_size; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
374 |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
375 if (buf_size < 16) |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
376 return buf_size; |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
377 |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
378 s->frame.reference = 1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
379 if (avctx->get_buffer(avctx, &s->frame)) { |
1927 | 380 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
|
381 return -1; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
382 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
383 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
384 vmd_decode(s); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
385 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
386 /* 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
|
387 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
|
388 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
389 /* shuffle frames */ |
5081
46c9abb46638
Do proper frame swapping so VMD video decoder works again
kostya
parents:
4962
diff
changeset
|
390 FFSWAP(AVFrame, s->frame, s->prev_frame); |
46c9abb46638
Do proper frame swapping so VMD video decoder works again
kostya
parents:
4962
diff
changeset
|
391 if (s->frame.data[0]) |
46c9abb46638
Do proper frame swapping so VMD video decoder works again
kostya
parents:
4962
diff
changeset
|
392 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
|
393 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
394 *data_size = sizeof(AVFrame); |
5081
46c9abb46638
Do proper frame swapping so VMD video decoder works again
kostya
parents:
4962
diff
changeset
|
395 *(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
|
396 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
397 /* 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
|
398 return buf_size; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
399 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
400 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6484
diff
changeset
|
401 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
|
402 { |
4827 | 403 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
|
404 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
405 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
|
406 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
|
407 av_free(s->unpack_buffer); |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
408 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
409 return 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
410 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
411 |
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 * Audio Decoder |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
415 */ |
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 typedef struct VmdAudioContext { |
1927 | 418 AVCodecContext *avctx; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
419 int channels; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
420 int bits; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
421 int block_align; |
3191 | 422 int predictors[2]; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
423 } VmdAudioContext; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
424 |
7129 | 425 static const uint16_t vmdaudio_table[128] = { |
3191 | 426 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, |
427 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, | |
428 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, | |
429 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, | |
430 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, | |
431 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, | |
432 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, | |
433 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, | |
434 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, | |
435 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, | |
436 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, | |
437 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, | |
438 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 | |
439 }; | |
440 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6484
diff
changeset
|
441 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
|
442 { |
4827 | 443 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
|
444 |
1927 | 445 s->avctx = avctx; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
446 s->channels = avctx->channels; |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7451
diff
changeset
|
447 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
|
448 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
|
449 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
|
450 |
1927 | 451 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", |
2979 | 452 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
|
453 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
454 return 0; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
455 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
456 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
457 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, |
6291 | 458 const uint8_t *buf, int stereo) |
3191 | 459 { |
460 int i; | |
461 int chan = 0; | |
462 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
|
463 |
3191 | 464 for(i = 0; i < s->block_align; i++) { |
465 if(buf[i] & 0x80) | |
466 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; | |
467 else | |
468 s->predictors[chan] += vmdaudio_table[buf[i]]; | |
5523 | 469 s->predictors[chan] = av_clip_int16(s->predictors[chan]); |
3191 | 470 out[i] = s->predictors[chan]; |
471 chan ^= stereo; | |
472 } | |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
473 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
474 |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
475 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, |
6291 | 476 const uint8_t *buf, int silence) |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
477 { |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
478 int bytes_decoded = 0; |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
479 int i; |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
480 |
3191 | 481 // if (silence) |
482 // 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
|
483 if (s->channels == 2) { |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
484 |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
485 /* stereo handling */ |
3191 | 486 if (silence) { |
487 memset(data, 0, s->block_align * 2); | |
488 } else { | |
489 if (s->bits == 16) | |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
490 vmdaudio_decode_audio(s, data, buf, 1); |
4182 | 491 else { |
3191 | 492 /* copy the data but convert it to signed */ |
4182 | 493 for (i = 0; i < s->block_align; i++){ |
494 *data++ = buf[i] + 0x80; | |
495 *data++ = buf[i] + 0x80; | |
496 } | |
497 } | |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
498 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
499 } else { |
3191 | 500 bytes_decoded = s->block_align * 2; |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
501 |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
502 /* mono handling */ |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
503 if (silence) { |
3191 | 504 memset(data, 0, s->block_align * 2); |
505 } else { | |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
506 if (s->bits == 16) { |
3191 | 507 vmdaudio_decode_audio(s, data, buf, 0); |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
508 } else { |
3191 | 509 /* copy the data but convert it to signed */ |
4182 | 510 for (i = 0; i < s->block_align; i++){ |
511 *data++ = buf[i] + 0x80; | |
512 *data++ = buf[i] + 0x80; | |
513 } | |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
514 } |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
515 } |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
516 } |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
517 |
3191 | 518 return s->block_align * 2; |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
519 } |
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 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
|
522 void *data, int *data_size, |
6291 | 523 const uint8_t *buf, int buf_size) |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
524 { |
4827 | 525 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
|
526 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
|
527 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
528 /* point to the start of the encoded data */ |
6291 | 529 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
|
530 |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
531 if (buf_size < 16) |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
532 return buf_size; |
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
533 |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
534 if (buf[6] == 1) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
535 /* the chunk contains audio */ |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
536 *data_size = vmdaudio_loadsound(s, output_samples, p, 0); |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
537 } else if (buf[6] == 2) { |
4213
42553b85aa7e
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
4182
diff
changeset
|
538 /* the chunk may contain audio */ |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
539 p += 4; |
4213
42553b85aa7e
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
4182
diff
changeset
|
540 *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16)); |
42553b85aa7e
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
4182
diff
changeset
|
541 output_samples += (s->block_align * s->bits / 8); |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
542 } else if (buf[6] == 3) { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
543 /* silent chunk */ |
1882
5456ab242388
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
1823
diff
changeset
|
544 *data_size = vmdaudio_loadsound(s, output_samples, p, 1); |
1717
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
545 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
546 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
547 return buf_size; |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
548 } |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
549 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
550 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
551 /* |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
552 * Public Data Structures |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
553 */ |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
554 |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
555 AVCodec vmdvideo_decoder = { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
556 "vmdvideo", |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
557 CODEC_TYPE_VIDEO, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
558 CODEC_ID_VMDVIDEO, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
559 sizeof(VmdVideoContext), |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
560 vmdvideo_decode_init, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
561 NULL, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
562 vmdvideo_decode_end, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
563 vmdvideo_decode_frame, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
564 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6750
diff
changeset
|
565 .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
|
566 }; |
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 AVCodec vmdaudio_decoder = { |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
569 "vmdaudio", |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
570 CODEC_TYPE_AUDIO, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
571 CODEC_ID_VMDAUDIO, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
572 sizeof(VmdAudioContext), |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
573 vmdaudio_decode_init, |
6a7e68899d8a
first pass at Sierra VMD A/V decoders; video looks great, audio is not
melanson
parents:
diff
changeset
|
574 NULL, |
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 vmdaudio_decode_frame, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6750
diff
changeset
|
577 .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
|
578 }; |