Mercurial > libavformat.hg
annotate flvdec.c @ 5255:6a23d76cc72c libavformat
Return special EOF checking for aiff and au demuxers, the check was at
the wrong place, causing an empty packet to be read before EOF was
detected and the eof detection is already now handled by av_get_packet anyway.
author | reimar |
---|---|
date | Fri, 02 Oct 2009 06:42:20 +0000 |
parents | 360f4a07ce5e |
children | 6f5a1064e48a |
rev | line source |
---|---|
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1414
diff
changeset
|
2 * FLV demuxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4125
diff
changeset
|
3 * Copyright (c) 2003 The FFmpeg Project |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
4 * |
2216 | 5 * This demuxer will generate a 1 byte extradata for VP6F content. |
6 * It is composed of: | |
7 * - upper 4bits: difference between encoded width and visible width | |
8 * - lower 4bits: difference between encoded height and visible height | |
9 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1318
diff
changeset
|
10 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1318
diff
changeset
|
11 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1318
diff
changeset
|
12 * FFmpeg is free software; you can redistribute it and/or |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
13 * modify it under the terms of the GNU Lesser General Public |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
14 * 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:
1318
diff
changeset
|
15 * version 2.1 of the License, or (at your option) any later version. |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
16 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1318
diff
changeset
|
17 * FFmpeg is distributed in the hope that it will be useful, |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
20 * Lesser General Public License for more details. |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
21 * |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
22 * 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:
1318
diff
changeset
|
23 * 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
|
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
25 */ |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
26 |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
27 #include "libavutil/avstring.h" |
5066
2bc8a9853970
flvdec: Build a Speex header during FLV demuxing using required and
jbr
parents:
5037
diff
changeset
|
28 #include "libavcodec/bytestream.h" |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
29 #include "libavcodec/mpeg4audio.h" |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
30 #include "avformat.h" |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
31 #include "flv.h" |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
32 |
4034 | 33 typedef struct { |
34 int wrong_dts; ///< wrong dts due to negative cts | |
35 } FLVContext; | |
36 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
37 static int flv_probe(AVProbeData *p) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
38 { |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
39 const uint8_t *d; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
40 |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
41 d = p->buf; |
5193 | 42 if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) { |
1718 | 43 return AVPROBE_SCORE_MAX; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
44 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
45 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
46 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
47 |
1568 | 48 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) { |
49 AVCodecContext *acodec = astream->codec; | |
50 switch(flv_codecid) { | |
51 //no distinction between S16 and S8 PCM codec flags | |
3061
8ae0431d7f43
flv/swf do not have a big endian codec id, they only support
michael
parents:
2848
diff
changeset
|
52 case FLV_CODECID_PCM: |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3799
diff
changeset
|
53 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 : |
5108 | 54 #if HAVE_BIGENDIAN |
3062 | 55 CODEC_ID_PCM_S16BE; |
56 #else | |
57 CODEC_ID_PCM_S16LE; | |
58 #endif | |
59 break; | |
1568 | 60 case FLV_CODECID_PCM_LE: |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3799
diff
changeset
|
61 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16LE; break; |
3364 | 62 case FLV_CODECID_AAC : acodec->codec_id = CODEC_ID_AAC; break; |
1568 | 63 case FLV_CODECID_ADPCM: acodec->codec_id = CODEC_ID_ADPCM_SWF; break; |
4006
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
64 case FLV_CODECID_SPEEX: |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
65 acodec->codec_id = CODEC_ID_SPEEX; |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
66 acodec->sample_rate = 16000; |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
67 break; |
2023 | 68 case FLV_CODECID_MP3 : acodec->codec_id = CODEC_ID_MP3 ; astream->need_parsing = AVSTREAM_PARSE_FULL; break; |
3996
41f9a32e9516
8HZ -> 8KHZ, cosmetics patch by Alexander Wichers development at wichersdot nu
banan
parents:
3908
diff
changeset
|
69 case FLV_CODECID_NELLYMOSER_8KHZ_MONO: |
1568 | 70 acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate |
71 case FLV_CODECID_NELLYMOSER: | |
2604 | 72 acodec->codec_id = CODEC_ID_NELLYMOSER; |
73 break; | |
1568 | 74 default: |
75 av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET); | |
76 acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; | |
77 } | |
78 } | |
79 | |
80 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { | |
81 AVCodecContext *vcodec = vstream->codec; | |
82 switch(flv_codecid) { | |
83 case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; | |
84 case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break; | |
85 case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; | |
2572 | 86 case FLV_CODECID_VP6A : |
87 if(flv_codecid == FLV_CODECID_VP6A) | |
88 vcodec->codec_id = CODEC_ID_VP6A; | |
1568 | 89 if(vcodec->extradata_size != 1) { |
90 vcodec->extradata_size = 1; | |
91 vcodec->extradata = av_malloc(1); | |
92 } | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
93 vcodec->extradata[0] = get_byte(s->pb); |
1568 | 94 return 1; // 1 byte body size adjustment for flv_read_packet() |
3364 | 95 case FLV_CODECID_H264: |
96 vcodec->codec_id = CODEC_ID_H264; | |
97 return 3; // not 4, reading packet type will consume one byte | |
1568 | 98 default: |
99 av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); | |
100 vcodec->codec_tag = flv_codecid; | |
101 } | |
102 | |
103 return 0; | |
104 } | |
105 | |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
106 static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) { |
1561 | 107 int length = get_be16(ioc); |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
108 if(length >= buffsize) { |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
109 url_fskip(ioc, length); |
1561 | 110 return -1; |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
111 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
112 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
113 get_buffer(ioc, buffer, length); |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
114 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
115 buffer[length] = '\0'; |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
116 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
117 return length; |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
118 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
119 |
4005 | 120 static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) { |
1568 | 121 AVCodecContext *acodec, *vcodec; |
122 ByteIOContext *ioc; | |
123 AMFDataType amf_type; | |
124 char str_val[256]; | |
125 double num_val; | |
126 | |
127 num_val = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
128 ioc = s->pb; |
1568 | 129 |
130 amf_type = get_byte(ioc); | |
131 | |
132 switch(amf_type) { | |
133 case AMF_DATA_TYPE_NUMBER: | |
134 num_val = av_int2dbl(get_be64(ioc)); break; | |
135 case AMF_DATA_TYPE_BOOL: | |
136 num_val = get_byte(ioc); break; | |
137 case AMF_DATA_TYPE_STRING: | |
138 if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) | |
139 return -1; | |
140 break; | |
141 case AMF_DATA_TYPE_OBJECT: { | |
142 unsigned int keylen; | |
143 | |
144 while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) { | |
145 url_fskip(ioc, keylen); //skip key string | |
146 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
147 return -1; //if we couldn't skip, bomb out. | |
148 } | |
149 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
150 return -1; | |
151 } | |
152 break; | |
153 case AMF_DATA_TYPE_NULL: | |
154 case AMF_DATA_TYPE_UNDEFINED: | |
155 case AMF_DATA_TYPE_UNSUPPORTED: | |
156 break; //these take up no additional space | |
157 case AMF_DATA_TYPE_MIXEDARRAY: | |
158 url_fskip(ioc, 4); //skip 32-bit max array index | |
159 while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { | |
160 //this is the only case in which we would want a nested parse to not skip over the object | |
161 if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) | |
162 return -1; | |
163 } | |
164 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
165 return -1; | |
166 break; | |
167 case AMF_DATA_TYPE_ARRAY: { | |
168 unsigned int arraylen, i; | |
169 | |
170 arraylen = get_be32(ioc); | |
171 for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) { | |
172 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
173 return -1; //if we couldn't skip, bomb out. | |
174 } | |
175 } | |
176 break; | |
177 case AMF_DATA_TYPE_DATE: | |
178 url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) | |
179 break; | |
180 default: //unsupported type, we couldn't skip | |
181 return -1; | |
182 } | |
183 | |
184 if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL | |
185 acodec = astream ? astream->codec : NULL; | |
186 vcodec = vstream ? vstream->codec : NULL; | |
187 | |
188 if(amf_type == AMF_DATA_TYPE_BOOL) { | |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
189 av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val)); |
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
190 av_metadata_set(&s->metadata, key, str_val); |
1568 | 191 } else if(amf_type == AMF_DATA_TYPE_NUMBER) { |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
192 snprintf(str_val, sizeof(str_val), "%.f", num_val); |
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
193 av_metadata_set(&s->metadata, key, str_val); |
1568 | 194 if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE; |
4347
932720e90fc5
Implement the reading of the video bitrate of flv movies out of the meta data,
benoit
parents:
4271
diff
changeset
|
195 else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0)) |
932720e90fc5
Implement the reading of the video bitrate of flv movies out of the meta data,
benoit
parents:
4271
diff
changeset
|
196 vcodec->bit_rate = num_val * 1024.0; |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
197 } else if (amf_type == AMF_DATA_TYPE_STRING) |
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
198 av_metadata_set(&s->metadata, key, str_val); |
1568 | 199 } |
200 | |
201 return 0; | |
202 } | |
203 | |
4005 | 204 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { |
1568 | 205 AMFDataType type; |
206 AVStream *stream, *astream, *vstream; | |
207 ByteIOContext *ioc; | |
4887
acb51f192e13
Remove unused variable from flv_read_metabody() found by CSA.
michael
parents:
4863
diff
changeset
|
208 int i; |
1568 | 209 char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. |
210 | |
211 astream = NULL; | |
212 vstream = NULL; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
213 ioc = s->pb; |
1568 | 214 |
215 //first object needs to be "onMetaData" string | |
216 type = get_byte(ioc); | |
217 if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) | |
218 return -1; | |
219 | |
220 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. | |
221 for(i = 0; i < s->nb_streams; i++) { | |
222 stream = s->streams[i]; | |
223 if (stream->codec->codec_type == CODEC_TYPE_AUDIO) astream = stream; | |
224 else if(stream->codec->codec_type == CODEC_TYPE_VIDEO) vstream = stream; | |
225 } | |
226 | |
227 //parse the second object (we want a mixed array) | |
228 if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) | |
229 return -1; | |
230 | |
231 return 0; | |
232 } | |
233 | |
2691 | 234 static AVStream *create_stream(AVFormatContext *s, int is_audio){ |
235 AVStream *st = av_new_stream(s, is_audio); | |
236 if (!st) | |
237 return NULL; | |
238 st->codec->codec_type = is_audio ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO; | |
3335 | 239 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ |
2691 | 240 return st; |
241 } | |
242 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
243 static int flv_read_header(AVFormatContext *s, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
244 AVFormatParameters *ap) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
245 { |
1563
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
246 int offset, flags; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
247 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
248 url_fskip(s->pb, 4); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
249 flags = get_byte(s->pb); |
1886 | 250 /* old flvtool cleared this field */ |
251 /* FIXME: better fix needed */ | |
252 if (!flags) { | |
253 flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; | |
254 av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); | |
255 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
256 |
3218 | 257 if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) |
258 != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) | |
259 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
260 | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
261 if(flags & FLV_HEADER_FLAG_HASVIDEO){ |
2691 | 262 if(!create_stream(s, 0)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
263 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
264 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
265 if(flags & FLV_HEADER_FLAG_HASAUDIO){ |
2691 | 266 if(!create_stream(s, 1)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
267 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
268 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
269 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
270 offset = get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
271 url_fseek(s->pb, offset, SEEK_SET); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
272 |
1318 | 273 s->start_time = 0; |
274 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
275 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
276 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
277 |
3364 | 278 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) |
279 { | |
280 av_free(st->codec->extradata); | |
281 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
282 if (!st->codec->extradata) | |
283 return AVERROR(ENOMEM); | |
284 st->codec->extradata_size = size; | |
285 get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); | |
286 return 0; | |
287 } | |
288 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
289 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
290 { |
4034 | 291 FLVContext *flv = s->priv_data; |
4005 | 292 int ret, i, type, size, flags, is_audio; |
293 int64_t next, pos; | |
4034 | 294 int64_t dts, pts = AV_NOPTS_VALUE; |
679 | 295 AVStream *st = NULL; |
885 | 296 |
445 | 297 for(;;){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
298 pos = url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
299 url_fskip(s->pb, 4); /* size of previous packet */ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
300 type = get_byte(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
301 size = get_be24(s->pb); |
3336 | 302 dts = get_be24(s->pb); |
303 dts |= get_byte(s->pb) << 24; | |
304 // av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, dts:%d\n", type, size, dts); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
305 if (url_feof(s->pb)) |
4542
241a66d33f49
FLV demuxer: return AVERROR_EOF upon detection of end of file.
pross
parents:
4509
diff
changeset
|
306 return AVERROR_EOF; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
307 url_fskip(s->pb, 3); /* stream id, always 0 */ |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
308 flags = 0; |
885 | 309 |
445 | 310 if(size == 0) |
311 continue; | |
885 | 312 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
313 next= size + url_ftell(s->pb); |
821 | 314 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
315 if (type == FLV_TAG_TYPE_AUDIO) { |
445 | 316 is_audio=1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
317 flags = get_byte(s->pb); |
3797 | 318 size--; |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
319 } else if (type == FLV_TAG_TYPE_VIDEO) { |
445 | 320 is_audio=0; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
321 flags = get_byte(s->pb); |
3797 | 322 size--; |
3798 | 323 if ((flags & 0xf0) == 0x50) /* video info / command frame */ |
324 goto skip; | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
325 } else { |
5096 | 326 if (type == FLV_TAG_TYPE_META && size > 13+1+4) |
1568 | 327 flv_read_metabody(s, next); |
328 else /* skip packet */ | |
5037
3550a49d6255
Downgrade message log level (from AV_LOG_ERROR to AV_LOG_DEBUG) about
stefano
parents:
4887
diff
changeset
|
329 av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); |
3798 | 330 skip: |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
331 url_fseek(s->pb, next, SEEK_SET); |
4643
d148dbaebaca
Replace two 'return AVERROR(EAGAIN);' by continue. The latter are nicer
michael
parents:
4559
diff
changeset
|
332 continue; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
333 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
334 |
3799 | 335 /* skip empty data packets */ |
336 if (!size) | |
337 continue; | |
338 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
339 /* now find stream */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
340 for(i=0;i<s->nb_streams;i++) { |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
341 st = s->streams[i]; |
445 | 342 if (st->id == is_audio) |
343 break; | |
344 } | |
345 if(i == s->nb_streams){ | |
4509 | 346 av_log(s, AV_LOG_ERROR, "invalid stream\n"); |
2692 | 347 st= create_stream(s, is_audio); |
3215
4efe0debe0cf
Stop find_stream_info() searching for further streams if 2 streams have
michael
parents:
3214
diff
changeset
|
348 s->ctx_flags &= ~AVFMTCTX_NOHEADER; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
349 } |
4509 | 350 // av_log(s, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard); |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
351 if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || is_audio)) |
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
352 ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio)) |
708 | 353 || st->discard >= AVDISCARD_ALL |
354 ){ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
355 url_fseek(s->pb, next, SEEK_SET); |
4643
d148dbaebaca
Replace two 'return AVERROR(EAGAIN);' by continue. The latter are nicer
michael
parents:
4559
diff
changeset
|
356 continue; |
652 | 357 } |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
358 if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) |
3336 | 359 av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); |
445 | 360 break; |
361 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
362 |
1563
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
363 // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
364 if(!url_is_streamed(s->pb) && s->duration==AV_NOPTS_VALUE){ |
1563
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
365 int size; |
4005 | 366 const int64_t pos= url_ftell(s->pb); |
367 const int64_t fsize= url_fsize(s->pb); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
368 url_fseek(s->pb, fsize-4, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
369 size= get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
370 url_fseek(s->pb, fsize-3-size, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
371 if(size == get_be24(s->pb) + 11){ |
5163
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
372 uint32_t ts = get_be24(s->pb); |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
373 ts |= get_byte(s->pb) << 24; |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
374 s->duration = ts * (int64_t)AV_TIME_BASE / 1000; |
1563
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
375 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
376 url_fseek(s->pb, pos, SEEK_SET); |
1563
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
377 } |
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
378 |
445 | 379 if(is_audio){ |
4125
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
380 if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) { |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
381 st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1; |
4009
f492dad79579
simplify sample rate code, flv_set_audio_codec already overrides it for nellymoser 8khz
bcoudurier
parents:
4006
diff
changeset
|
382 st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3); |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3799
diff
changeset
|
383 st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; |
4125
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
384 } |
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
385 if(!st->codec->codec_id){ |
1568 | 386 flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK); |
445 | 387 } |
388 }else{ | |
1568 | 389 size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); |
378 | 390 } |
391 | |
3364 | 392 if (st->codec->codec_id == CODEC_ID_AAC || |
393 st->codec->codec_id == CODEC_ID_H264) { | |
394 int type = get_byte(s->pb); | |
395 size--; | |
396 if (st->codec->codec_id == CODEC_ID_H264) { | |
4034 | 397 int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension |
398 pts = dts + cts; | |
399 if (cts < 0) { // dts are wrong | |
400 flv->wrong_dts = 1; | |
401 av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); | |
402 } | |
403 if (flv->wrong_dts) | |
404 dts = AV_NOPTS_VALUE; | |
3364 | 405 } |
406 if (type == 0) { | |
3797 | 407 if ((ret = flv_get_extradata(s, st, size)) < 0) |
3364 | 408 return ret; |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
409 if (st->codec->codec_id == CODEC_ID_AAC) { |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
410 MPEG4AudioConfig cfg; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
411 ff_mpeg4audio_get_config(&cfg, st->codec->extradata, |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
412 st->codec->extradata_size); |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
413 if (cfg.chan_config > 7) |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
414 return -1; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
415 st->codec->channels = ff_mpeg4audio_channels[cfg.chan_config]; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
416 st->codec->sample_rate = cfg.sample_rate; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
417 dprintf(s, "mp4a config channels %d sample rate %d\n", |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
418 st->codec->channels, st->codec->sample_rate); |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
419 } |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
420 |
4271
f9ec55b30dfa
Use EAGAIN return, primarely intended as example of EAGAIN useage.
michael
parents:
4251
diff
changeset
|
421 return AVERROR(EAGAIN); |
3364 | 422 } |
423 } | |
424 | |
4805 | 425 /* skip empty data packets */ |
426 if (!size) | |
427 return AVERROR(EAGAIN); | |
428 | |
3797 | 429 ret= av_get_packet(s->pb, pkt, size); |
4811 | 430 if (ret < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
431 return AVERROR(EIO); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
432 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
433 /* note: we need to modify the packet size here to handle the last |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
434 packet */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
435 pkt->size = ret; |
3336 | 436 pkt->dts = dts; |
4034 | 437 pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
438 pkt->stream_index = st->index; |
885 | 439 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
440 if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) |
887 | 441 pkt->flags |= PKT_FLAG_KEY; |
885 | 442 |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
443 return ret; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
444 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
445 |
1167 | 446 AVInputFormat flv_demuxer = { |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
447 "flv", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3364
diff
changeset
|
448 NULL_IF_CONFIG_SMALL("FLV format"), |
4034 | 449 sizeof(FLVContext), |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
450 flv_probe, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
451 flv_read_header, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
452 flv_read_packet, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
453 .extensions = "flv", |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
454 .value = CODEC_ID_FLV1, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
455 }; |