2 * Flash Compatible Streaming Format
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
23 #include "bitstream.h"
24 #include "riff.h" /* for CodecTag */
26 /* should have a generic way to indicate probable size */
27 #define DUMMY_FILE_SIZE (100 * 1024 * 1024)
28 #define DUMMY_DURATION 600 /* in seconds */
31 #define TAG_SHOWFRAME 1
32 #define TAG_DEFINESHAPE 2
33 #define TAG_FREECHARACTER 3
34 #define TAG_PLACEOBJECT 4
35 #define TAG_REMOVEOBJECT 5
36 #define TAG_STREAMHEAD 18
37 #define TAG_STREAMBLOCK 19
39 #define TAG_PLACEOBJECT2 26
40 #define TAG_STREAMHEAD2 45
41 #define TAG_VIDEOSTREAM 60
42 #define TAG_VIDEOFRAME 61
44 #define TAG_LONG 0x100
46 /* flags for shape definition */
47 #define FLAG_MOVETO 0x01
48 #define FLAG_SETFILL0 0x02
49 #define FLAG_SETFILL1 0x04
51 #define AUDIO_FIFO_SIZE 65536
53 /* character id used */
62 int audio_stream_index;
63 offset_t duration_pos;
66 int samples_per_frame;
70 int video_frame_number;
83 static const AVCodecTag swf_codec_tags[] = {
84 {CODEC_ID_FLV1, 0x02},
85 {CODEC_ID_VP6F, 0x04},
89 static const int sSampleRates[3][4] = {
90 {44100, 48000, 32000, 0},
91 {22050, 24000, 16000, 0},
92 {11025, 12000, 8000, 0},
95 static const int sBitRates[2][3][15] = {
96 { { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
97 { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
98 { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
100 { { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
101 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
102 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
106 static const int sSamplesPerFrame[3][3] =
113 static const int sBitsPerSlot[3] = {
119 static int swf_mp3_info(void *data, int *byteSize, int *samplesPerFrame, int *sampleRate, int *isMono )
121 uint32_t header = AV_RB32(data);
122 int layerID = 3 - ((header >> 17) & 0x03);
123 int bitRateID = ((header >> 12) & 0x0f);
124 int sampleRateID = ((header >> 10) & 0x03);
126 int bitsPerSlot = sBitsPerSlot[layerID];
127 int isPadded = ((header >> 9) & 0x01);
129 if ( (( header >> 21 ) & 0x7ff) != 0x7ff ) {
133 *isMono = ((header >> 6) & 0x03) == 0x03;
135 if ( (header >> 19 ) & 0x01 ) {
136 *sampleRate = sSampleRates[0][sampleRateID];
137 bitRate = sBitRates[0][layerID][bitRateID] * 1000;
138 *samplesPerFrame = sSamplesPerFrame[0][layerID];
140 if ( (header >> 20) & 0x01 ) {
141 *sampleRate = sSampleRates[1][sampleRateID];
142 bitRate = sBitRates[1][layerID][bitRateID] * 1000;
143 *samplesPerFrame = sSamplesPerFrame[1][layerID];
145 *sampleRate = sSampleRates[2][sampleRateID];
146 bitRate = sBitRates[1][layerID][bitRateID] * 1000;
147 *samplesPerFrame = sSamplesPerFrame[2][layerID];
151 *byteSize = ( ( ( ( *samplesPerFrame * (bitRate / bitsPerSlot) ) / *sampleRate ) + isPadded ) );
157 static void put_swf_tag(AVFormatContext *s, int tag)
159 SWFContext *swf = s->priv_data;
160 ByteIOContext *pb = &s->pb;
162 swf->tag_pos = url_ftell(pb);
164 /* reserve some room for the tag */
165 if (tag & TAG_LONG) {
173 static void put_swf_end_tag(AVFormatContext *s)
175 SWFContext *swf = s->priv_data;
176 ByteIOContext *pb = &s->pb;
181 tag_len = pos - swf->tag_pos - 2;
183 url_fseek(pb, swf->tag_pos, SEEK_SET);
184 if (tag & TAG_LONG) {
186 put_le16(pb, (tag << 6) | 0x3f);
187 put_le32(pb, tag_len - 4);
189 assert(tag_len < 0x3f);
190 put_le16(pb, (tag << 6) | tag_len);
192 url_fseek(pb, pos, SEEK_SET);
195 static inline void max_nbits(int *nbits_ptr, int val)
211 static void put_swf_rect(ByteIOContext *pb,
212 int xmin, int xmax, int ymin, int ymax)
218 init_put_bits(&p, buf, sizeof(buf));
221 max_nbits(&nbits, xmin);
222 max_nbits(&nbits, xmax);
223 max_nbits(&nbits, ymin);
224 max_nbits(&nbits, ymax);
225 mask = (1 << nbits) - 1;
228 put_bits(&p, 5, nbits);
229 put_bits(&p, nbits, xmin & mask);
230 put_bits(&p, nbits, xmax & mask);
231 put_bits(&p, nbits, ymin & mask);
232 put_bits(&p, nbits, ymax & mask);
235 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
238 static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
242 put_bits(pb, 1, 1); /* edge */
243 put_bits(pb, 1, 1); /* line select */
245 max_nbits(&nbits, dx);
246 max_nbits(&nbits, dy);
248 mask = (1 << nbits) - 1;
249 put_bits(pb, 4, nbits - 2); /* 16 bits precision */
253 put_bits(pb, nbits, dy & mask);
254 } else if (dy == 0) {
257 put_bits(pb, nbits, dx & mask);
260 put_bits(pb, nbits, dx & mask);
261 put_bits(pb, nbits, dy & mask);
268 static void put_swf_matrix(ByteIOContext *pb,
269 int a, int b, int c, int d, int tx, int ty)
275 init_put_bits(&p, buf, sizeof(buf));
277 put_bits(&p, 1, 1); /* a, d present */
279 max_nbits(&nbits, a);
280 max_nbits(&nbits, d);
281 put_bits(&p, 5, nbits); /* nb bits */
282 put_bits(&p, nbits, a);
283 put_bits(&p, nbits, d);
285 put_bits(&p, 1, 1); /* b, c present */
287 max_nbits(&nbits, c);
288 max_nbits(&nbits, b);
289 put_bits(&p, 5, nbits); /* nb bits */
290 put_bits(&p, nbits, c);
291 put_bits(&p, nbits, b);
294 max_nbits(&nbits, tx);
295 max_nbits(&nbits, ty);
296 put_bits(&p, 5, nbits); /* nb bits */
297 put_bits(&p, nbits, tx);
298 put_bits(&p, nbits, ty);
301 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
305 static int swf_write_header(AVFormatContext *s)
307 SWFContext *swf = s->priv_data;
308 ByteIOContext *pb = &s->pb;
309 AVCodecContext *enc, *audio_enc, *video_enc;
312 int i, width, height, rate, rate_base;
314 swf->audio_in_pos = 0;
315 swf->audio_out_pos = 0;
317 swf->audio_fifo = av_malloc(AUDIO_FIFO_SIZE);
318 swf->sound_samples = 0;
319 swf->video_samples = 0;
320 swf->swf_frame_number = 0;
321 swf->video_frame_number = 0;
325 for(i=0;i<s->nb_streams;i++) {
326 enc = s->streams[i]->codec;
327 if (enc->codec_type == CODEC_TYPE_AUDIO)
330 if ( enc->codec_id == CODEC_ID_VP6F ||
331 enc->codec_id == CODEC_ID_FLV1 ||
332 enc->codec_id == CODEC_ID_MJPEG ) {
335 av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n");
342 /* currenty, cannot work correctly if audio only */
349 swf->video_type = video_enc->codec_id;
350 width = video_enc->width;
351 height = video_enc->height;
352 rate = video_enc->time_base.den;
353 rate_base = video_enc->time_base.num;
358 swf->samples_per_frame = ( 44100. * rate_base ) / rate;
360 swf->audio_type = audio_enc->codec_id;
361 swf->samples_per_frame = ( ( audio_enc->sample_rate ) * rate_base ) / rate;
365 if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) {
366 put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */
367 } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
368 put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
370 put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
372 put_le32(pb, DUMMY_FILE_SIZE); /* dummy size
373 (will be patched if not streamed) */
375 put_swf_rect(pb, 0, width * 20, 0, height * 20);
376 put_le16(pb, (rate * 256) / rate_base); /* frame rate */
377 swf->duration_pos = url_ftell(pb);
378 put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
380 /* define a shape with the jpeg inside */
381 if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
382 video_enc->codec_id == CODEC_ID_FLV1 )) {
383 } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
384 put_swf_tag(s, TAG_DEFINESHAPE);
386 put_le16(pb, SHAPE_ID); /* ID of shape */
387 /* bounding rectangle */
388 put_swf_rect(pb, 0, width, 0, height);
390 put_byte(pb, 1); /* one fill style */
391 put_byte(pb, 0x41); /* clipped bitmap fill */
392 put_le16(pb, BITMAP_ID); /* bitmap ID */
393 /* position of the bitmap */
394 put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
395 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
396 put_byte(pb, 0); /* no line style */
399 init_put_bits(&p, buf1, sizeof(buf1));
400 put_bits(&p, 4, 1); /* one fill bit */
401 put_bits(&p, 4, 0); /* zero line bit */
403 put_bits(&p, 1, 0); /* not an edge */
404 put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
405 put_bits(&p, 5, 1); /* nbits */
406 put_bits(&p, 1, 0); /* X */
407 put_bits(&p, 1, 0); /* Y */
408 put_bits(&p, 1, 1); /* set fill style 1 */
410 /* draw the rectangle ! */
411 put_swf_line_edge(&p, width, 0);
412 put_swf_line_edge(&p, 0, height);
413 put_swf_line_edge(&p, -width, 0);
414 put_swf_line_edge(&p, 0, -height);
417 put_bits(&p, 1, 0); /* not an edge */
421 put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
426 if (audio_enc && audio_enc->codec_id == CODEC_ID_MP3 ) {
430 put_swf_tag(s, TAG_STREAMHEAD2);
433 switch(audio_enc->sample_rate) {
445 av_log(s, AV_LOG_ERROR, "swf doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
446 av_free(swf->audio_fifo);
449 v |= 0x02; /* 16 bit playback */
450 if (audio_enc->channels == 2)
451 v |= 0x01; /* stereo playback */
453 v |= 0x20; /* mp3 compressed */
455 put_le16(&s->pb, swf->samples_per_frame); /* avg samples per frame */
461 put_flush_packet(&s->pb);
465 static int swf_write_video(AVFormatContext *s,
466 AVCodecContext *enc, const uint8_t *buf, int size)
468 SWFContext *swf = s->priv_data;
469 ByteIOContext *pb = &s->pb;
474 /* Flash Player limit */
475 if ( swf->swf_frame_number == 16000 ) {
476 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
479 if ( swf->audio_type ) {
480 /* Prescan audio data for this swf frame */
481 retry_swf_audio_packet:
482 if ( ( swf->audio_size-outSize ) >= 4 ) {
483 int mp3FrameSize = 0;
484 int mp3SampleRate = 0;
486 int mp3SamplesPerFrame = 0;
488 /* copy out mp3 header from ring buffer */
490 for (c=0; c<4; c++) {
491 header[c] = swf->audio_fifo[(swf->audio_in_pos+outSize+c) % AUDIO_FIFO_SIZE];
494 if ( swf_mp3_info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {
495 if ( ( swf->audio_size-outSize ) >= mp3FrameSize ) {
496 outSize += mp3FrameSize;
497 outSamples += mp3SamplesPerFrame;
498 if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
499 goto retry_swf_audio_packet;
503 /* invalid mp3 data, skip forward
504 we need to do this since the Flash Player
505 does not like custom headers */
506 swf->audio_in_pos ++;
508 swf->audio_in_pos %= AUDIO_FIFO_SIZE;
509 goto retry_swf_audio_packet;
513 /* audio stream is behind video stream, bail */
514 if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
519 if ( swf->video_type == CODEC_ID_VP6F ||
520 swf->video_type == CODEC_ID_FLV1 ) {
521 if ( swf->video_frame_number == 0 ) {
522 /* create a new video object */
523 put_swf_tag(s, TAG_VIDEOSTREAM);
524 put_le16(pb, VIDEO_ID);
525 put_le16(pb, 15000 ); /* hard flash player limit */
526 put_le16(pb, enc->width);
527 put_le16(pb, enc->height);
529 put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));
532 /* place the video object for the first time */
533 put_swf_tag(s, TAG_PLACEOBJECT2);
536 put_le16(pb, VIDEO_ID);
537 put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
538 put_le16(pb, swf->video_frame_number );
547 /* mark the character for update */
548 put_swf_tag(s, TAG_PLACEOBJECT2);
551 put_le16(pb, swf->video_frame_number );
555 /* set video frame data */
556 put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
557 put_le16(pb, VIDEO_ID);
558 put_le16(pb, swf->video_frame_number++ );
559 put_buffer(pb, buf, size);
561 } else if ( swf->video_type == CODEC_ID_MJPEG ) {
562 if (swf->swf_frame_number > 0) {
563 /* remove the shape */
564 put_swf_tag(s, TAG_REMOVEOBJECT);
565 put_le16(pb, SHAPE_ID); /* shape ID */
566 put_le16(pb, 1); /* depth */
569 /* free the bitmap */
570 put_swf_tag(s, TAG_FREECHARACTER);
571 put_le16(pb, BITMAP_ID);
575 put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
577 put_le16(pb, BITMAP_ID); /* ID of the image */
579 /* a dummy jpeg header seems to be required */
584 /* write the jpeg image */
585 put_buffer(pb, buf, size);
591 put_swf_tag(s, TAG_PLACEOBJECT);
592 put_le16(pb, SHAPE_ID); /* shape ID */
593 put_le16(pb, 1); /* depth */
594 put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
600 swf->swf_frame_number ++;
602 swf->video_samples += swf->samples_per_frame;
604 /* streaming sound always should be placed just before showframe tags */
606 put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
607 put_le16(pb, outSamples);
609 for (c=0; c<outSize; c++) {
610 put_byte(pb,swf->audio_fifo[(swf->audio_in_pos+c) % AUDIO_FIFO_SIZE]);
615 swf->sound_samples += outSamples;
616 swf->audio_in_pos += outSize;
617 swf->audio_size -= outSize;
618 swf->audio_in_pos %= AUDIO_FIFO_SIZE;
621 /* output the frame */
622 put_swf_tag(s, TAG_SHOWFRAME);
625 put_flush_packet(&s->pb);
630 static int swf_write_audio(AVFormatContext *s,
631 AVCodecContext *enc, const uint8_t *buf, int size)
633 SWFContext *swf = s->priv_data;
636 /* Flash Player limit */
637 if ( swf->swf_frame_number == 16000 ) {
638 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
641 if (enc->codec_id == CODEC_ID_MP3 ) {
642 for (c=0; c<size; c++) {
643 swf->audio_fifo[(swf->audio_out_pos+c)%AUDIO_FIFO_SIZE] = buf[c];
645 swf->audio_size += size;
646 swf->audio_out_pos += size;
647 swf->audio_out_pos %= AUDIO_FIFO_SIZE;
650 /* if audio only stream make sure we add swf frames */
651 if ( swf->video_type == 0 ) {
652 swf_write_video(s, enc, 0, 0);
658 static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
660 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
661 if (codec->codec_type == CODEC_TYPE_AUDIO)
662 return swf_write_audio(s, codec, pkt->data, pkt->size);
664 return swf_write_video(s, codec, pkt->data, pkt->size);
667 static int swf_write_trailer(AVFormatContext *s)
669 SWFContext *swf = s->priv_data;
670 ByteIOContext *pb = &s->pb;
671 AVCodecContext *enc, *video_enc;
675 for(i=0;i<s->nb_streams;i++) {
676 enc = s->streams[i]->codec;
677 if (enc->codec_type == CODEC_TYPE_VIDEO)
681 put_swf_tag(s, TAG_END);
684 put_flush_packet(&s->pb);
686 /* patch file size and number of frames if not streamed */
687 if (!url_is_streamed(&s->pb) && video_enc) {
688 file_size = url_ftell(pb);
689 url_fseek(pb, 4, SEEK_SET);
690 put_le32(pb, file_size);
691 url_fseek(pb, swf->duration_pos, SEEK_SET);
692 put_le16(pb, video_enc->frame_number);
693 url_fseek(pb, file_size, SEEK_SET);
696 av_free(swf->audio_fifo);
700 #endif //CONFIG_MUXERS
702 /*********************************************/
703 /* Extract FLV encoded frame and MP3 from swf
704 Note that the detection of the real frame
705 is inaccurate at this point as it can be
706 quite tricky to determine, you almost certainly
707 will get a bad audio/video sync */
709 static int get_swf_tag(ByteIOContext *pb, int *len_ptr)
722 // av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len);
728 static int swf_probe(AVProbeData *p)
730 /* check file header */
731 if (p->buf_size <= 16)
733 if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
735 return AVPROBE_SCORE_MAX;
740 static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
742 SWFContext *swf = s->priv_data;
743 ByteIOContext *pb = &s->pb;
744 int nbits, len, frame_rate, tag, v;
745 offset_t frame_offset = -1;
749 tag = get_be32(pb) & 0xffffff00;
751 if (tag == MKBETAG('C', 'W', 'S', 0))
753 av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
756 if (tag != MKBETAG('F', 'W', 'S', 0))
759 /* skip rectangle size */
760 nbits = get_byte(pb) >> 3;
761 len = (4 * nbits - 3 + 7) / 8;
763 frame_rate = get_le16(pb);
764 get_le16(pb); /* frame count */
766 /* The Flash Player converts 8.8 frame rates
767 to milliseconds internally. Do the same to get
768 a correct framerate */
769 swf->ms_per_frame = ( 1000 * 256 ) / frame_rate;
770 swf->samples_per_frame = 0;
773 offset_t tag_offset = url_ftell(pb);
774 tag = get_swf_tag(pb, &len);
775 if (tag < 0 || tag == TAG_VIDEOFRAME || tag == TAG_STREAMBLOCK) {
776 url_fseek(pb, frame_offset == -1 ? tag_offset : frame_offset, SEEK_SET);
779 if ( tag == TAG_VIDEOSTREAM && !vst) {
780 int ch_id = get_le16(pb);
786 vst = av_new_stream(s, ch_id);
787 vst->codec->codec_type = CODEC_TYPE_VIDEO;
788 vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
789 } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) {
790 /* streaming found */
791 int sample_rate_code;
794 swf->samples_per_frame = get_le16(pb);
795 ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */
796 av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
797 swf->audio_stream_index = ast->index;
798 ast->codec->channels = 1 + (v&1);
799 ast->codec->codec_type = CODEC_TYPE_AUDIO;
801 ast->codec->codec_id = CODEC_ID_MP3;
802 ast->need_parsing = 1;
803 sample_rate_code= (v>>2) & 3;
804 if (!sample_rate_code)
806 ast->codec->sample_rate = 11025 << (sample_rate_code-1);
810 } else if (tag == TAG_JPEG2 && !vst) {
811 vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */
812 vst->codec->codec_type = CODEC_TYPE_VIDEO;
813 vst->codec->codec_id = CODEC_ID_MJPEG;
815 frame_offset = tag_offset;
821 av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
822 if (swf->ms_per_frame) {
823 vst->codec->time_base.den = 1000. / swf->ms_per_frame;
824 vst->codec->time_base.num = 1;
830 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
832 SWFContext *swf = s->priv_data;
833 ByteIOContext *pb = &s->pb;
835 int tag, len, i, frame;
838 tag = get_swf_tag(pb, &len);
841 if (tag == TAG_VIDEOFRAME) {
842 int ch_id = get_le16(pb);
844 for( i=0; i<s->nb_streams; i++ ) {
846 if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) {
847 frame = get_le16(pb);
848 av_get_packet(pb, pkt, len-2);
849 pkt->pts = frame * swf->ms_per_frame;
850 pkt->stream_index = st->index;
854 } else if (tag == TAG_STREAMBLOCK) {
855 st = s->streams[swf->audio_stream_index];
856 if (st->codec->codec_id == CODEC_ID_MP3) {
858 av_get_packet(pb, pkt, len-4);
859 pkt->stream_index = st->index;
862 } else if (tag == TAG_JPEG2) {
863 for (i=0; i<s->nb_streams; i++) {
866 get_le16(pb); /* BITMAP_ID */
867 av_new_packet(pkt, len-2);
868 get_buffer(pb, pkt->data, 4);
869 if (AV_RB32(pkt->data) == 0xffd8ffd9) {
870 /* old SWF files containing SOI/EOI as data start */
872 get_buffer(pb, pkt->data, pkt->size);
874 get_buffer(pb, pkt->data + 4, pkt->size - 4);
876 pkt->stream_index = st->index;
886 static int swf_read_close(AVFormatContext *s)
891 #ifdef CONFIG_SWF_DEMUXER
892 AVInputFormat swf_demuxer = {
902 #ifdef CONFIG_SWF_MUXER
903 AVOutputFormat swf_muxer = {
906 "application/x-shockwave-flash",