Originally committed as revision 13203 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -30,7 +30,7 @@ OBJS-$(CONFIG_AU_MUXER) += au.o | |||
| OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o | |||
| OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o | |||
| OBJS-$(CONFIG_AVISYNTH) += avisynth.o | |||
| OBJS-$(CONFIG_AVM2_MUXER) += swf.o | |||
| OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o | |||
| OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o | |||
| OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o | |||
| OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o | |||
| @@ -161,8 +161,8 @@ OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o | |||
| OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o | |||
| OBJS-$(CONFIG_SOL_DEMUXER) += sol.o raw.o | |||
| OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o | |||
| OBJS-$(CONFIG_SWF_DEMUXER) += swf.o | |||
| OBJS-$(CONFIG_SWF_MUXER) += swf.o | |||
| OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o | |||
| OBJS-$(CONFIG_SWF_MUXER) += swfenc.o | |||
| OBJS-$(CONFIG_TG2_MUXER) += movenc.o riff.o isom.o avc.o | |||
| OBJS-$(CONFIG_TGP_MUXER) += movenc.o riff.o isom.o avc.o | |||
| OBJS-$(CONFIG_THP_DEMUXER) += thp.o | |||
| @@ -0,0 +1,99 @@ | |||
| /* | |||
| * Flash Compatible Streaming Format common header. | |||
| * Copyright (c) 2000 Fabrice Bellard. | |||
| * Copyright (c) 2003 Tinic Uro. | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * FFmpeg is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with FFmpeg; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef FFMPEG_SWF_H | |||
| #define FFMPEG_SWF_H | |||
| #include "avformat.h" | |||
| #include "riff.h" /* for CodecTag */ | |||
| /* should have a generic way to indicate probable size */ | |||
| #define DUMMY_FILE_SIZE (100 * 1024 * 1024) | |||
| #define DUMMY_DURATION 600 /* in seconds */ | |||
| #define TAG_END 0 | |||
| #define TAG_SHOWFRAME 1 | |||
| #define TAG_DEFINESHAPE 2 | |||
| #define TAG_FREECHARACTER 3 | |||
| #define TAG_PLACEOBJECT 4 | |||
| #define TAG_REMOVEOBJECT 5 | |||
| #define TAG_STREAMHEAD 18 | |||
| #define TAG_STREAMBLOCK 19 | |||
| #define TAG_JPEG2 21 | |||
| #define TAG_PLACEOBJECT2 26 | |||
| #define TAG_STREAMHEAD2 45 | |||
| #define TAG_VIDEOSTREAM 60 | |||
| #define TAG_VIDEOFRAME 61 | |||
| #define TAG_FILEATTRIBUTES 69 | |||
| #define TAG_LONG 0x100 | |||
| /* flags for shape definition */ | |||
| #define FLAG_MOVETO 0x01 | |||
| #define FLAG_SETFILL0 0x02 | |||
| #define FLAG_SETFILL1 0x04 | |||
| #define AUDIO_FIFO_SIZE 65536 | |||
| /* character id used */ | |||
| #define BITMAP_ID 0 | |||
| #define VIDEO_ID 0 | |||
| #define SHAPE_ID 1 | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| typedef struct { | |||
| int audio_stream_index; | |||
| offset_t duration_pos; | |||
| offset_t tag_pos; | |||
| int samples_per_frame; | |||
| int sound_samples; | |||
| int swf_frame_number; | |||
| int video_frame_number; | |||
| int frame_rate; | |||
| int tag; | |||
| uint8_t audio_fifo[AUDIO_FIFO_SIZE]; | |||
| int audio_in_pos; | |||
| int video_type; | |||
| int audio_type; | |||
| } SWFContext; | |||
| static const AVCodecTag swf_codec_tags[] = { | |||
| {CODEC_ID_FLV1, 0x02}, | |||
| {CODEC_ID_VP6F, 0x04}, | |||
| {0, 0}, | |||
| }; | |||
| static const AVCodecTag swf_audio_codec_tags[] = { | |||
| {CODEC_ID_PCM_S16LE, 0x00}, | |||
| {CODEC_ID_ADPCM_SWF, 0x01}, | |||
| {CODEC_ID_MP3, 0x02}, | |||
| {CODEC_ID_PCM_S16LE, 0x03}, | |||
| //{CODEC_ID_NELLYMOSER, 0x06}, | |||
| {0, 0}, | |||
| }; | |||
| #endif /* FFMPEG_SWF_H */ | |||
| @@ -0,0 +1,206 @@ | |||
| /* | |||
| * Flash Compatible Streaming Format | |||
| * Copyright (c) 2000 Fabrice Bellard. | |||
| * Copyright (c) 2003 Tinic Uro. | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * FFmpeg is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with FFmpeg; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "swf.h" | |||
| /*********************************************/ | |||
| /* Extract FLV encoded frame and MP3 from swf | |||
| Note that the detection of the real frame | |||
| is inaccurate at this point as it can be | |||
| quite tricky to determine, you almost certainly | |||
| will get a bad audio/video sync */ | |||
| static int get_swf_tag(ByteIOContext *pb, int *len_ptr) | |||
| { | |||
| int tag, len; | |||
| if (url_feof(pb)) | |||
| return -1; | |||
| tag = get_le16(pb); | |||
| len = tag & 0x3f; | |||
| tag = tag >> 6; | |||
| if (len == 0x3f) { | |||
| len = get_le32(pb); | |||
| } | |||
| // av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len); | |||
| *len_ptr = len; | |||
| return tag; | |||
| } | |||
| static int swf_probe(AVProbeData *p) | |||
| { | |||
| /* check file header */ | |||
| if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' && | |||
| p->buf[2] == 'S') | |||
| return AVPROBE_SCORE_MAX; | |||
| else | |||
| return 0; | |||
| } | |||
| static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| { | |||
| SWFContext *swf = s->priv_data; | |||
| ByteIOContext *pb = s->pb; | |||
| int nbits, len, tag; | |||
| tag = get_be32(pb) & 0xffffff00; | |||
| if (tag == MKBETAG('C', 'W', 'S', 0)) { | |||
| av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n"); | |||
| return AVERROR(EIO); | |||
| } | |||
| if (tag != MKBETAG('F', 'W', 'S', 0)) | |||
| return AVERROR(EIO); | |||
| get_le32(pb); | |||
| /* skip rectangle size */ | |||
| nbits = get_byte(pb) >> 3; | |||
| len = (4 * nbits - 3 + 7) / 8; | |||
| url_fskip(pb, len); | |||
| swf->frame_rate = get_le16(pb); /* 8.8 fixed */ | |||
| get_le16(pb); /* frame count */ | |||
| swf->samples_per_frame = 0; | |||
| s->ctx_flags |= AVFMTCTX_NOHEADER; | |||
| return 0; | |||
| } | |||
| static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
| { | |||
| SWFContext *swf = s->priv_data; | |||
| ByteIOContext *pb = s->pb; | |||
| AVStream *vst = NULL, *ast = NULL, *st = 0; | |||
| int tag, len, i, frame, v; | |||
| for(;;) { | |||
| tag = get_swf_tag(pb, &len); | |||
| if (tag < 0) | |||
| return AVERROR(EIO); | |||
| if (tag == TAG_VIDEOSTREAM && !vst) { | |||
| int ch_id = get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_byte(pb); | |||
| /* Check for FLV1 */ | |||
| vst = av_new_stream(s, ch_id); | |||
| if (!vst) | |||
| return -1; | |||
| vst->codec->codec_type = CODEC_TYPE_VIDEO; | |||
| vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb)); | |||
| av_set_pts_info(vst, 64, 256, swf->frame_rate); | |||
| vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; | |||
| len -= 10; | |||
| } else if ((tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) && !ast) { | |||
| /* streaming found */ | |||
| int sample_rate_code; | |||
| get_byte(pb); | |||
| v = get_byte(pb); | |||
| swf->samples_per_frame = get_le16(pb); | |||
| ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */ | |||
| if (!ast) | |||
| return -1; | |||
| swf->audio_stream_index = ast->index; | |||
| ast->codec->channels = 1 + (v&1); | |||
| ast->codec->codec_type = CODEC_TYPE_AUDIO; | |||
| ast->codec->codec_id = codec_get_id(swf_audio_codec_tags, (v>>4) & 15); | |||
| ast->need_parsing = AVSTREAM_PARSE_FULL; | |||
| sample_rate_code= (v>>2) & 3; | |||
| if (!sample_rate_code) | |||
| return AVERROR(EIO); | |||
| ast->codec->sample_rate = 11025 << (sample_rate_code-1); | |||
| av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); | |||
| len -= 4; | |||
| } else if (tag == TAG_VIDEOFRAME) { | |||
| int ch_id = get_le16(pb); | |||
| len -= 2; | |||
| for(i=0; i<s->nb_streams; i++) { | |||
| st = s->streams[i]; | |||
| if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) { | |||
| frame = get_le16(pb); | |||
| av_get_packet(pb, pkt, len-2); | |||
| pkt->pts = frame; | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } | |||
| } | |||
| } else if (tag == TAG_STREAMBLOCK) { | |||
| st = s->streams[swf->audio_stream_index]; | |||
| if (st->codec->codec_id == CODEC_ID_MP3) { | |||
| url_fskip(pb, 4); | |||
| av_get_packet(pb, pkt, len-4); | |||
| } else { // ADPCM, PCM | |||
| av_get_packet(pb, pkt, len); | |||
| } | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } else if (tag == TAG_JPEG2) { | |||
| for (i=0; i<s->nb_streams; i++) { | |||
| st = s->streams[i]; | |||
| if (st->id == -2) | |||
| break; | |||
| } | |||
| if (i == s->nb_streams) { | |||
| vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */ | |||
| if (!vst) | |||
| return -1; | |||
| vst->codec->codec_type = CODEC_TYPE_VIDEO; | |||
| vst->codec->codec_id = CODEC_ID_MJPEG; | |||
| av_set_pts_info(vst, 64, 256, swf->frame_rate); | |||
| vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; | |||
| st = vst; | |||
| } | |||
| get_le16(pb); /* BITMAP_ID */ | |||
| av_new_packet(pkt, len-2); | |||
| get_buffer(pb, pkt->data, 4); | |||
| if (AV_RB32(pkt->data) == 0xffd8ffd9 || | |||
| AV_RB32(pkt->data) == 0xffd9ffd8) { | |||
| /* old SWF files containing SOI/EOI as data start */ | |||
| /* files created by swink have reversed tag */ | |||
| pkt->size -= 4; | |||
| get_buffer(pb, pkt->data, pkt->size); | |||
| } else { | |||
| get_buffer(pb, pkt->data + 4, pkt->size - 4); | |||
| } | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } | |||
| url_fskip(pb, len); | |||
| } | |||
| return 0; | |||
| } | |||
| static int swf_read_close(AVFormatContext *s) | |||
| { | |||
| return 0; | |||
| } | |||
| AVInputFormat swf_demuxer = { | |||
| "swf", | |||
| "Flash format", | |||
| sizeof(SWFContext), | |||
| swf_probe, | |||
| swf_read_header, | |||
| swf_read_packet, | |||
| swf_read_close, | |||
| }; | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Flash Compatible Streaming Format | |||
| * Flash Compatible Streaming Format muxer. | |||
| * Copyright (c) 2000 Fabrice Bellard. | |||
| * Copyright (c) 2003 Tinic Uro. | |||
| * | |||
| @@ -22,79 +22,8 @@ | |||
| #include "libavcodec/bitstream.h" | |||
| #include "avformat.h" | |||
| #include "riff.h" /* for CodecTag */ | |||
| /* should have a generic way to indicate probable size */ | |||
| #define DUMMY_FILE_SIZE (100 * 1024 * 1024) | |||
| #define DUMMY_DURATION 600 /* in seconds */ | |||
| #define TAG_END 0 | |||
| #define TAG_SHOWFRAME 1 | |||
| #define TAG_DEFINESHAPE 2 | |||
| #define TAG_FREECHARACTER 3 | |||
| #define TAG_PLACEOBJECT 4 | |||
| #define TAG_REMOVEOBJECT 5 | |||
| #define TAG_STREAMHEAD 18 | |||
| #define TAG_STREAMBLOCK 19 | |||
| #define TAG_JPEG2 21 | |||
| #define TAG_PLACEOBJECT2 26 | |||
| #define TAG_STREAMHEAD2 45 | |||
| #define TAG_VIDEOSTREAM 60 | |||
| #define TAG_VIDEOFRAME 61 | |||
| #define TAG_FILEATTRIBUTES 69 | |||
| #define TAG_LONG 0x100 | |||
| /* flags for shape definition */ | |||
| #define FLAG_MOVETO 0x01 | |||
| #define FLAG_SETFILL0 0x02 | |||
| #define FLAG_SETFILL1 0x04 | |||
| #define AUDIO_FIFO_SIZE 65536 | |||
| /* character id used */ | |||
| #define BITMAP_ID 0 | |||
| #define VIDEO_ID 0 | |||
| #define SHAPE_ID 1 | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| typedef struct { | |||
| int audio_stream_index; | |||
| offset_t duration_pos; | |||
| offset_t tag_pos; | |||
| int samples_per_frame; | |||
| int sound_samples; | |||
| int swf_frame_number; | |||
| int video_frame_number; | |||
| int frame_rate; | |||
| int tag; | |||
| uint8_t audio_fifo[AUDIO_FIFO_SIZE]; | |||
| int audio_in_pos; | |||
| int video_type; | |||
| int audio_type; | |||
| } SWFContext; | |||
| static const AVCodecTag swf_codec_tags[] = { | |||
| {CODEC_ID_FLV1, 0x02}, | |||
| {CODEC_ID_VP6F, 0x04}, | |||
| {0, 0}, | |||
| }; | |||
| static const AVCodecTag swf_audio_codec_tags[] = { | |||
| {CODEC_ID_PCM_S16LE, 0x00}, | |||
| {CODEC_ID_ADPCM_SWF, 0x01}, | |||
| {CODEC_ID_MP3, 0x02}, | |||
| {CODEC_ID_PCM_S16LE, 0x03}, | |||
| //{CODEC_ID_NELLYMOSER, 0x06}, | |||
| {0, 0}, | |||
| }; | |||
| #include "swf.h" | |||
| #ifdef CONFIG_MUXERS | |||
| static void put_swf_tag(AVFormatContext *s, int tag) | |||
| { | |||
| SWFContext *swf = s->priv_data; | |||
| @@ -601,192 +530,7 @@ static int swf_write_trailer(AVFormatContext *s) | |||
| } | |||
| return 0; | |||
| } | |||
| #endif //CONFIG_MUXERS | |||
| /*********************************************/ | |||
| /* Extract FLV encoded frame and MP3 from swf | |||
| Note that the detection of the real frame | |||
| is inaccurate at this point as it can be | |||
| quite tricky to determine, you almost certainly | |||
| will get a bad audio/video sync */ | |||
| static int get_swf_tag(ByteIOContext *pb, int *len_ptr) | |||
| { | |||
| int tag, len; | |||
| if (url_feof(pb)) | |||
| return -1; | |||
| tag = get_le16(pb); | |||
| len = tag & 0x3f; | |||
| tag = tag >> 6; | |||
| if (len == 0x3f) { | |||
| len = get_le32(pb); | |||
| } | |||
| // av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len); | |||
| *len_ptr = len; | |||
| return tag; | |||
| } | |||
| static int swf_probe(AVProbeData *p) | |||
| { | |||
| /* check file header */ | |||
| if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' && | |||
| p->buf[2] == 'S') | |||
| return AVPROBE_SCORE_MAX; | |||
| else | |||
| return 0; | |||
| } | |||
| static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| { | |||
| SWFContext *swf = s->priv_data; | |||
| ByteIOContext *pb = s->pb; | |||
| int nbits, len, tag; | |||
| tag = get_be32(pb) & 0xffffff00; | |||
| if (tag == MKBETAG('C', 'W', 'S', 0)) { | |||
| av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n"); | |||
| return AVERROR(EIO); | |||
| } | |||
| if (tag != MKBETAG('F', 'W', 'S', 0)) | |||
| return AVERROR(EIO); | |||
| get_le32(pb); | |||
| /* skip rectangle size */ | |||
| nbits = get_byte(pb) >> 3; | |||
| len = (4 * nbits - 3 + 7) / 8; | |||
| url_fskip(pb, len); | |||
| swf->frame_rate = get_le16(pb); /* 8.8 fixed */ | |||
| get_le16(pb); /* frame count */ | |||
| swf->samples_per_frame = 0; | |||
| s->ctx_flags |= AVFMTCTX_NOHEADER; | |||
| return 0; | |||
| } | |||
| static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
| { | |||
| SWFContext *swf = s->priv_data; | |||
| ByteIOContext *pb = s->pb; | |||
| AVStream *vst = NULL, *ast = NULL, *st = 0; | |||
| int tag, len, i, frame, v; | |||
| for(;;) { | |||
| tag = get_swf_tag(pb, &len); | |||
| if (tag < 0) | |||
| return AVERROR(EIO); | |||
| if (tag == TAG_VIDEOSTREAM && !vst) { | |||
| int ch_id = get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_le16(pb); | |||
| get_byte(pb); | |||
| /* Check for FLV1 */ | |||
| vst = av_new_stream(s, ch_id); | |||
| if (!vst) | |||
| return -1; | |||
| vst->codec->codec_type = CODEC_TYPE_VIDEO; | |||
| vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb)); | |||
| av_set_pts_info(vst, 64, 256, swf->frame_rate); | |||
| vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; | |||
| len -= 10; | |||
| } else if ((tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) && !ast) { | |||
| /* streaming found */ | |||
| int sample_rate_code; | |||
| get_byte(pb); | |||
| v = get_byte(pb); | |||
| swf->samples_per_frame = get_le16(pb); | |||
| ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */ | |||
| if (!ast) | |||
| return -1; | |||
| swf->audio_stream_index = ast->index; | |||
| ast->codec->channels = 1 + (v&1); | |||
| ast->codec->codec_type = CODEC_TYPE_AUDIO; | |||
| ast->codec->codec_id = codec_get_id(swf_audio_codec_tags, (v>>4) & 15); | |||
| ast->need_parsing = AVSTREAM_PARSE_FULL; | |||
| sample_rate_code= (v>>2) & 3; | |||
| if (!sample_rate_code) | |||
| return AVERROR(EIO); | |||
| ast->codec->sample_rate = 11025 << (sample_rate_code-1); | |||
| av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); | |||
| len -= 4; | |||
| } else if (tag == TAG_VIDEOFRAME) { | |||
| int ch_id = get_le16(pb); | |||
| len -= 2; | |||
| for(i=0; i<s->nb_streams; i++) { | |||
| st = s->streams[i]; | |||
| if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) { | |||
| frame = get_le16(pb); | |||
| av_get_packet(pb, pkt, len-2); | |||
| pkt->pts = frame; | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } | |||
| } | |||
| } else if (tag == TAG_STREAMBLOCK) { | |||
| st = s->streams[swf->audio_stream_index]; | |||
| if (st->codec->codec_id == CODEC_ID_MP3) { | |||
| url_fskip(pb, 4); | |||
| av_get_packet(pb, pkt, len-4); | |||
| } else { // ADPCM, PCM | |||
| av_get_packet(pb, pkt, len); | |||
| } | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } else if (tag == TAG_JPEG2) { | |||
| for (i=0; i<s->nb_streams; i++) { | |||
| st = s->streams[i]; | |||
| if (st->id == -2) | |||
| break; | |||
| } | |||
| if (i == s->nb_streams) { | |||
| vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */ | |||
| if (!vst) | |||
| return -1; | |||
| vst->codec->codec_type = CODEC_TYPE_VIDEO; | |||
| vst->codec->codec_id = CODEC_ID_MJPEG; | |||
| av_set_pts_info(vst, 64, 256, swf->frame_rate); | |||
| vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; | |||
| st = vst; | |||
| } | |||
| get_le16(pb); /* BITMAP_ID */ | |||
| av_new_packet(pkt, len-2); | |||
| get_buffer(pb, pkt->data, 4); | |||
| if (AV_RB32(pkt->data) == 0xffd8ffd9 || | |||
| AV_RB32(pkt->data) == 0xffd9ffd8) { | |||
| /* old SWF files containing SOI/EOI as data start */ | |||
| /* files created by swink have reversed tag */ | |||
| pkt->size -= 4; | |||
| get_buffer(pb, pkt->data, pkt->size); | |||
| } else { | |||
| get_buffer(pb, pkt->data + 4, pkt->size - 4); | |||
| } | |||
| pkt->stream_index = st->index; | |||
| return pkt->size; | |||
| } | |||
| url_fskip(pb, len); | |||
| } | |||
| return 0; | |||
| } | |||
| static int swf_read_close(AVFormatContext *s) | |||
| { | |||
| return 0; | |||
| } | |||
| #ifdef CONFIG_SWF_DEMUXER | |||
| AVInputFormat swf_demuxer = { | |||
| "swf", | |||
| "Flash format", | |||
| sizeof(SWFContext), | |||
| swf_probe, | |||
| swf_read_header, | |||
| swf_read_packet, | |||
| swf_read_close, | |||
| }; | |||
| #endif | |||
| #ifdef CONFIG_SWF_MUXER | |||
| AVOutputFormat swf_muxer = { | |||
| "swf", | |||