1 /*
2 * Smacker demuxer
3 * Copyright (c) 2006 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /*
23 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
24 */
25
26 #include <inttypes.h>
27
35
36 #define SMACKER_PAL 0x01
37 #define SMACKER_FLAG_RING_FRAME 0x01
38 #define SMACKER_FLAG_Y_INTERLACE (1 << 1)
39 #define SMACKER_FLAG_Y_DOUBLE (1 << 2)
40
47 };
48
51 /* frame info */
54 /* internal variables */
60 /* current frame for demuxing */
68
69 /* palette used in Smacker */
71 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
72 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
73 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D,
74 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D,
75 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9A, 0x9E,
76 0xA2, 0xA6, 0xAA, 0xAE, 0xB2, 0xB6, 0xBA, 0xBE,
77 0xC3, 0xC7, 0xCB, 0xCF, 0xD3, 0xD7, 0xDB, 0xDF,
78 0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF
79 };
80
81
83 {
86 return 0;
87
90
92 }
93
95 {
103 int tbase;
104
105 /* read and check header */
107 if (magic !=
MKTAG(
'S',
'M',
'K',
'2') && magic !=
MKTAG(
'S',
'M',
'K',
'4'))
113 if (pts_inc > INT_MAX / 100 || pts_inc == INT_MIN) {
116 }
117
121 if (smk->
frames > 0xFFFFFF) {
124 }
125
126 avio_skip(pb, 28);
/* Unused audio related data */
127
129 if (treesize >= UINT_MAX/4) {
130 // treesize + 16 must not overflow (this check is probably redundant)
133 }
134
136 if (!st)
138
140 /* Smacker uses 100000 as internal timebase */
141 if (pts_inc < 0)
142 pts_inc = -pts_inc;
143 else
144 pts_inc *= 100;
145 tbase = 100000;
146 av_reduce(&tbase, &pts_inc, tbase, pts_inc, (1UL << 31) - 1);
149
152
153 /* init video codec */
161
164 "Cannot allocate %"PRIu32" bytes of extradata\n",
165 treesize + 16);
167 }
170
171 /* handle possible audio streams */
172 for (
i = 0;
i < 7;
i++) {
175
177
178 if (rate) {
181 if (!ast)
183
194 } else {
196 }
204 else
208 }
209 }
210
212
213 /* setup data */
220
221 /* read frame info */
229 }
231 /* load trees to extradata, they will be unpacked by decoder */
235 }
236
237 return 0;
238 }
239
241 {
245
248
249 /* if we demuxed all streams, pass another frame */
255 /* handle palette change event */
258 uint8_t *pal = smk->
pal;
259 uint8_t oldpal[768];
260
261 memcpy(oldpal, pal, 768);
266 goto next_frame;
267 }
269 sz = 0;
271 while (sz < 256) {
273 if (t & 0x80) { /* skip palette entries */
274 sz += (t & 0x7F) + 1;
275 pal += ((t & 0x7F) + 1) * 3;
276 } else if (t & 0x40) { /* copy with offset */
278 j = (t & 0x3F) + 1;
279 if (off + j > 0x100) {
281 "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
282 off, j);
284 goto next_frame;
285 }
286 off *= 3;
287 while (j-- && sz < 256) {
288 *pal++ = oldpal[off + 0];
289 *pal++ = oldpal[off + 1];
290 *pal++ = oldpal[off + 2];
291 sz++;
292 off += 3;
293 }
294 } else { /* new entries */
298 sz++;
299 }
300 }
303 }
304 }
305
307 if (smk->
flags & (1 <<
i)) {
309
314 goto next_frame;
315 }
318
324 continue;
325 }
328 goto next_frame;
329 }
336 return 0;
337 }
338 }
339
342 goto next_frame;
343 }
346 goto next_frame;
347 }
349 goto next_frame;
357 goto next_frame;
366
367 return 0;
368 next_frame:
373 }
374
377 {
382
384 return -1;
385
386 if (timestamp < 0 || timestamp >= smk->
frames)
388
392
398
402 memset(smk->
pal, 0,
sizeof(smk->
pal));
404
405 return 0;
406 }
407
416 };