Mercurial > libavformat.hg
annotate swfdec.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | 7a0230981402 |
children | 7d2f3f1b68d8 |
rev | line source |
---|---|
0 | 1 /* |
3357 | 2 * Flash Compatible Streaming Format demuxer |
0 | 3 * Copyright (c) 2000 Fabrice Bellard. |
359 | 4 * Copyright (c) 2003 Tinic Uro. |
0 | 5 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
6 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
7 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
0 | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
0 | 12 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1305
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 21 */ |
3286 | 22 |
3302 | 23 #include "swf.h" |
0 | 24 |
25 static int get_swf_tag(ByteIOContext *pb, int *len_ptr) | |
26 { | |
27 int tag, len; | |
885 | 28 |
0 | 29 if (url_feof(pb)) |
30 return -1; | |
31 | |
32 tag = get_le16(pb); | |
33 len = tag & 0x3f; | |
34 tag = tag >> 6; | |
35 if (len == 0x3f) { | |
36 len = get_le32(pb); | |
37 } | |
806 | 38 // av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len); |
0 | 39 *len_ptr = len; |
40 return tag; | |
41 } | |
42 | |
43 | |
44 static int swf_probe(AVProbeData *p) | |
45 { | |
46 /* check file header */ | |
806 | 47 if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' && |
0 | 48 p->buf[2] == 'S') |
49 return AVPROBE_SCORE_MAX; | |
50 else | |
51 return 0; | |
52 } | |
53 | |
54 static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
55 { | |
1641 | 56 SWFContext *swf = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2402
diff
changeset
|
57 ByteIOContext *pb = s->pb; |
2310 | 58 int nbits, len, tag; |
359 | 59 |
806 | 60 tag = get_be32(pb) & 0xffffff00; |
61 | |
2309 | 62 if (tag == MKBETAG('C', 'W', 'S', 0)) { |
887 | 63 av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n"); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2164
diff
changeset
|
64 return AVERROR(EIO); |
806 | 65 } |
66 if (tag != MKBETAG('F', 'W', 'S', 0)) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2164
diff
changeset
|
67 return AVERROR(EIO); |
0 | 68 get_le32(pb); |
69 /* skip rectangle size */ | |
70 nbits = get_byte(pb) >> 3; | |
71 len = (4 * nbits - 3 + 7) / 8; | |
72 url_fskip(pb, len); | |
1889 | 73 swf->frame_rate = get_le16(pb); /* 8.8 fixed */ |
0 | 74 get_le16(pb); /* frame count */ |
885 | 75 |
359 | 76 swf->samples_per_frame = 0; |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
77 s->ctx_flags |= AVFMTCTX_NOHEADER; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
78 return 0; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
79 } |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
80 |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
81 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
82 { |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
83 SWFContext *swf = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2402
diff
changeset
|
84 ByteIOContext *pb = s->pb; |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
85 AVStream *vst = NULL, *ast = NULL, *st = 0; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
86 int tag, len, i, frame, v; |
0 | 87 |
88 for(;;) { | |
89 tag = get_swf_tag(pb, &len); | |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
90 if (tag < 0) |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
91 return AVERROR(EIO); |
2309 | 92 if (tag == TAG_VIDEOSTREAM && !vst) { |
1637 | 93 int ch_id = get_le16(pb); |
359 | 94 get_le16(pb); |
95 get_le16(pb); | |
96 get_le16(pb); | |
97 get_byte(pb); | |
98 /* Check for FLV1 */ | |
1637 | 99 vst = av_new_stream(s, ch_id); |
2913 | 100 if (!vst) |
101 return -1; | |
1635 | 102 vst->codec->codec_type = CODEC_TYPE_VIDEO; |
103 vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb)); | |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
104 av_set_pts_info(vst, 64, 256, swf->frame_rate); |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
105 vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
106 len -= 10; |
2309 | 107 } else if ((tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) && !ast) { |
0 | 108 /* streaming found */ |
1642 | 109 int sample_rate_code; |
0 | 110 get_byte(pb); |
111 v = get_byte(pb); | |
359 | 112 swf->samples_per_frame = get_le16(pb); |
1638 | 113 ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */ |
2913 | 114 if (!ast) |
115 return -1; | |
1638 | 116 swf->audio_stream_index = ast->index; |
1636 | 117 ast->codec->channels = 1 + (v&1); |
118 ast->codec->codec_type = CODEC_TYPE_AUDIO; | |
1833 | 119 ast->codec->codec_id = codec_get_id(swf_audio_codec_tags, (v>>4) & 15); |
2023 | 120 ast->need_parsing = AVSTREAM_PARSE_FULL; |
1642 | 121 sample_rate_code= (v>>2) & 3; |
122 if (!sample_rate_code) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2164
diff
changeset
|
123 return AVERROR(EIO); |
1642 | 124 ast->codec->sample_rate = 11025 << (sample_rate_code-1); |
1890
04f9a3ae30af
seems safer to set pts timebase to sample rate, fix some mp3
bcoudurier
parents:
1889
diff
changeset
|
125 av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
126 len -= 4; |
2308 | 127 } else if (tag == TAG_VIDEOFRAME) { |
1637 | 128 int ch_id = get_le16(pb); |
1639 | 129 len -= 2; |
2309 | 130 for(i=0; i<s->nb_streams; i++) { |
887 | 131 st = s->streams[i]; |
1637 | 132 if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) { |
133 frame = get_le16(pb); | |
1639 | 134 av_get_packet(pb, pkt, len-2); |
1889 | 135 pkt->pts = frame; |
1637 | 136 pkt->stream_index = st->index; |
137 return pkt->size; | |
359 | 138 } |
885 | 139 } |
359 | 140 } else if (tag == TAG_STREAMBLOCK) { |
1638 | 141 st = s->streams[swf->audio_stream_index]; |
142 if (st->codec->codec_id == CODEC_ID_MP3) { | |
143 url_fskip(pb, 4); | |
144 av_get_packet(pb, pkt, len-4); | |
1833 | 145 } else { // ADPCM, PCM |
146 av_get_packet(pb, pkt, len); | |
359 | 147 } |
1833 | 148 pkt->stream_index = st->index; |
149 return pkt->size; | |
1640 | 150 } else if (tag == TAG_JPEG2) { |
151 for (i=0; i<s->nb_streams; i++) { | |
152 st = s->streams[i]; | |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
153 if (st->id == -2) |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
154 break; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
155 } |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
156 if (i == s->nb_streams) { |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
157 vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */ |
2913 | 158 if (!vst) |
159 return -1; | |
2307
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
160 vst->codec->codec_type = CODEC_TYPE_VIDEO; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
161 vst->codec->codec_id = CODEC_ID_MJPEG; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
162 av_set_pts_info(vst, 64, 256, swf->frame_rate); |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
163 vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
164 st = vst; |
d5508f387614
add streams on the fly, swf is a streaming format and has no real header, correctly detect audio in RamboMJPEGAVP6_112K.swf now
bcoudurier
parents:
2289
diff
changeset
|
165 } |
2308 | 166 get_le16(pb); /* BITMAP_ID */ |
167 av_new_packet(pkt, len-2); | |
168 get_buffer(pb, pkt->data, 4); | |
2402
8decf7585a94
support swink created files which have soi/eoi broken tags reversed
bcoudurier
parents:
2310
diff
changeset
|
169 if (AV_RB32(pkt->data) == 0xffd8ffd9 || |
8decf7585a94
support swink created files which have soi/eoi broken tags reversed
bcoudurier
parents:
2310
diff
changeset
|
170 AV_RB32(pkt->data) == 0xffd9ffd8) { |
2308 | 171 /* old SWF files containing SOI/EOI as data start */ |
2402
8decf7585a94
support swink created files which have soi/eoi broken tags reversed
bcoudurier
parents:
2310
diff
changeset
|
172 /* files created by swink have reversed tag */ |
2308 | 173 pkt->size -= 4; |
174 get_buffer(pb, pkt->data, pkt->size); | |
175 } else { | |
176 get_buffer(pb, pkt->data + 4, pkt->size - 4); | |
177 } | |
178 pkt->stream_index = st->index; | |
179 return pkt->size; | |
0 | 180 } |
1639 | 181 url_fskip(pb, len); |
0 | 182 } |
183 return 0; | |
184 } | |
185 | |
1169 | 186 AVInputFormat swf_demuxer = { |
0 | 187 "swf", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3357
diff
changeset
|
188 NULL_IF_CONFIG_SMALL("Flash format"), |
359 | 189 sizeof(SWFContext), |
0 | 190 swf_probe, |
191 swf_read_header, | |
192 swf_read_packet, | |
193 }; |