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
29
35 // { AV_CODEC_ID_NELLYMOSER, 0x06 },
37 };
38
40 {
42
45
47 len = tag & 0x3f;
48 tag = tag >> 6;
49 if (len == 0x3f) {
51 }
54 }
55
56
58 {
60 int len, xmin, xmax, ymin, ymax;
61
63 return 0;
64
65 /* check file header */
68 return 0;
69
71
74 if (!len)
75 return 0;
80 if (xmin || ymin || !xmax || !ymax)
81 return 0;
82
83 if (p->
buf[3] >= 20 || xmax < 16 || ymax < 16)
85
87 }
88
89 #if CONFIG_ZLIB
90 static int zlib_refill(
void *opaque,
uint8_t *
buf,
int buf_size)
91 {
94 z_stream *z = &swf->zstream;
96
97 retry:
98 if (!z->avail_in) {
100 if (n < 0)
102 z->next_in = swf->zbuf_in;
104 }
105
107 z->avail_out = buf_size;
108
109 ret = inflate(z, Z_NO_FLUSH);
110 if (ret < 0)
112 if (ret == Z_STREAM_END)
114
115 if (buf_size - z->avail_out == 0)
116 goto retry;
117
118 return buf_size - z->avail_out;
119 }
120 #endif
121
123 {
127
130
131 if (tag ==
MKBETAG(
'C',
'W',
'S', 0)) {
133 #if CONFIG_ZLIB
138 if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
140 swf->zpb->seekable = 0;
141 if (inflateInit(&swf->zstream) != Z_OK) {
144 }
145 pb = swf->zpb;
146 #else
149 #endif
150 }
else if (tag !=
MKBETAG(
'F',
'W',
'S', 0))
152 /* skip rectangle size */
154 len = (4 * nbits - 3 + 7) / 8;
158
161 return 0;
162 }
163
165 {
166 int sample_rate_code, sample_size_code;
168 if (!ast)
171 if (info & 1) {
174 } else {
177 }
181 sample_rate_code = info>>2 & 3;
182 sample_size_code = info>>1 & 1;
187 return ast;
188 }
189
191 {
196
197 #if CONFIG_ZLIB
198 if (swf->zpb)
199 pb = swf->zpb;
200 #endif
201
202 for(;;) {
205 if (tag < 0)
207 if (len < 0) {
210 }
213 len -= 2;
214
218 goto skip;
219 }
220
225 /* Check for FLV1 */
227 if (!vst)
233 len -= 8;
235 /* streaming found */
236
240 goto skip;
241 }
242
247 if (!ast)
249 len -= 4;
251 /* audio stream */
253
257 goto skip;
258 }
259
260 // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
261 // these are smaller audio streams in DEFINESOUND tags, but it's technically
262 // possible they could be huge. Break it up into multiple packets if it's big.
265 if (!ast)
267 ast->duration =
avio_rl32(pb);
// number of samples
268 if (((v>>4) & 15) == 2) { // MP3 sound data record
270 len -= 2;
271 }
272 len -= 7;
274 return res;
280 len -= 2;
285 len -= 2;
286 if (len <= 0)
287 goto skip;
289 return res;
294 }
295 }
297 #if CONFIG_ZLIB
298 long out_len;
302 const int colormapbpp = 3 + alpha_bmp;
303 int linesize, colormapsize = 0;
304
306 const int bmp_fmt =
avio_r8(pb);
310
311 len -= 2+1+2+2;
312
313 switch (bmp_fmt) {
314 case 3: // PAL-8
316 colormapsize =
avio_r8(pb) + 1;
317 len--;
318 break;
319 case 4: // RGB15
320 linesize = width * 2;
321 break;
322 case 5: // RGB24 (0RGB)
323 linesize = width * 4;
324 break;
325 default:
327 goto bitmap_end_skip;
328 }
329
330 linesize =
FFALIGN(linesize, 4);
331
333 linesize >= INT_MAX / height ||
334 linesize * height >= INT_MAX - colormapsize * colormapbpp) {
336 goto bitmap_end_skip;
337 }
338
339 out_len = colormapsize * colormapbpp + linesize *
height;
340
341 av_dlog(s,
"bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
342 ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize);
343
346 if (!zbuf || !buf) {
348 goto bitmap_end;
349 }
350
352 if (len < 0 || (res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) {
354 goto bitmap_end_skip;
355 }
356
360 break;
361 }
364 if (!vst) {
366 goto bitmap_end;
367 }
368 vst->
id = -3;
/* -3 to avoid clash with video stream and audio stream */
372 st = vst;
373 }
374
375 if ((res =
av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0)
376 goto bitmap_end;
377 if (!st->codec->width && !st->codec->height) {
379 st->codec->height =
height;
380 } else {
382 }
385
386 switch (bmp_fmt) {
387 case 3:
389 for (i = 0; i < colormapsize; i++)
390 if (alpha_bmp) colormap[i] = buf[3]<<24 |
AV_RB24(buf + 4*i);
391 else colormap[i] = 0xff
U <<24 |
AV_RB24(buf + 3*i);
393 if (!pal) {
395 goto bitmap_end;
396 }
398 break;
399 case 4:
401 break;
402 case 5:
404 break;
405 default:
407 }
408 if (st->codec->pix_fmt !=
AV_PIX_FMT_NONE && st->codec->pix_fmt != pix_fmt) {
411 goto bitmap_end;
412 }
414
415 if (linesize * height > pkt->
size) {
417 goto bitmap_end;
418 }
419 memcpy(pkt->
data, buf + colormapsize*colormapbpp, linesize * height);
420
422
423 bitmap_end:
426 return res;
427 bitmap_end_skip:
430 #else
432 #endif
439 len -= 4;
440 if (len <= 0)
441 goto skip;
443 return res;
444 } else { // ADPCM, PCM
445 if (len <= 0)
446 goto skip;
448 return res;
449 }
453 }
454 }
459 break;
460 }
463 if (!vst)
465 vst->
id = -2;
/* -2 to avoid clash with video stream and audio stream */
469 st = vst;
470 }
472 len -= 2;
473 if (len < 4)
474 goto skip;
476 return res;
480 }
483 /* old SWF files containing SOI/EOI as data start */
484 /* files created by swink have reversed tag */
488 } else {
490 if (res >= 0)
491 res += 4;
492 }
493 if (res != pkt->
size) {
494 if (res < 0) {
496 return res;
497 }
499 }
500
504 } else {
506 }
507 skip:
508 if(len<0)
512 }
513 }
514
515 #if CONFIG_ZLIB
517 {
519 inflateEnd(&s->zstream);
523 return 0;
524 }
525 #endif
526
534 #if CONFIG_ZLIB
536 #endif
537 };