2 * Flash Compatible Streaming Format demuxer
3 * Copyright (c) 2000 Fabrice Bellard
4 * Copyright (c) 2003 Tinic Uro
6 * This file is part of FFmpeg.
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.
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.
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
29 #include "libavutil/avassert.h"
30 #include "libavutil/channel_layout.h"
31 #include "libavutil/imgutils.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavcodec/get_bits.h"
38 typedef struct SWFDecContext
{
39 int samples_per_frame
;
42 #define ZBUF_SIZE 4096
50 static const AVCodecTag swf_audio_codec_tags
[] = {
51 { AV_CODEC_ID_PCM_S16LE
, 0x00 },
52 { AV_CODEC_ID_ADPCM_SWF
, 0x01 },
53 { AV_CODEC_ID_MP3
, 0x02 },
54 { AV_CODEC_ID_PCM_S16LE
, 0x03 },
55 { AV_CODEC_ID_NELLYMOSER
, 0x06 },
56 { AV_CODEC_ID_NONE
, 0 },
59 static int get_swf_tag(AVIOContext
*pb
, int *len_ptr
)
77 static int swf_probe(const AVProbeData
*p
)
80 int len
, xmin
, xmax
, ymin
, ymax
;
85 /* check file header */
86 if ( AV_RB24(p
->buf
) != AV_RB24("CWS")
87 && AV_RB24(p
->buf
) != AV_RB24("FWS"))
90 if ( AV_RB24(p
->buf
) == AV_RB24("CWS")
92 return AVPROBE_SCORE_MAX
/ 4 + 1;
94 if (init_get_bits8(&gb
, p
->buf
+ 8, p
->buf_size
- 8) < 0)
97 len
= get_bits(&gb
, 5);
100 xmin
= get_bits_long(&gb
, len
);
101 xmax
= get_bits_long(&gb
, len
);
102 ymin
= get_bits_long(&gb
, len
);
103 ymax
= get_bits_long(&gb
, len
);
104 if (xmin
|| ymin
|| !xmax
|| !ymax
)
107 if (p
->buf
[3] >= 20 || xmax
< 16 || ymax
< 16)
108 return AVPROBE_SCORE_MAX
/ 4;
110 return AVPROBE_SCORE_EXTENSION
+ 1;
114 static int zlib_refill(void *opaque
, uint8_t *buf
, int buf_size
)
116 AVFormatContext
*s
= opaque
;
117 SWFDecContext
*swf
= s
->priv_data
;
118 z_stream
*z
= &swf
->zstream
;
123 int n
= avio_read(s
->pb
, swf
->zbuf_in
, ZBUF_SIZE
);
126 z
->next_in
= swf
->zbuf_in
;
131 z
->avail_out
= buf_size
;
133 ret
= inflate(z
, Z_NO_FLUSH
);
134 if (ret
== Z_STREAM_END
)
137 return AVERROR(EINVAL
);
139 if (buf_size
- z
->avail_out
== 0)
142 return buf_size
- z
->avail_out
;
145 static av_cold
int swf_read_close(AVFormatContext
*avctx
);
148 static int swf_read_header(AVFormatContext
*s
)
150 SWFDecContext
*swf
= s
->priv_data
;
151 AVIOContext
*pb
= s
->pb
;
154 tag
= avio_rb32(pb
) & 0xffffff00;
157 if (tag
== MKBETAG('C', 'W', 'S', 0)) {
158 av_log(s
, AV_LOG_INFO
, "SWF compressed file detected\n");
160 if (inflateInit(&swf
->zstream
) != Z_OK
) {
161 av_log(s
, AV_LOG_ERROR
, "Unable to init zlib context\n");
162 return AVERROR(EINVAL
);
164 if (!(swf
->zbuf_in
= av_malloc(ZBUF_SIZE
)) ||
165 !(swf
->zbuf_out
= av_malloc(ZBUF_SIZE
)) ||
166 !(swf
->zpb
= avio_alloc_context(swf
->zbuf_out
, ZBUF_SIZE
, 0,
167 s
, zlib_refill
, NULL
, NULL
))) {
169 return AVERROR(ENOMEM
);
171 swf
->zpb
->seekable
= 0;
174 av_log(s
, AV_LOG_ERROR
, "zlib support is required to read SWF compressed files\n");
177 } else if (tag
!= MKBETAG('F', 'W', 'S', 0))
179 /* skip rectangle size */
180 nbits
= avio_r8(pb
) >> 3;
181 len
= (4 * nbits
- 3 + 7) / 8;
183 swf
->frame_rate
= avio_rl16(pb
); /* 8.8 fixed */
184 avio_rl16(pb
); /* frame count */
186 swf
->samples_per_frame
= 0;
187 s
->ctx_flags
|= AVFMTCTX_NOHEADER
;
191 static AVStream
*create_new_audio_stream(AVFormatContext
*s
, int id
, int info
)
193 int sample_rate_code
, sample_size_code
;
194 AVStream
*ast
= avformat_new_stream(s
, NULL
);
199 ast
->codecpar
->channels
= 2;
200 ast
->codecpar
->channel_layout
= AV_CH_LAYOUT_STEREO
;
202 ast
->codecpar
->channels
= 1;
203 ast
->codecpar
->channel_layout
= AV_CH_LAYOUT_MONO
;
205 ast
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
206 ast
->codecpar
->codec_id
= ff_codec_get_id(swf_audio_codec_tags
, info
>>4 & 15);
207 ffstream(ast
)->need_parsing
= AVSTREAM_PARSE_FULL
;
208 sample_rate_code
= info
>>2 & 3;
209 sample_size_code
= info
>>1 & 1;
210 if (!sample_size_code
&& ast
->codecpar
->codec_id
== AV_CODEC_ID_PCM_S16LE
)
211 ast
->codecpar
->codec_id
= AV_CODEC_ID_PCM_U8
;
212 ast
->codecpar
->sample_rate
= 44100 >> (3 - sample_rate_code
);
213 avpriv_set_pts_info(ast
, 64, 1, ast
->codecpar
->sample_rate
);
217 static int swf_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
219 SWFDecContext
*swf
= s
->priv_data
;
220 AVIOContext
*pb
= s
->pb
;
221 AVStream
*vst
= NULL
, *ast
= NULL
, *st
= 0;
222 int tag
, len
, i
, frame
, v
, res
;
230 uint64_t pos
= avio_tell(pb
);
231 tag
= get_swf_tag(pb
, &len
);
235 av_log(s
, AV_LOG_ERROR
, "invalid tag length: %d\n", len
);
236 return AVERROR_INVALIDDATA
;
238 if (tag
== TAG_VIDEOSTREAM
) {
239 int ch_id
= avio_rl16(pb
);
242 for (i
=0; i
<s
->nb_streams
; i
++) {
244 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
&& st
->id
== ch_id
)
253 vst
= avformat_new_stream(s
, NULL
);
255 return AVERROR(ENOMEM
);
257 vst
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
258 vst
->codecpar
->codec_id
= ff_codec_get_id(ff_swf_codec_tags
, avio_r8(pb
));
259 avpriv_set_pts_info(vst
, 16, 256, swf
->frame_rate
);
261 } else if (tag
== TAG_STREAMHEAD
|| tag
== TAG_STREAMHEAD2
) {
262 /* streaming found */
264 for (i
=0; i
<s
->nb_streams
; i
++) {
266 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
&& st
->id
== -1)
272 swf
->samples_per_frame
= avio_rl16(pb
);
273 ast
= create_new_audio_stream(s
, -1, v
); /* -1 to avoid clash with video stream ch_id */
275 return AVERROR(ENOMEM
);
277 } else if (tag
== TAG_DEFINESOUND
) {
279 int ch_id
= avio_rl16(pb
);
281 for (i
=0; i
<s
->nb_streams
; i
++) {
283 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
&& st
->id
== ch_id
)
287 // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
288 // these are smaller audio streams in DEFINESOUND tags, but it's technically
289 // possible they could be huge. Break it up into multiple packets if it's big.
291 ast
= create_new_audio_stream(s
, ch_id
, v
);
293 return AVERROR(ENOMEM
);
294 ast
->duration
= avio_rl32(pb
); // number of samples
295 if (((v
>>4) & 15) == 2) { // MP3 sound data record
296 ffstream(ast
)->skip_samples
= avio_rl16(pb
);
300 if ((res
= av_get_packet(pb
, pkt
, len
)) < 0)
303 pkt
->stream_index
= ast
->index
;
305 } else if (tag
== TAG_VIDEOFRAME
) {
306 int ch_id
= avio_rl16(pb
);
308 for(i
=0; i
<s
->nb_streams
; i
++) {
310 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
&& st
->id
== ch_id
) {
312 frame
= avio_rl16(pb
);
316 if (st
->codecpar
->codec_id
== AV_CODEC_ID_FLASHSV
) {
317 unsigned flags
= avio_r8(pb
);
321 pkt_flags
|= (flags
& FLV_VIDEO_FRAMETYPE_MASK
) == FLV_FRAME_KEY
? AV_PKT_FLAG_KEY
: 0;
323 if ((res
= av_get_packet(pb
, pkt
, len
)) < 0)
327 pkt
->stream_index
= st
->index
;
328 pkt
->flags
|= pkt_flags
;
332 } else if (tag
== TAG_DEFINEBITSLOSSLESS
|| tag
== TAG_DEFINEBITSLOSSLESS2
) {
335 uint8_t *buf
= NULL
, *zbuf
= NULL
, *pal
;
336 uint32_t colormap
[AVPALETTE_COUNT
] = {0};
337 const int alpha_bmp
= tag
== TAG_DEFINEBITSLOSSLESS2
;
338 const int colormapbpp
= 3 + alpha_bmp
;
339 int linesize
, colormapsize
= 0;
341 const int ch_id
= avio_rl16(pb
);
342 const int bmp_fmt
= avio_r8(pb
);
343 const int width
= avio_rl16(pb
);
344 const int height
= avio_rl16(pb
);
352 colormapsize
= avio_r8(pb
) + 1;
356 linesize
= width
* 2;
358 case 5: // RGB24 (0RGB)
359 linesize
= width
* 4;
362 av_log(s
, AV_LOG_ERROR
, "invalid bitmap format %d, skipped\n", bmp_fmt
);
363 goto bitmap_end_skip
;
366 linesize
= FFALIGN(linesize
, 4);
368 if (av_image_check_size(width
, height
, 0, s
) < 0 ||
369 linesize
>= INT_MAX
/ height
||
370 linesize
* height
>= INT_MAX
- colormapsize
* colormapbpp
) {
371 av_log(s
, AV_LOG_ERROR
, "invalid frame size %dx%d\n", width
, height
);
372 goto bitmap_end_skip
;
375 out_len
= colormapsize
* colormapbpp
+ linesize
* height
;
377 ff_dlog(s
, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
378 ch_id
, bmp_fmt
, width
, height
, linesize
, len
, out_len
, colormapsize
);
380 if (len
* 17373LL < out_len
)
381 goto bitmap_end_skip
;
383 zbuf
= av_malloc(len
);
385 res
= AVERROR(ENOMEM
);
389 len
= avio_read(pb
, zbuf
, len
);
391 goto bitmap_end_skip
;
393 buf
= av_malloc(out_len
);
395 res
= AVERROR(ENOMEM
);
398 if ((res
= uncompress(buf
, &out_len
, zbuf
, len
)) != Z_OK
) {
399 av_log(s
, AV_LOG_WARNING
, "Failed to uncompress one bitmap\n");
400 goto bitmap_end_skip
;
403 for (i
= 0; i
< s
->nb_streams
; i
++) {
405 if (st
->codecpar
->codec_id
== AV_CODEC_ID_RAWVIDEO
&& st
->id
== -3)
408 if (i
== s
->nb_streams
) {
409 vst
= avformat_new_stream(s
, NULL
);
411 res
= AVERROR(ENOMEM
);
414 vst
->id
= -3; /* -3 to avoid clash with video stream and audio stream */
415 vst
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
416 vst
->codecpar
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
417 avpriv_set_pts_info(vst
, 64, 256, swf
->frame_rate
);
421 if ((res
= av_new_packet(pkt
, out_len
- colormapsize
* colormapbpp
)) < 0)
423 if (!st
->codecpar
->width
&& !st
->codecpar
->height
) {
424 st
->codecpar
->width
= width
;
425 st
->codecpar
->height
= height
;
427 ff_add_param_change(pkt
, 0, 0, 0, width
, height
);
430 pkt
->stream_index
= st
->index
;
432 if (linesize
* height
> pkt
->size
) {
433 res
= AVERROR_INVALIDDATA
;
439 pix_fmt
= AV_PIX_FMT_PAL8
;
440 for (i
= 0; i
< colormapsize
; i
++)
441 if (alpha_bmp
) colormap
[i
] = buf
[3]<<24 | AV_RB24(buf
+ 4*i
);
442 else colormap
[i
] = 0xffU
<<24 | AV_RB24(buf
+ 3*i
);
443 pal
= av_packet_new_side_data(pkt
, AV_PKT_DATA_PALETTE
, AVPALETTE_SIZE
);
445 res
= AVERROR(ENOMEM
);
448 memcpy(pal
, colormap
, AVPALETTE_SIZE
);
451 pix_fmt
= AV_PIX_FMT_RGB555
;
454 pix_fmt
= alpha_bmp
? AV_PIX_FMT_ARGB
: AV_PIX_FMT_0RGB
;
459 if (st
->codecpar
->format
!= AV_PIX_FMT_NONE
&& st
->codecpar
->format
!= pix_fmt
) {
460 av_log(s
, AV_LOG_ERROR
, "pixel format change unsupported\n");
462 st
->codecpar
->format
= pix_fmt
;
464 memcpy(pkt
->data
, buf
+ colormapsize
*colormapbpp
, linesize
* height
);
476 av_log(s
, AV_LOG_ERROR
, "this file requires zlib support compiled in\n");
478 } else if (tag
== TAG_STREAMBLOCK
) {
479 for (i
= 0; i
< s
->nb_streams
; i
++) {
481 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
&& st
->id
== -1) {
482 if (st
->codecpar
->codec_id
== AV_CODEC_ID_MP3
) {
487 if ((res
= av_get_packet(pb
, pkt
, len
)) < 0)
489 } else { // ADPCM, PCM
492 if ((res
= av_get_packet(pb
, pkt
, len
)) < 0)
496 pkt
->stream_index
= st
->index
;
500 } else if (tag
== TAG_JPEG2
) {
501 for (i
=0; i
<s
->nb_streams
; i
++) {
503 if (st
->codecpar
->codec_id
== AV_CODEC_ID_MJPEG
&& st
->id
== -2)
506 if (i
== s
->nb_streams
) {
507 vst
= avformat_new_stream(s
, NULL
);
509 return AVERROR(ENOMEM
);
510 vst
->id
= -2; /* -2 to avoid clash with video stream and audio stream */
511 vst
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
512 vst
->codecpar
->codec_id
= AV_CODEC_ID_MJPEG
;
513 avpriv_set_pts_info(vst
, 64, 256, swf
->frame_rate
);
516 avio_rl16(pb
); /* BITMAP_ID */
520 if ((res
= av_new_packet(pkt
, len
)) < 0)
522 if (avio_read(pb
, pkt
->data
, 4) != 4) {
523 return AVERROR_INVALIDDATA
;
525 if (AV_RB32(pkt
->data
) == 0xffd8ffd9 ||
526 AV_RB32(pkt
->data
) == 0xffd9ffd8) {
527 /* old SWF files containing SOI/EOI as data start */
528 /* files created by swink have reversed tag */
530 memset(pkt
->data
+pkt
->size
, 0, 4);
531 res
= avio_read(pb
, pkt
->data
, pkt
->size
);
533 res
= avio_read(pb
, pkt
->data
+ 4, pkt
->size
- 4);
537 if (res
!= pkt
->size
) {
541 av_shrink_packet(pkt
, res
);
545 pkt
->stream_index
= st
->index
;
548 av_log(s
, AV_LOG_DEBUG
, "Unknown tag: %d\n", tag
);
552 av_log(s
, AV_LOG_WARNING
, "Clipping len %d\n", len
);
559 static av_cold
int swf_read_close(AVFormatContext
*avctx
)
561 SWFDecContext
*s
= avctx
->priv_data
;
562 inflateEnd(&s
->zstream
);
563 av_freep(&s
->zbuf_in
);
564 av_freep(&s
->zbuf_out
);
565 avio_context_free(&s
->zpb
);
570 const AVInputFormat ff_swf_demuxer
= {
572 .long_name
= NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
573 .priv_data_size
= sizeof(SWFDecContext
),
574 .read_probe
= swf_probe
,
575 .read_header
= swf_read_header
,
576 .read_packet
= swf_read_packet
,
578 .read_close
= swf_read_close
,