1 /*
2 * Flash Compatible Streaming Format demuxer
3 * Copyright (c) 2000 Fabrice Bellard
4 * Copyright (c) 2003 Tinic Uro
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
28
34 // { AV_CODEC_ID_NELLYMOSER, 0x06 },
36 };
37
39 {
41
44
46 len = tag & 0x3f;
47 tag = tag >> 6;
48 if (len == 0x3f) {
50 }
53 }
54
55
57 {
59 return 0;
60
61 /* check file header */
64 return 0;
65
68
70 }
71
72 #if CONFIG_ZLIB
73 static int zlib_refill(
void *opaque,
uint8_t *
buf,
int buf_size)
74 {
77 z_stream *z = &swf->zstream;
79
80 retry:
81 if (!z->avail_in) {
83 if (n < 0)
85 z->next_in = swf->zbuf_in;
87 }
88
90 z->avail_out = buf_size;
91
92 ret = inflate(z, Z_NO_FLUSH);
93 if (ret < 0)
95 if (ret == Z_STREAM_END)
97
98 if (buf_size - z->avail_out == 0)
99 goto retry;
100
101 return buf_size - z->avail_out;
102 }
103 #endif
104
106 {
110
113
114 if (tag ==
MKBETAG(
'C',
'W',
'S', 0)) {
116 #if CONFIG_ZLIB
120 zlib_refill, NULL, NULL);
121 if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
123 swf->zpb->seekable = 0;
124 if (inflateInit(&swf->zstream) != Z_OK) {
127 }
128 pb = swf->zpb;
129 #else
132 #endif
133 }
else if (tag !=
MKBETAG(
'F',
'W',
'S', 0))
135 /* skip rectangle size */
137 len = (4 * nbits - 3 + 7) / 8;
141
144 return 0;
145 }
146
148 {
149 int sample_rate_code, sample_size_code;
151 if (!ast)
152 return NULL;
154 if (info & 1) {
157 } else {
160 }
164 sample_rate_code = info>>2 & 3;
165 sample_size_code = info>>1 & 1;
170 return ast;
171 }
172
174 {
177 AVStream *vst = NULL, *ast = NULL, *st = 0;
179
180 #if CONFIG_ZLIB
181 if (swf->zpb)
182 pb = swf->zpb;
183 #endif
184
185 for(;;) {
188 if (tag < 0)
190 if (len < 0) {
193 }
196 len -= 2;
197
201 goto skip;
202 }
203
208 /* Check for FLV1 */
210 if (!vst)
216 len -= 8;
218 /* streaming found */
219
223 goto skip;
224 }
225
230 if (!ast)
232 len -= 4;
234 /* audio stream */
236
240 goto skip;
241 }
242
243 // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
244 // these are smaller audio streams in DEFINESOUND tags, but it's technically
245 // possible they could be huge. Break it up into multiple packets if it's big.
248 if (!ast)
250 ast->duration =
avio_rl32(pb);
// number of samples
251 if (((v>>4) & 15) == 2) { // MP3 sound data record
253 len -= 2;
254 }
255 len -= 7;
263 len -= 2;
268 len -= 2;
269 if (len <= 0)
270 goto skip;
277 }
278 }
280 #if CONFIG_ZLIB
281 long out_len;
282 uint8_t *buf = NULL, *zbuf = NULL, *pal;
285 const int colormapbpp = 3 + alpha_bmp;
286 int linesize, colormapsize = 0;
287
289 const int bmp_fmt =
avio_r8(pb);
292
293 len -= 2+1+2+2;
294
295 switch (bmp_fmt) {
296 case 3: // PAL-8
298 colormapsize =
avio_r8(pb) + 1;
299 len--;
300 break;
301 case 4: // RGB15
302 linesize = width * 2;
303 break;
304 case 5: // RGB24 (0RGB)
305 linesize = width * 4;
306 break;
307 default:
309 goto bitmap_end_skip;
310 }
311
312 linesize =
FFALIGN(linesize, 4);
313
315 linesize >= INT_MAX / height ||
316 linesize * height >= INT_MAX - colormapsize * colormapbpp) {
318 goto bitmap_end_skip;
319 }
320
321 out_len = colormapsize * colormapbpp + linesize *
height;
322
323 av_dlog(s,
"bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
324 ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize);
325
328 if (!zbuf || !buf) {
330 goto bitmap_end;
331 }
332
334 if (len < 0 || (res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) {
336 goto bitmap_end_skip;
337 }
338
342 break;
343 }
346 if (!vst) {
348 goto bitmap_end;
349 }
350 vst->
id = -3;
/* -3 to avoid clash with video stream and audio stream */
354 st = vst;
355 }
357 st->codec->height =
height;
358
359 if ((res =
av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0)
360 goto bitmap_end;
363
364 switch (bmp_fmt) {
365 case 3:
367 for (i = 0; i < colormapsize; i++)
368 if (alpha_bmp) colormap[i] = buf[3]<<24 |
AV_RB24(buf + 4*i);
369 else colormap[i] = 0xff
U <<24 |
AV_RB24(buf + 3*i);
371 if (!pal) {
373 goto bitmap_end;
374 }
376 break;
377 case 4:
379 break;
380 case 5:
382 break;
383 default:
385 }
386
387 if (linesize * height > pkt->
size) {
389 goto bitmap_end;
390 }
391 memcpy(pkt->
data, buf + colormapsize*colormapbpp, linesize * height);
392
394
395 bitmap_end:
399 bitmap_end_skip:
402 #else
404 #endif
411 len -= 4;
412 if (len <= 0)
413 goto skip;
416 } else { // ADPCM, PCM
417 if (len <= 0)
418 goto skip;
421 }
425 }
426 }
431 break;
432 }
435 if (!vst)
437 vst->
id = -2;
/* -2 to avoid clash with video stream and audio stream */
441 st = vst;
442 }
444 len -= 2;
445 if (len < 4)
446 goto skip;
452 }
455 /* old SWF files containing SOI/EOI as data start */
456 /* files created by swink have reversed tag */
460 } else {
462 if (res >= 0)
463 res += 4;
464 }
465 if (res != pkt->
size) {
466 if (res < 0) {
469 }
471 }
472
476 } else {
478 }
479 skip:
480 if(len<0)
484 }
485 }
486
487 #if CONFIG_ZLIB
489 {
491 inflateEnd(&s->zstream);
495 return 0;
496 }
497 #endif
498
506 #if CONFIG_ZLIB
508 #endif
509 };