Mercurial > libavformat.hg
annotate flvdec.c @ 4387:5c42816e12c6 libavformat
Add "AVFormatContext *ctx" (that being the RTSP demuxer's) as first argument
to the parse_packet() function pointer in RTPDynamicProtocolHandlers. This
allows these functions to peek back and retrieve values from the demuxer's
context (or RTSPState). The ASF/RTP payload parser will use this to be able
to parse SDP values (which occur even before the payload ID is given), store
them in the RTSPState and then retrieve them while parsing payload data. See
"[PATCH] RTSP-MS 13/15: add RTSP demuxer AVFormatContext to parse_packet()
function pointer (was: transport context)" mailinglist thread.
author | rbultje |
---|---|
date | Fri, 06 Feb 2009 01:37:19 +0000 |
parents | 932720e90fc5 |
children | 8ec95cf6deb9 |
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 */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
26 #include "avformat.h" |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
27 #include "flv.h" |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
28 |
4034 | 29 typedef struct { |
30 int wrong_dts; ///< wrong dts due to negative cts | |
31 } FLVContext; | |
32 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
33 static int flv_probe(AVProbeData *p) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
34 { |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
35 const uint8_t *d; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
36 |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
37 d = p->buf; |
1718 | 38 if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0) { |
39 return AVPROBE_SCORE_MAX; | |
164
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 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
42 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
43 |
1568 | 44 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) { |
45 AVCodecContext *acodec = astream->codec; | |
46 switch(flv_codecid) { | |
47 //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
|
48 case FLV_CODECID_PCM: |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3799
diff
changeset
|
49 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 : |
3062 | 50 #ifdef WORDS_BIGENDIAN |
51 CODEC_ID_PCM_S16BE; | |
52 #else | |
53 CODEC_ID_PCM_S16LE; | |
54 #endif | |
55 break; | |
1568 | 56 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
|
57 acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16LE; break; |
3364 | 58 case FLV_CODECID_AAC : acodec->codec_id = CODEC_ID_AAC; break; |
1568 | 59 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
|
60 case FLV_CODECID_SPEEX: |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
61 acodec->codec_id = CODEC_ID_SPEEX; |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
62 acodec->sample_rate = 16000; |
cf359952a1fc
force sample rate to 16khz for speex in flv, fix speexaudio.flv
bcoudurier
parents:
4005
diff
changeset
|
63 break; |
2023 | 64 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
|
65 case FLV_CODECID_NELLYMOSER_8KHZ_MONO: |
1568 | 66 acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate |
67 case FLV_CODECID_NELLYMOSER: | |
2604 | 68 acodec->codec_id = CODEC_ID_NELLYMOSER; |
69 break; | |
1568 | 70 default: |
71 av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET); | |
72 acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; | |
73 } | |
74 } | |
75 | |
76 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { | |
77 AVCodecContext *vcodec = vstream->codec; | |
78 switch(flv_codecid) { | |
79 case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; | |
80 case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break; | |
81 case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; | |
2572 | 82 case FLV_CODECID_VP6A : |
83 if(flv_codecid == FLV_CODECID_VP6A) | |
84 vcodec->codec_id = CODEC_ID_VP6A; | |
1568 | 85 if(vcodec->extradata_size != 1) { |
86 vcodec->extradata_size = 1; | |
87 vcodec->extradata = av_malloc(1); | |
88 } | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
89 vcodec->extradata[0] = get_byte(s->pb); |
1568 | 90 return 1; // 1 byte body size adjustment for flv_read_packet() |
3364 | 91 case FLV_CODECID_H264: |
92 vcodec->codec_id = CODEC_ID_H264; | |
93 return 3; // not 4, reading packet type will consume one byte | |
1568 | 94 default: |
95 av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); | |
96 vcodec->codec_tag = flv_codecid; | |
97 } | |
98 | |
99 return 0; | |
100 } | |
101 | |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
102 static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) { |
1561 | 103 int length = get_be16(ioc); |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
104 if(length >= buffsize) { |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
105 url_fskip(ioc, length); |
1561 | 106 return -1; |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
107 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
108 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
109 get_buffer(ioc, buffer, length); |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
110 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
111 buffer[length] = '\0'; |
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 return 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 |
4005 | 116 static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) { |
1568 | 117 AVCodecContext *acodec, *vcodec; |
118 ByteIOContext *ioc; | |
119 AMFDataType amf_type; | |
120 char str_val[256]; | |
121 double num_val; | |
122 | |
123 num_val = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
124 ioc = s->pb; |
1568 | 125 |
126 amf_type = get_byte(ioc); | |
127 | |
128 switch(amf_type) { | |
129 case AMF_DATA_TYPE_NUMBER: | |
130 num_val = av_int2dbl(get_be64(ioc)); break; | |
131 case AMF_DATA_TYPE_BOOL: | |
132 num_val = get_byte(ioc); break; | |
133 case AMF_DATA_TYPE_STRING: | |
134 if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) | |
135 return -1; | |
136 break; | |
137 case AMF_DATA_TYPE_OBJECT: { | |
138 unsigned int keylen; | |
139 | |
140 while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) { | |
141 url_fskip(ioc, keylen); //skip key string | |
142 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
143 return -1; //if we couldn't skip, bomb out. | |
144 } | |
145 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
146 return -1; | |
147 } | |
148 break; | |
149 case AMF_DATA_TYPE_NULL: | |
150 case AMF_DATA_TYPE_UNDEFINED: | |
151 case AMF_DATA_TYPE_UNSUPPORTED: | |
152 break; //these take up no additional space | |
153 case AMF_DATA_TYPE_MIXEDARRAY: | |
154 url_fskip(ioc, 4); //skip 32-bit max array index | |
155 while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { | |
156 //this is the only case in which we would want a nested parse to not skip over the object | |
157 if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) | |
158 return -1; | |
159 } | |
160 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
161 return -1; | |
162 break; | |
163 case AMF_DATA_TYPE_ARRAY: { | |
164 unsigned int arraylen, i; | |
165 | |
166 arraylen = get_be32(ioc); | |
167 for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) { | |
168 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
169 return -1; //if we couldn't skip, bomb out. | |
170 } | |
171 } | |
172 break; | |
173 case AMF_DATA_TYPE_DATE: | |
174 url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) | |
175 break; | |
176 default: //unsupported type, we couldn't skip | |
177 return -1; | |
178 } | |
179 | |
180 if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL | |
181 acodec = astream ? astream->codec : NULL; | |
182 vcodec = vstream ? vstream->codec : NULL; | |
183 | |
184 if(amf_type == AMF_DATA_TYPE_BOOL) { | |
185 if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1; | |
186 } else if(amf_type == AMF_DATA_TYPE_NUMBER) { | |
187 if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE; | |
1719
f813f8755dd1
flv follows in movs footsteps and has random trash in the width/height fields
michael
parents:
1718
diff
changeset
|
188 // else if(!strcmp(key, "width") && vcodec && num_val > 0) vcodec->width = num_val; |
f813f8755dd1
flv follows in movs footsteps and has random trash in the width/height fields
michael
parents:
1718
diff
changeset
|
189 // else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val; |
4347
932720e90fc5
Implement the reading of the video bitrate of flv movies out of the meta data,
benoit
parents:
4271
diff
changeset
|
190 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
|
191 vcodec->bit_rate = num_val * 1024.0; |
3152
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
192 else if(!strcmp(key, "audiocodecid") && acodec && 0 <= (int)num_val) |
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
193 flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET); |
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
194 else if(!strcmp(key, "videocodecid") && vcodec && 0 <= (int)num_val) |
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
195 flv_set_video_codec(s, vstream, (int)num_val); |
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
196 else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) { |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3799
diff
changeset
|
197 acodec->bits_per_coded_sample = num_val; |
1568 | 198 //we may have to rewrite a previously read codecid because FLV only marks PCM endianness. |
199 if(num_val == 8 && (acodec->codec_id == CODEC_ID_PCM_S16BE || acodec->codec_id == CODEC_ID_PCM_S16LE)) | |
200 acodec->codec_id = CODEC_ID_PCM_S8; | |
201 } | |
202 else if(!strcmp(key, "audiosamplerate") && acodec && num_val >= 0) { | |
203 //some tools, like FLVTool2, write consistently approximate metadata sample rates | |
2847
f2a69a8c657d
Correctly handle FLV_CODECID_NELLYMOSER_8HZ_MONO files
banan
parents:
2771
diff
changeset
|
204 if (!acodec->sample_rate) { |
2848 | 205 switch((int)num_val) { |
206 case 44000: acodec->sample_rate = 44100 ; break; | |
207 case 22000: acodec->sample_rate = 22050 ; break; | |
208 case 11000: acodec->sample_rate = 11025 ; break; | |
209 case 5000 : acodec->sample_rate = 5512 ; break; | |
210 default : acodec->sample_rate = num_val; | |
211 } | |
2847
f2a69a8c657d
Correctly handle FLV_CODECID_NELLYMOSER_8HZ_MONO files
banan
parents:
2771
diff
changeset
|
212 } |
1568 | 213 } |
214 } | |
215 } | |
216 | |
217 return 0; | |
218 } | |
219 | |
4005 | 220 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { |
1568 | 221 AMFDataType type; |
222 AVStream *stream, *astream, *vstream; | |
223 ByteIOContext *ioc; | |
224 int i, keylen; | |
225 char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. | |
226 | |
227 astream = NULL; | |
228 vstream = NULL; | |
229 keylen = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
230 ioc = s->pb; |
1568 | 231 |
232 //first object needs to be "onMetaData" string | |
233 type = get_byte(ioc); | |
234 if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) | |
235 return -1; | |
236 | |
237 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. | |
238 for(i = 0; i < s->nb_streams; i++) { | |
239 stream = s->streams[i]; | |
240 if (stream->codec->codec_type == CODEC_TYPE_AUDIO) astream = stream; | |
241 else if(stream->codec->codec_type == CODEC_TYPE_VIDEO) vstream = stream; | |
242 } | |
243 | |
244 //parse the second object (we want a mixed array) | |
245 if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) | |
246 return -1; | |
247 | |
248 return 0; | |
249 } | |
250 | |
2691 | 251 static AVStream *create_stream(AVFormatContext *s, int is_audio){ |
252 AVStream *st = av_new_stream(s, is_audio); | |
253 if (!st) | |
254 return NULL; | |
255 st->codec->codec_type = is_audio ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO; | |
3335 | 256 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ |
2691 | 257 return st; |
258 } | |
259 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
260 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
|
261 AVFormatParameters *ap) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
262 { |
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
|
263 int offset, flags; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
264 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
265 url_fskip(s->pb, 4); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
266 flags = get_byte(s->pb); |
1886 | 267 /* old flvtool cleared this field */ |
268 /* FIXME: better fix needed */ | |
269 if (!flags) { | |
270 flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; | |
271 av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); | |
272 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
273 |
3218 | 274 if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) |
275 != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) | |
276 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
277 | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
278 if(flags & FLV_HEADER_FLAG_HASVIDEO){ |
2691 | 279 if(!create_stream(s, 0)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
280 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
281 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
282 if(flags & FLV_HEADER_FLAG_HASAUDIO){ |
2691 | 283 if(!create_stream(s, 1)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
284 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
285 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
286 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
287 offset = get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
288 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
|
289 |
1318 | 290 s->start_time = 0; |
291 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
292 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
293 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
294 |
3364 | 295 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) |
296 { | |
297 av_free(st->codec->extradata); | |
298 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
299 if (!st->codec->extradata) | |
300 return AVERROR(ENOMEM); | |
301 st->codec->extradata_size = size; | |
302 get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); | |
303 return 0; | |
304 } | |
305 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
306 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
|
307 { |
4034 | 308 FLVContext *flv = s->priv_data; |
4005 | 309 int ret, i, type, size, flags, is_audio; |
310 int64_t next, pos; | |
4034 | 311 int64_t dts, pts = AV_NOPTS_VALUE; |
679 | 312 AVStream *st = NULL; |
885 | 313 |
445 | 314 for(;;){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
315 pos = url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
316 url_fskip(s->pb, 4); /* size of previous packet */ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
317 type = get_byte(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
318 size = get_be24(s->pb); |
3336 | 319 dts = get_be24(s->pb); |
320 dts |= get_byte(s->pb) << 24; | |
321 // 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
|
322 if (url_feof(s->pb)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
323 return AVERROR(EIO); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
324 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
|
325 flags = 0; |
885 | 326 |
445 | 327 if(size == 0) |
328 continue; | |
885 | 329 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
330 next= size + url_ftell(s->pb); |
821 | 331 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
332 if (type == FLV_TAG_TYPE_AUDIO) { |
445 | 333 is_audio=1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
334 flags = get_byte(s->pb); |
3797 | 335 size--; |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
336 } else if (type == FLV_TAG_TYPE_VIDEO) { |
445 | 337 is_audio=0; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
338 flags = get_byte(s->pb); |
3797 | 339 size--; |
3798 | 340 if ((flags & 0xf0) == 0x50) /* video info / command frame */ |
341 goto skip; | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
342 } else { |
1568 | 343 if (type == FLV_TAG_TYPE_META && size > 13+1+4) |
344 flv_read_metabody(s, next); | |
345 else /* skip packet */ | |
346 av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); | |
3798 | 347 skip: |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
348 url_fseek(s->pb, next, SEEK_SET); |
4271
f9ec55b30dfa
Use EAGAIN return, primarely intended as example of EAGAIN useage.
michael
parents:
4251
diff
changeset
|
349 return AVERROR(EAGAIN); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
350 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
351 |
3799 | 352 /* skip empty data packets */ |
353 if (!size) | |
354 continue; | |
355 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
356 /* now find stream */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
357 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
|
358 st = s->streams[i]; |
445 | 359 if (st->id == is_audio) |
360 break; | |
361 } | |
362 if(i == s->nb_streams){ | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
363 av_log(NULL, AV_LOG_ERROR, "invalid stream\n"); |
2692 | 364 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
|
365 s->ctx_flags &= ~AVFMTCTX_NOHEADER; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
366 } |
708 | 367 // av_log(NULL, 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
|
368 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
|
369 ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio)) |
708 | 370 || st->discard >= AVDISCARD_ALL |
371 ){ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
372 url_fseek(s->pb, next, SEEK_SET); |
4271
f9ec55b30dfa
Use EAGAIN return, primarely intended as example of EAGAIN useage.
michael
parents:
4251
diff
changeset
|
373 return AVERROR(EAGAIN); |
652 | 374 } |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
375 if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) |
3336 | 376 av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); |
445 | 377 break; |
378 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
379 |
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
|
380 // 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
|
381 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
|
382 int size; |
4005 | 383 const int64_t pos= url_ftell(s->pb); |
384 const int64_t fsize= url_fsize(s->pb); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
385 url_fseek(s->pb, fsize-4, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
386 size= get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
387 url_fseek(s->pb, fsize-3-size, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
388 if(size == get_be24(s->pb) + 11){ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
389 s->duration= get_be24(s->pb) * (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
|
390 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
391 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
|
392 } |
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
393 |
445 | 394 if(is_audio){ |
4125
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
395 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
|
396 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
|
397 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
|
398 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
|
399 } |
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
400 if(!st->codec->codec_id){ |
1568 | 401 flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK); |
445 | 402 } |
403 }else{ | |
1568 | 404 size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); |
378 | 405 } |
406 | |
3364 | 407 if (st->codec->codec_id == CODEC_ID_AAC || |
408 st->codec->codec_id == CODEC_ID_H264) { | |
409 int type = get_byte(s->pb); | |
410 size--; | |
411 if (st->codec->codec_id == CODEC_ID_H264) { | |
4034 | 412 int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension |
413 pts = dts + cts; | |
414 if (cts < 0) { // dts are wrong | |
415 flv->wrong_dts = 1; | |
416 av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); | |
417 } | |
418 if (flv->wrong_dts) | |
419 dts = AV_NOPTS_VALUE; | |
3364 | 420 } |
421 if (type == 0) { | |
3797 | 422 if ((ret = flv_get_extradata(s, st, size)) < 0) |
3364 | 423 return ret; |
4271
f9ec55b30dfa
Use EAGAIN return, primarely intended as example of EAGAIN useage.
michael
parents:
4251
diff
changeset
|
424 return AVERROR(EAGAIN); |
3364 | 425 } |
426 } | |
427 | |
3797 | 428 ret= av_get_packet(s->pb, pkt, size); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
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 }; |