Mercurial > libavformat.hg
annotate flvdec.c @ 6260:5c17c20dd67a libavformat
In ogg muxer, use dyn buffer to compute crc of the page, fix muxing with pipe
when page buffer is bigger than default buffer size. Max page is 65k.
author | bcoudurier |
---|---|
date | Wed, 14 Jul 2010 23:21:18 +0000 |
parents | da46dcc05d4a |
children |
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)); |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5963
diff
changeset
|
191 av_metadata_set2(&s->metadata, key, str_val, 0); |
1568 | 192 } else if(amf_type == AMF_DATA_TYPE_NUMBER) { |
5462 | 193 snprintf(str_val, sizeof(str_val), "%.f", num_val); |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5963
diff
changeset
|
194 av_metadata_set2(&s->metadata, key, str_val, 0); |
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; |
5945 | 198 else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0)) |
199 acodec->bit_rate = num_val * 1024.0; | |
5097
453175c733c4
flvdec: expose metadata through the generic metadata API
aurel
parents:
5096
diff
changeset
|
200 } else if (amf_type == AMF_DATA_TYPE_STRING) |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5963
diff
changeset
|
201 av_metadata_set2(&s->metadata, key, str_val, 0); |
1568 | 202 } |
203 | |
204 return 0; | |
205 } | |
206 | |
4005 | 207 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { |
1568 | 208 AMFDataType type; |
209 AVStream *stream, *astream, *vstream; | |
210 ByteIOContext *ioc; | |
4887
acb51f192e13
Remove unused variable from flv_read_metabody() found by CSA.
michael
parents:
4863
diff
changeset
|
211 int i; |
5462 | 212 char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. |
1568 | 213 |
214 astream = NULL; | |
215 vstream = NULL; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
216 ioc = s->pb; |
1568 | 217 |
218 //first object needs to be "onMetaData" string | |
219 type = get_byte(ioc); | |
5462 | 220 if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) |
1568 | 221 return -1; |
222 | |
223 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. | |
224 for(i = 0; i < s->nb_streams; i++) { | |
225 stream = s->streams[i]; | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5564
diff
changeset
|
226 if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream; |
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5564
diff
changeset
|
227 else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream; |
1568 | 228 } |
229 | |
230 //parse the second object (we want a mixed array) | |
5462 | 231 if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) |
1568 | 232 return -1; |
233 | |
234 return 0; | |
235 } | |
236 | |
2691 | 237 static AVStream *create_stream(AVFormatContext *s, int is_audio){ |
238 AVStream *st = av_new_stream(s, is_audio); | |
239 if (!st) | |
240 return NULL; | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5564
diff
changeset
|
241 st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO; |
3335 | 242 av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ |
2691 | 243 return st; |
244 } | |
245 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
246 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
|
247 AVFormatParameters *ap) |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
248 { |
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
|
249 int offset, flags; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
250 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
251 url_fskip(s->pb, 4); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
252 flags = get_byte(s->pb); |
1886 | 253 /* old flvtool cleared this field */ |
254 /* FIXME: better fix needed */ | |
255 if (!flags) { | |
256 flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; | |
257 av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); | |
258 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
259 |
3218 | 260 if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) |
261 != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) | |
262 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
263 | |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
264 if(flags & FLV_HEADER_FLAG_HASVIDEO){ |
2691 | 265 if(!create_stream(s, 0)) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2216
diff
changeset
|
266 return AVERROR(ENOMEM); |
1559
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
267 } |
515e80ef01e6
get rid of AVFMTCTX_NOHEADER, create streams in read_header()
michael
parents:
1553
diff
changeset
|
268 if(flags & FLV_HEADER_FLAG_HASAUDIO){ |
2691 | 269 if(!create_stream(s, 1)) |
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 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
273 offset = get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
274 url_fseek(s->pb, offset, SEEK_SET); |
5916 | 275 url_fskip(s->pb, 4); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
276 |
1318 | 277 s->start_time = 0; |
278 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
279 return 0; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
280 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
281 |
3364 | 282 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) |
283 { | |
284 av_free(st->codec->extradata); | |
285 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
286 if (!st->codec->extradata) | |
287 return AVERROR(ENOMEM); | |
288 st->codec->extradata_size = size; | |
289 get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); | |
290 return 0; | |
291 } | |
292 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
293 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
|
294 { |
4034 | 295 FLVContext *flv = s->priv_data; |
4005 | 296 int ret, i, type, size, flags, is_audio; |
297 int64_t next, pos; | |
4034 | 298 int64_t dts, pts = AV_NOPTS_VALUE; |
679 | 299 AVStream *st = NULL; |
885 | 300 |
5916 | 301 for(;;url_fskip(s->pb, 4)){ /* pkt size is repeated at end. skip it */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
302 pos = url_ftell(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
303 type = get_byte(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
304 size = get_be24(s->pb); |
3336 | 305 dts = get_be24(s->pb); |
306 dts |= get_byte(s->pb) << 24; | |
307 // 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
|
308 if (url_feof(s->pb)) |
4542
241a66d33f49
FLV demuxer: return AVERROR_EOF upon detection of end of file.
pross
parents:
4509
diff
changeset
|
309 return AVERROR_EOF; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
310 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
|
311 flags = 0; |
885 | 312 |
445 | 313 if(size == 0) |
314 continue; | |
885 | 315 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
316 next= size + url_ftell(s->pb); |
821 | 317 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
318 if (type == FLV_TAG_TYPE_AUDIO) { |
445 | 319 is_audio=1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
320 flags = get_byte(s->pb); |
3797 | 321 size--; |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
322 } else if (type == FLV_TAG_TYPE_VIDEO) { |
445 | 323 is_audio=0; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
324 flags = get_byte(s->pb); |
3797 | 325 size--; |
3798 | 326 if ((flags & 0xf0) == 0x50) /* video info / command frame */ |
327 goto skip; | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
328 } else { |
5096 | 329 if (type == FLV_TAG_TYPE_META && size > 13+1+4) |
1568 | 330 flv_read_metabody(s, next); |
331 else /* skip packet */ | |
5037
3550a49d6255
Downgrade message log level (from AV_LOG_ERROR to AV_LOG_DEBUG) about
stefano
parents:
4887
diff
changeset
|
332 av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); |
3798 | 333 skip: |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
334 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
|
335 continue; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
336 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
337 |
3799 | 338 /* skip empty data packets */ |
339 if (!size) | |
340 continue; | |
341 | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
342 /* now find stream */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
343 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
|
344 st = s->streams[i]; |
445 | 345 if (st->id == is_audio) |
346 break; | |
347 } | |
348 if(i == s->nb_streams){ | |
4509 | 349 av_log(s, AV_LOG_ERROR, "invalid stream\n"); |
2692 | 350 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
|
351 s->ctx_flags &= ~AVFMTCTX_NOHEADER; |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
352 } |
4509 | 353 // 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
|
354 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
|
355 ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio)) |
708 | 356 || st->discard >= AVDISCARD_ALL |
357 ){ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
358 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
|
359 continue; |
652 | 360 } |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
361 if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) |
3336 | 362 av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); |
445 | 363 break; |
364 } | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
365 |
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 // 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
|
367 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
|
368 int size; |
4005 | 369 const int64_t pos= url_ftell(s->pb); |
370 const int64_t fsize= url_fsize(s->pb); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
371 url_fseek(s->pb, fsize-4, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
372 size= get_be32(s->pb); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
373 url_fseek(s->pb, fsize-3-size, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
374 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
|
375 uint32_t ts = get_be24(s->pb); |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
376 ts |= get_byte(s->pb) << 24; |
01514407ab35
Use all 32 bits of the timestamp when calculating flv duration.
diego
parents:
5155
diff
changeset
|
377 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
|
378 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2756
diff
changeset
|
379 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
|
380 } |
bf3589ba8d7e
move duration finding code into read_packet() so it can be skiped if duration has already been set
michael
parents:
1562
diff
changeset
|
381 |
445 | 382 if(is_audio){ |
4125
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
383 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
|
384 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
|
385 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
|
386 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
|
387 } |
df6989f6122b
Fix detection of audio codec in K70707-ARIA229.flv.
michael
parents:
4034
diff
changeset
|
388 if(!st->codec->codec_id){ |
1568 | 389 flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK); |
445 | 390 } |
391 }else{ | |
1568 | 392 size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); |
378 | 393 } |
394 | |
3364 | 395 if (st->codec->codec_id == CODEC_ID_AAC || |
396 st->codec->codec_id == CODEC_ID_H264) { | |
397 int type = get_byte(s->pb); | |
398 size--; | |
399 if (st->codec->codec_id == CODEC_ID_H264) { | |
4034 | 400 int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension |
401 pts = dts + cts; | |
402 if (cts < 0) { // dts are wrong | |
403 flv->wrong_dts = 1; | |
404 av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); | |
405 } | |
406 if (flv->wrong_dts) | |
407 dts = AV_NOPTS_VALUE; | |
3364 | 408 } |
409 if (type == 0) { | |
3797 | 410 if ((ret = flv_get_extradata(s, st, size)) < 0) |
3364 | 411 return ret; |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
412 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
|
413 MPEG4AudioConfig cfg; |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
414 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
|
415 st->codec->extradata_size); |
5362 | 416 st->codec->channels = cfg.channels; |
6210
da46dcc05d4a
Use ext sample from mpeg4audio config if set with AAC SBR
bcoudurier
parents:
5982
diff
changeset
|
417 if (cfg.ext_sample_rate) |
da46dcc05d4a
Use ext sample from mpeg4audio config if set with AAC SBR
bcoudurier
parents:
5982
diff
changeset
|
418 st->codec->sample_rate = cfg.ext_sample_rate; |
da46dcc05d4a
Use ext sample from mpeg4audio config if set with AAC SBR
bcoudurier
parents:
5982
diff
changeset
|
419 else |
da46dcc05d4a
Use ext sample from mpeg4audio config if set with AAC SBR
bcoudurier
parents:
5982
diff
changeset
|
420 st->codec->sample_rate = cfg.sample_rate; |
4559
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
421 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
|
422 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
|
423 } |
ee5d7f52e4bc
parse aac extradata to fetch channels and sample rate, patch from Netgem
bcoudurier
parents:
4542
diff
changeset
|
424 |
5916 | 425 ret = AVERROR(EAGAIN); |
426 goto leave; | |
3364 | 427 } |
428 } | |
429 | |
4805 | 430 /* skip empty data packets */ |
5916 | 431 if (!size) { |
432 ret = AVERROR(EAGAIN); | |
433 goto leave; | |
434 } | |
4805 | 435 |
3797 | 436 ret= av_get_packet(s->pb, pkt, size); |
4811 | 437 if (ret < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
438 return AVERROR(EIO); |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
439 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
440 /* 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
|
441 packet */ |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
442 pkt->size = ret; |
3336 | 443 pkt->dts = dts; |
4034 | 444 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
|
445 pkt->stream_index = st->index; |
885 | 446 |
1553
504ceaa50e31
Defines various common FLV format values between the FLV muxer and demuxer
aurel
parents:
1415
diff
changeset
|
447 if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) |
5913
11bb10c37225
Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents:
5910
diff
changeset
|
448 pkt->flags |= AV_PKT_FLAG_KEY; |
885 | 449 |
5916 | 450 leave: |
451 url_fskip(s->pb, 4); | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
452 return ret; |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
453 } |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
454 |
5963 | 455 static int flv_read_seek(AVFormatContext *s, int stream_index, |
456 int64_t ts, int flags) | |
457 { | |
458 return av_url_read_fseek(s->pb, stream_index, ts, flags); | |
459 } | |
460 | |
461 #if 0 /* don't know enough to implement this */ | |
462 static int flv_read_seek2(AVFormatContext *s, int stream_index, | |
463 int64_t min_ts, int64_t ts, int64_t max_ts, int flags) | |
464 { | |
465 int ret = AVERROR(ENOSYS); | |
466 | |
467 if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD; | |
468 | |
469 if (url_is_streamed(s->pb)) { | |
470 if (stream_index < 0) { | |
471 stream_index = av_find_default_stream_index(s); | |
472 if (stream_index < 0) | |
473 return -1; | |
474 | |
475 /* timestamp for default must be expressed in AV_TIME_BASE units */ | |
476 ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, | |
477 flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); | |
478 } | |
479 ret = av_url_read_fseek(s->pb, stream_index, ts, flags); | |
480 } | |
481 | |
482 if (ret == AVERROR(ENOSYS)) | |
483 ret = av_seek_frame(s, stream_index, ts, flags); | |
484 return ret; | |
485 } | |
486 #endif | |
487 | |
1167 | 488 AVInputFormat flv_demuxer = { |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
489 "flv", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3364
diff
changeset
|
490 NULL_IF_CONFIG_SMALL("FLV format"), |
4034 | 491 sizeof(FLVContext), |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
492 flv_probe, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
493 flv_read_header, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
494 flv_read_packet, |
5963 | 495 .read_seek = flv_read_seek, |
496 #if 0 | |
497 .read_seek2 = flv_read_seek2, | |
498 #endif | |
164
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
499 .extensions = "flv", |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
500 .value = CODEC_ID_FLV1, |
99fbacf0f764
flash video (flv) support patch by (Garrick Meeker <gmeeker at theoryllc dot com>)
michaelni
parents:
diff
changeset
|
501 }; |