Mercurial > libavformat.hg
annotate flvdec.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | 2a7f495e8c56 |
children | ccddbe22fa8f |
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 |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
3 * Copyright (c) 2003 The FFmpeg Project. |
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 |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
29 static int flv_probe(AVProbeData *p) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
30 { |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
31 const uint8_t *d; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
32 |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
33 d = p->buf; |
1718 | 34 if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0) { |
35 return AVPROBE_SCORE_MAX; | |
164
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 return 0; |
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 |
1568 | 40 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) { |
41 AVCodecContext *acodec = astream->codec; | |
42 switch(flv_codecid) { | |
43 //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
|
44 case FLV_CODECID_PCM: |
3062 | 45 acodec->codec_id = acodec->bits_per_sample == 8 ? CODEC_ID_PCM_S8 : |
46 #ifdef WORDS_BIGENDIAN | |
47 CODEC_ID_PCM_S16BE; | |
48 #else | |
49 CODEC_ID_PCM_S16LE; | |
50 #endif | |
51 break; | |
1568 | 52 case FLV_CODECID_PCM_LE: |
53 acodec->codec_id = acodec->bits_per_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16LE; break; | |
3364 | 54 case FLV_CODECID_AAC : acodec->codec_id = CODEC_ID_AAC; break; |
1568 | 55 case FLV_CODECID_ADPCM: acodec->codec_id = CODEC_ID_ADPCM_SWF; break; |
2023 | 56 case FLV_CODECID_MP3 : acodec->codec_id = CODEC_ID_MP3 ; astream->need_parsing = AVSTREAM_PARSE_FULL; break; |
1568 | 57 case FLV_CODECID_NELLYMOSER_8HZ_MONO: |
58 acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate | |
59 case FLV_CODECID_NELLYMOSER: | |
2604 | 60 acodec->codec_id = CODEC_ID_NELLYMOSER; |
61 break; | |
1568 | 62 default: |
63 av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET); | |
64 acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; | |
65 } | |
66 } | |
67 | |
68 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { | |
69 AVCodecContext *vcodec = vstream->codec; | |
70 switch(flv_codecid) { | |
71 case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; | |
72 case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break; | |
73 case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; | |
2572 | 74 case FLV_CODECID_VP6A : |
75 if(flv_codecid == FLV_CODECID_VP6A) | |
76 vcodec->codec_id = CODEC_ID_VP6A; | |
1568 | 77 if(vcodec->extradata_size != 1) { |
78 vcodec->extradata_size = 1; | |
79 vcodec->extradata = av_malloc(1); | |
80 } | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
81 vcodec->extradata[0] = get_byte(s->pb); |
1568 | 82 return 1; // 1 byte body size adjustment for flv_read_packet() |
3364 | 83 case FLV_CODECID_H264: |
84 vcodec->codec_id = CODEC_ID_H264; | |
85 return 3; // not 4, reading packet type will consume one byte | |
1568 | 86 default: |
87 av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); | |
88 vcodec->codec_tag = flv_codecid; | |
89 } | |
90 | |
91 return 0; | |
92 } | |
93 | |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
94 static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) { |
1561 | 95 int length = get_be16(ioc); |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
96 if(length >= buffsize) { |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
97 url_fskip(ioc, length); |
1561 | 98 return -1; |
1560
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
99 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
100 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
101 get_buffer(ioc, buffer, length); |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
102 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
103 buffer[length] = '\0'; |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
104 |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
105 return length; |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
106 } |
f59b66f9d679
amf_get_string() by Allan Hsu allan aat counterpop doot net
michael
parents:
1559
diff
changeset
|
107 |
1568 | 108 static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, unsigned int max_pos, int depth) { |
109 AVCodecContext *acodec, *vcodec; | |
110 ByteIOContext *ioc; | |
111 AMFDataType amf_type; | |
112 char str_val[256]; | |
113 double num_val; | |
114 | |
115 num_val = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
116 ioc = s->pb; |
1568 | 117 |
118 amf_type = get_byte(ioc); | |
119 | |
120 switch(amf_type) { | |
121 case AMF_DATA_TYPE_NUMBER: | |
122 num_val = av_int2dbl(get_be64(ioc)); break; | |
123 case AMF_DATA_TYPE_BOOL: | |
124 num_val = get_byte(ioc); break; | |
125 case AMF_DATA_TYPE_STRING: | |
126 if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) | |
127 return -1; | |
128 break; | |
129 case AMF_DATA_TYPE_OBJECT: { | |
130 unsigned int keylen; | |
131 | |
132 while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) { | |
133 url_fskip(ioc, keylen); //skip key string | |
134 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
135 return -1; //if we couldn't skip, bomb out. | |
136 } | |
137 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
138 return -1; | |
139 } | |
140 break; | |
141 case AMF_DATA_TYPE_NULL: | |
142 case AMF_DATA_TYPE_UNDEFINED: | |
143 case AMF_DATA_TYPE_UNSUPPORTED: | |
144 break; //these take up no additional space | |
145 case AMF_DATA_TYPE_MIXEDARRAY: | |
146 url_fskip(ioc, 4); //skip 32-bit max array index | |
147 while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { | |
148 //this is the only case in which we would want a nested parse to not skip over the object | |
149 if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) | |
150 return -1; | |
151 } | |
152 if(get_byte(ioc) != AMF_END_OF_OBJECT) | |
153 return -1; | |
154 break; | |
155 case AMF_DATA_TYPE_ARRAY: { | |
156 unsigned int arraylen, i; | |
157 | |
158 arraylen = get_be32(ioc); | |
159 for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) { | |
160 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) | |
161 return -1; //if we couldn't skip, bomb out. | |
162 } | |
163 } | |
164 break; | |
165 case AMF_DATA_TYPE_DATE: | |
166 url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) | |
167 break; | |
168 default: //unsupported type, we couldn't skip | |
169 return -1; | |
170 } | |
171 | |
172 if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL | |
173 acodec = astream ? astream->codec : NULL; | |
174 vcodec = vstream ? vstream->codec : NULL; | |
175 | |
176 if(amf_type == AMF_DATA_TYPE_BOOL) { | |
177 if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1; | |
178 } else if(amf_type == AMF_DATA_TYPE_NUMBER) { | |
179 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
|
180 // 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
|
181 // else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val; |
3152
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
182 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
|
183 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
|
184 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
|
185 flv_set_video_codec(s, vstream, (int)num_val); |
1d9a55c8d259
Additional checks for strange num_val in FLV metadata
skal
parents:
3062
diff
changeset
|
186 else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) { |
1568 | 187 acodec->bits_per_sample = num_val; |
188 //we may have to rewrite a previously read codecid because FLV only marks PCM endianness. | |
189 if(num_val == 8 && (acodec->codec_id == CODEC_ID_PCM_S16BE || acodec->codec_id == CODEC_ID_PCM_S16LE)) | |
190 acodec->codec_id = CODEC_ID_PCM_S8; | |
191 } | |
192 else if(!strcmp(key, "audiosamplerate") && acodec && num_val >= 0) { | |
193 //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
|
194 if (!acodec->sample_rate) { |
2848 | 195 switch((int)num_val) { |
196 case 44000: acodec->sample_rate = 44100 ; break; | |
197 case 22000: acodec->sample_rate = 22050 ; break; | |
198 case 11000: acodec->sample_rate = 11025 ; break; | |
199 case 5000 : acodec->sample_rate = 5512 ; break; | |
200 default : acodec->sample_rate = num_val; | |
201 } | |
2847
f2a69a8c657d
Correctly handle FLV_CODECID_NELLYMOSER_8HZ_MONO files
banan
parents:
2771
diff
changeset
|
202 } |
1568 | 203 } |
204 } | |
205 } | |
206 | |
207 return 0; | |
208 } | |
209 | |
210 static int flv_read_metabody(AVFormatContext *s, unsigned int next_pos) { | |
211 AMFDataType type; | |
212 AVStream *stream, *astream, *vstream; | |
213 ByteIOContext *ioc; | |
214 int i, keylen; | |
215 char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. | |
216 | |
217 astream = NULL; | |
218 vstream = NULL; | |
219 keylen = 0; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
220 ioc = s->pb; |
1568 | 221 |
222 //first object needs to be "onMetaData" string | |
223 type = get_byte(ioc); | |
224 if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) | |
225 return -1; | |
226 | |
227 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. | |
228 for(i = 0; i < s->nb_streams; i++) { | |
229 stream = s->streams[i]; | |
230 if (stream->codec->codec_type == CODEC_TYPE_AUDIO) astream = stream; | |
231 else if(stream->codec->codec_type == CODEC_TYPE_VIDEO) vstream = stream; | |
232 } | |
233 | |
234 //parse the second object (we want a mixed array) | |
235 if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) | |
236 return -1; | |
237 | |
238 return 0; | |
239 } | |
240 | |
2691 | 241 static AVStream *create_stream(AVFormatContext *s, int is_audio){ |
242 AVStream *st = av_new_stream(s, is_audio); | |
243 if (!st) | |
244 return NULL; | |
245 st->codec->codec_type = is_audio ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO; | |
3335 | 246 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ |
2691 | 247 return st; |
248 } | |
249 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
250 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
|
251 AVFormatParameters *ap) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
252 { |
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
|
253 int offset, flags; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
254 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
255 url_fskip(s->pb, 4); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
256 flags = get_byte(s->pb); |
1886 | 257 /* old flvtool cleared this field */ |
258 /* FIXME: better fix needed */ | |
259 if (!flags) { | |
260 flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; | |
261 av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); | |
262 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
263 |
3218 | 264 if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) |
265 != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) | |
266 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
267 | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
268 if(flags & FLV_HEADER_FLAG_HASVIDEO){ |
2691 | 269 if(!create_stream(s, 0)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
270 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
271 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
272 if(flags & FLV_HEADER_FLAG_HASAUDIO){ |
2691 | 273 if(!create_stream(s, 1)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
274 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
275 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
276 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
277 offset = get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
278 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
|
279 |
1318 | 280 s->start_time = 0; |
281 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
282 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
283 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
284 |
3364 | 285 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) |
286 { | |
287 av_free(st->codec->extradata); | |
288 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
289 if (!st->codec->extradata) | |
290 return AVERROR(ENOMEM); | |
291 st->codec->extradata_size = size; | |
292 get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); | |
293 return 0; | |
294 } | |
295 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
296 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
|
297 { |
3251
994c65371958
pts are unsigned according to specs, fix negative pts when 32bit pts are used
bcoudurier
parents:
3219
diff
changeset
|
298 int ret, i, type, size, flags, is_audio, next, pos; |
3336 | 299 unsigned dts; |
679 | 300 AVStream *st = NULL; |
885 | 301 |
3364 | 302 retry: |
445 | 303 for(;;){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
304 pos = url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
305 url_fskip(s->pb, 4); /* size of previous packet */ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
306 type = get_byte(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
307 size = get_be24(s->pb); |
3336 | 308 dts = get_be24(s->pb); |
309 dts |= get_byte(s->pb) << 24; | |
310 // 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
|
311 if (url_feof(s->pb)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
312 return AVERROR(EIO); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
313 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
|
314 flags = 0; |
885 | 315 |
445 | 316 if(size == 0) |
317 continue; | |
885 | 318 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
319 next= size + url_ftell(s->pb); |
821 | 320 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
321 if (type == FLV_TAG_TYPE_AUDIO) { |
445 | 322 is_audio=1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
323 flags = get_byte(s->pb); |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
324 } else if (type == FLV_TAG_TYPE_VIDEO) { |
445 | 325 is_audio=0; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
326 flags = get_byte(s->pb); |
3611
2a7f495e8c56
skip flv video info / command frame packets, fix issue #546
bcoudurier
parents:
3424
diff
changeset
|
327 if ((flags & 0xf0) == 0x50) { /* video info / command frame */ |
2a7f495e8c56
skip flv video info / command frame packets, fix issue #546
bcoudurier
parents:
3424
diff
changeset
|
328 url_fskip(s->pb, size - 1); |
2a7f495e8c56
skip flv video info / command frame packets, fix issue #546
bcoudurier
parents:
3424
diff
changeset
|
329 continue; |
2a7f495e8c56
skip flv video info / command frame packets, fix issue #546
bcoudurier
parents:
3424
diff
changeset
|
330 } |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
331 } else { |
1568 | 332 if (type == FLV_TAG_TYPE_META && size > 13+1+4) |
333 flv_read_metabody(s, next); | |
334 else /* skip packet */ | |
335 av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
336 url_fseek(s->pb, next, SEEK_SET); |
445 | 337 continue; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
338 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
339 |
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){ | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
347 av_log(NULL, 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 } |
708 | 351 // 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
|
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); |
652 | 357 continue; |
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 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
365 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
|
366 int size; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
367 const int pos= url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
368 const int fsize= url_fsize(s->pb); |
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){ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
373 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
|
374 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
375 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
|
376 } |
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 |
445 | 378 if(is_audio){ |
1568 | 379 if(!st->codec->sample_rate || !st->codec->bits_per_sample || (!st->codec->codec_id && !st->codec->codec_tag)) { |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
380 st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1; |
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
381 if((flags & FLV_AUDIO_CODECID_MASK) == FLV_CODECID_NELLYMOSER_8HZ_MONO) |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
382 st->codec->sample_rate= 8000; |
445 | 383 else |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
384 st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3); |
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
385 st->codec->bits_per_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; |
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) { | |
397 // cts offset ignored because it might to be signed | |
398 // and would cause pts < dts | |
399 get_be24(s->pb); | |
400 } | |
401 if (type == 0) { | |
402 if ((ret = flv_get_extradata(s, st, size - 1)) < 0) | |
403 return ret; | |
404 goto retry; | |
405 } | |
406 } | |
407 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
408 ret= av_get_packet(s->pb, pkt, size - 1); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
409 if (ret <= 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
410 return AVERROR(EIO); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
411 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
412 /* 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
|
413 packet */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
414 pkt->size = ret; |
3336 | 415 pkt->dts = dts; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
416 pkt->stream_index = st->index; |
885 | 417 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
418 if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) |
887 | 419 pkt->flags |= PKT_FLAG_KEY; |
885 | 420 |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
421 return ret; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
422 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
423 |
1167 | 424 AVInputFormat flv_demuxer = { |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
425 "flv", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3364
diff
changeset
|
426 NULL_IF_CONFIG_SMALL("FLV format"), |
2571 | 427 0, |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
428 flv_probe, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
429 flv_read_header, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
430 flv_read_packet, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
431 .extensions = "flv", |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
432 .value = CODEC_ID_FLV1, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
433 }; |