Mercurial > libavformat.hg
annotate flvdec.c @ 5565:befe2f0f9a00 libavformat
Use the configure check from r21351 and use it to properly define struct
sockaddr (in case it's not missing) so it always works on the system that
we are defining it for, in a RFC-2553/3493-compliant way (i.e. containing
a ss_family field). which is used in udp.c. Patch by Martin Storsj
<$firstname $firstname st>.
author | rbultje |
---|---|
date | Wed, 20 Jan 2010 17:26:14 +0000 |
parents | 2db4e4b04157 |
children | 536e5527c1e0 |
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: |
5461 | 53 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : |
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: |
5461 | 61 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : 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; | |
5372
58056ca84fb1
Add codec id for Flash screen codec v2 and hook it up in FLV demuxer
daniel
parents:
5362
diff
changeset
|
85 case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break; |
1568 | 86 case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; |
2572 | 87 case FLV_CODECID_VP6A : |
88 if(flv_codecid == FLV_CODECID_VP6A) | |
89 vcodec->codec_id = CODEC_ID_VP6A; | |
1568 | 90 if(vcodec->extradata_size != 1) { |
91 vcodec->extradata_size = 1; | |
92 vcodec->extradata = av_malloc(1); | |
93 } | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
94 vcodec->extradata[0] = get_byte(s->pb); |
1568 | 95 return 1; // 1 byte body size adjustment for flv_read_packet() |
3364 | 96 case FLV_CODECID_H264: |
97 vcodec->codec_id = CODEC_ID_H264; | |
98 return 3; // not 4, reading packet type will consume one byte | |
1568 | 99 default: |
100 av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); | |
101 vcodec->codec_tag = flv_codecid; | |
102 } | |
103 | |
104 return 0; | |
105 } | |
106 | |
5462 | 107 static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) { |
108 int length = get_be16(ioc); | |
109 if(length >= buffsize) { | |
110 url_fskip(ioc, length); | |
111 return -1; | |
112 } | |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
113 |
5462 | 114 get_buffer(ioc, buffer, length); |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
115 |
5462 | 116 buffer[length] = '\0'; |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
117 |
5462 | 118 return length; |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
119 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
120 |
4005 | 121 static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) { |
1568 | 122 AVCodecContext *acodec, *vcodec; |
123 ByteIOContext *ioc; | |
124 AMFDataType amf_type; | |
5462 | 125 char str_val[256]; |
1568 | 126 double num_val; |
127 | |
128 num_val = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
129 ioc = s->pb; |
1568 | 130 |
131 amf_type = get_byte(ioc); | |
132 | |
133 switch(amf_type) { | |
134 case AMF_DATA_TYPE_NUMBER: | |
135 num_val = av_int2dbl(get_be64(ioc)); break; | |
136 case AMF_DATA_TYPE_BOOL: | |
137 num_val = get_byte(ioc); break; | |
138 case AMF_DATA_TYPE_STRING: | |
5462 | 139 if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) |
1568 | 140 return -1; |
141 break; | |
142 case AMF_DATA_TYPE_OBJECT: { | |
143 unsigned int keylen; | |
144 | |
145 while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) { | |
146 url_fskip(ioc, keylen); //skip key string | |
147 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
148 return -1; //if we couldn't skip, bomb out. | |
149 } | |
150 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
151 return -1; | |
152 } | |
153 break; | |
154 case AMF_DATA_TYPE_NULL: | |
155 case AMF_DATA_TYPE_UNDEFINED: | |
156 case AMF_DATA_TYPE_UNSUPPORTED: | |
157 break; //these take up no additional space | |
158 case AMF_DATA_TYPE_MIXEDARRAY: | |
159 url_fskip(ioc, 4); //skip 32-bit max array index | |
5462 | 160 while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { |
1568 | 161 //this is the only case in which we would want a nested parse to not skip over the object |
5462 | 162 if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) |
1568 | 163 return -1; |
164 } | |
165 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
166 return -1; | |
167 break; | |
168 case AMF_DATA_TYPE_ARRAY: { | |
169 unsigned int arraylen, i; | |
170 | |
171 arraylen = get_be32(ioc); | |
172 for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) { | |
173 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
174 return -1; //if we couldn't skip, bomb out. | |
175 } | |
176 } | |
177 break; | |
178 case AMF_DATA_TYPE_DATE: | |
179 url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) | |
180 break; | |
181 default: //unsupported type, we couldn't skip | |
182 return -1; | |
183 } | |
184 | |
185 if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL | |
186 acodec = astream ? astream->codec : NULL; | |
187 vcodec = vstream ? vstream->codec : NULL; | |
188 | |
189 if(amf_type == AMF_DATA_TYPE_BOOL) { | |
5462 | 190 av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val)); |
191 av_metadata_set(&s->metadata, key, str_val); | |
1568 | 192 } else if(amf_type == AMF_DATA_TYPE_NUMBER) { |
5462 | 193 snprintf(str_val, sizeof(str_val), "%.f", num_val); |
194 av_metadata_set(&s->metadata, key, str_val); | |
1568 | 195 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
|
196 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
|
197 vcodec->bit_rate = num_val * 1024.0; |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
198 } else if (amf_type == AMF_DATA_TYPE_STRING) |
5462 | 199 av_metadata_set(&s->metadata, key, str_val); |
1568 | 200 } |
201 | |
202 return 0; | |
203 } | |
204 | |
4005 | 205 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { |
1568 | 206 AMFDataType type; |
207 AVStream *stream, *astream, *vstream; | |
208 ByteIOContext *ioc; | |
4887
acb51f192e13
Remove unused variable from flv_read_metabody() found by CSA.
michael
parents:
4863
diff
changeset
|
209 int i; |
5462 | 210 char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. |
1568 | 211 |
212 astream = NULL; | |
213 vstream = NULL; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
214 ioc = s->pb; |
1568 | 215 |
216 //first object needs to be "onMetaData" string | |
217 type = get_byte(ioc); | |
5462 | 218 if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) |
1568 | 219 return -1; |
220 | |
221 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. | |
222 for(i = 0; i < s->nb_streams; i++) { | |
223 stream = s->streams[i]; | |
224 if (stream->codec->codec_type == CODEC_TYPE_AUDIO) astream = stream; | |
225 else if(stream->codec->codec_type == CODEC_TYPE_VIDEO) vstream = stream; | |
226 } | |
227 | |
228 //parse the second object (we want a mixed array) | |
5462 | 229 if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) |
1568 | 230 return -1; |
231 | |
232 return 0; | |
233 } | |
234 | |
2691 | 235 static AVStream *create_stream(AVFormatContext *s, int is_audio){ |
236 AVStream *st = av_new_stream(s, is_audio); | |
237 if (!st) | |
238 return NULL; | |
239 st->codec->codec_type = is_audio ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO; | |
3335 | 240 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ |
2691 | 241 return st; |
242 } | |
243 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
244 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
|
245 AVFormatParameters *ap) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
246 { |
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
|
247 int offset, flags; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
248 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
249 url_fskip(s->pb, 4); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
250 flags = get_byte(s->pb); |
1886 | 251 /* old flvtool cleared this field */ |
252 /* FIXME: better fix needed */ | |
253 if (!flags) { | |
254 flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; | |
255 av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); | |
256 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
257 |
3218 | 258 if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) |
259 != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) | |
260 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
261 | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
262 if(flags & FLV_HEADER_FLAG_HASVIDEO){ |
2691 | 263 if(!create_stream(s, 0)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
264 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
265 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
266 if(flags & FLV_HEADER_FLAG_HASAUDIO){ |
2691 | 267 if(!create_stream(s, 1)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
268 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
269 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
270 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
271 offset = get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
272 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
|
273 |
1318 | 274 s->start_time = 0; |
275 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
276 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
277 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
278 |
3364 | 279 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) |
280 { | |
281 av_free(st->codec->extradata); | |
282 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
283 if (!st->codec->extradata) | |
284 return AVERROR(ENOMEM); | |
285 st->codec->extradata_size = size; | |
286 get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); | |
287 return 0; | |
288 } | |
289 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
290 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
|
291 { |
4034 | 292 FLVContext *flv = s->priv_data; |
4005 | 293 int ret, i, type, size, flags, is_audio; |
294 int64_t next, pos; | |
4034 | 295 int64_t dts, pts = AV_NOPTS_VALUE; |
679 | 296 AVStream *st = NULL; |
885 | 297 |
445 | 298 for(;;){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
299 pos = url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
300 url_fskip(s->pb, 4); /* size of previous packet */ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
301 type = get_byte(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
302 size = get_be24(s->pb); |
3336 | 303 dts = get_be24(s->pb); |
304 dts |= get_byte(s->pb) << 24; | |
305 // 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
|
306 if (url_feof(s->pb)) |
4542
241a66d33f49
FLV demuxer: return AVERROR_EOF upon detection of end of file.
pross
parents:
4509
diff
changeset
|
307 return AVERROR_EOF; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
308 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
|
309 flags = 0; |
885 | 310 |
445 | 311 if(size == 0) |
312 continue; | |
885 | 313 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
314 next= size + url_ftell(s->pb); |
821 | 315 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
316 if (type == FLV_TAG_TYPE_AUDIO) { |
445 | 317 is_audio=1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
318 flags = get_byte(s->pb); |
3797 | 319 size--; |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
320 } else if (type == FLV_TAG_TYPE_VIDEO) { |
445 | 321 is_audio=0; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
322 flags = get_byte(s->pb); |
3797 | 323 size--; |
3798 | 324 if ((flags & 0xf0) == 0x50) /* video info / command frame */ |
325 goto skip; | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
326 } else { |
5096 | 327 if (type == FLV_TAG_TYPE_META && size > 13+1+4) |
1568 | 328 flv_read_metabody(s, next); |
329 else /* skip packet */ | |
5037
3550a49d6255
Downgrade message log level (from AV_LOG_ERROR to AV_LOG_DEBUG) about
stefano
parents:
4887
diff
changeset
|
330 av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); |
3798 | 331 skip: |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
332 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
|
333 continue; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
334 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
335 |
3799 | 336 /* skip empty data packets */ |
337 if (!size) | |
338 continue; | |
339 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
340 /* now find stream */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
341 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
|
342 st = s->streams[i]; |
445 | 343 if (st->id == is_audio) |
344 break; | |
345 } | |
346 if(i == s->nb_streams){ | |
4509 | 347 av_log(s, AV_LOG_ERROR, "invalid stream\n"); |
2692 | 348 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
|
349 s->ctx_flags &= ~AVFMTCTX_NOHEADER; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
350 } |
4509 | 351 // 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
|
352 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
|
353 ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio)) |
708 | 354 || st->discard >= AVDISCARD_ALL |
355 ){ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
356 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
|
357 continue; |
652 | 358 } |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
359 if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) |
3336 | 360 av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); |
445 | 361 break; |
362 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
363 |
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
|
364 // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps |
5564
2db4e4b04157
fetch flv duration from file if it is set to 0 in metadata
bcoudurier
parents:
5462
diff
changeset
|
365 if(!url_is_streamed(s->pb) && (!s->duration || 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
|
366 int size; |
4005 | 367 const int64_t pos= url_ftell(s->pb); |
368 const int64_t fsize= url_fsize(s->pb); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
369 url_fseek(s->pb, fsize-4, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
370 size= get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
371 url_fseek(s->pb, fsize-3-size, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
372 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
|
373 uint32_t ts = get_be24(s->pb); |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
374 ts |= get_byte(s->pb) << 24; |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
375 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
|
376 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
377 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
|
378 } |
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
379 |
445 | 380 if(is_audio){ |
4125
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
381 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
|
382 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
|
383 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
|
384 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
|
385 } |
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
386 if(!st->codec->codec_id){ |
1568 | 387 flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK); |
445 | 388 } |
389 }else{ | |
1568 | 390 size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); |
378 | 391 } |
392 | |
3364 | 393 if (st->codec->codec_id == CODEC_ID_AAC || |
394 st->codec->codec_id == CODEC_ID_H264) { | |
395 int type = get_byte(s->pb); | |
396 size--; | |
397 if (st->codec->codec_id == CODEC_ID_H264) { | |
4034 | 398 int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension |
399 pts = dts + cts; | |
400 if (cts < 0) { // dts are wrong | |
401 flv->wrong_dts = 1; | |
402 av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); | |
403 } | |
404 if (flv->wrong_dts) | |
405 dts = AV_NOPTS_VALUE; | |
3364 | 406 } |
407 if (type == 0) { | |
3797 | 408 if ((ret = flv_get_extradata(s, st, size)) < 0) |
3364 | 409 return ret; |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
410 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
|
411 MPEG4AudioConfig cfg; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
412 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
|
413 st->codec->extradata_size); |
5362 | 414 st->codec->channels = cfg.channels; |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
415 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
|
416 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
|
417 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
|
418 } |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
419 |
4271
f9ec55b30dfa
Use EAGAIN return, primarely intended as example of EAGAIN useage.
michael
parents:
4251
diff
changeset
|
420 return AVERROR(EAGAIN); |
3364 | 421 } |
422 } | |
423 | |
4805 | 424 /* skip empty data packets */ |
425 if (!size) | |
426 return AVERROR(EAGAIN); | |
427 | |
3797 | 428 ret= av_get_packet(s->pb, pkt, size); |
4811 | 429 if (ret < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
430 return AVERROR(EIO); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
431 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
432 /* 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
|
433 packet */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
434 pkt->size = ret; |
3336 | 435 pkt->dts = dts; |
4034 | 436 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
|
437 pkt->stream_index = st->index; |
885 | 438 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
439 if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) |
887 | 440 pkt->flags |= PKT_FLAG_KEY; |
885 | 441 |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
442 return ret; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
443 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
444 |
1167 | 445 AVInputFormat flv_demuxer = { |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
446 "flv", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3364
diff
changeset
|
447 NULL_IF_CONFIG_SMALL("FLV format"), |
4034 | 448 sizeof(FLVContext), |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
449 flv_probe, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
450 flv_read_header, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
451 flv_read_packet, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
452 .extensions = "flv", |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
453 .value = CODEC_ID_FLV1, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
454 }; |