[FFmpeg-devel] [PATCH] better detection of available streams for flv
Reimar Döffinger
Reimar.Doeffinger
Sun Apr 13 18:06:00 CEST 2008
Hello,
with e.g. http://eurovision.tv/upload/video/2008/WELCOMETOBELGRADE.flv
the flv demuxer thinks that there is no video stream.
Attached code changes the code to create a audio/video stream if the
metadata-parsing code finds a key starting with "audio" or "video" and
there is not yet such a stream.
Obviously, there are many other ways to do this, and if such a change is
done the hack in flv_read_header should probably be removed.
Instead of checking for any key starting with audio/video this could of
course be restricted to those we actually handle, namely audiocodecid,
videocodecid, audiosamplesize, audiosamplerate and stereo.
Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavformat/flvdec.c
===================================================================
--- libavformat/flvdec.c (revision 12797)
+++ libavformat/flvdec.c (working copy)
@@ -101,7 +101,9 @@
return length;
}
-static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, unsigned int max_pos, int depth) {
+static AVStream *create_stream(AVFormatContext *s, int is_audio);
+
+static int amf_parse_object(AVFormatContext *s, AVStream **astream, AVStream **vstream, const char *key, unsigned int max_pos, int depth) {
AVCodecContext *acodec, *vcodec;
ByteIOContext *ioc;
AMFDataType amf_type;
@@ -166,8 +168,13 @@
}
if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
- acodec = astream ? astream->codec : NULL;
- vcodec = vstream ? vstream->codec : NULL;
+ // HACK: create extra streams if it looks like there are more streams than the header indicates
+ if(vstream && !*vstream && !strncmp(key, "video", 5))
+ *vstream = create_stream(s, 0);
+ if(astream && !*astream && !strncmp(key, "audio", 5))
+ *astream = create_stream(s, 1);
+ acodec = *astream ? (*astream)->codec : NULL;
+ vcodec = *vstream ? (*vstream)->codec : NULL;
if(amf_type == AMF_DATA_TYPE_BOOL) {
if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1;
@@ -176,9 +183,9 @@
// else if(!strcmp(key, "width") && vcodec && num_val > 0) vcodec->width = num_val;
// else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val;
else if(!strcmp(key, "audiocodecid") && acodec && 0 <= (int)num_val)
- flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
+ flv_set_audio_codec(s, *astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
else if(!strcmp(key, "videocodecid") && vcodec && 0 <= (int)num_val)
- flv_set_video_codec(s, vstream, (int)num_val);
+ flv_set_video_codec(s, *vstream, (int)num_val);
else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) {
acodec->bits_per_sample = num_val;
//we may have to rewrite a previously read codecid because FLV only marks PCM endianness.
@@ -228,7 +235,7 @@
}
//parse the second object (we want a mixed array)
- if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
+ if(amf_parse_object(s, &astream, &vstream, buffer, next_pos, 0) < 0)
return -1;
return 0;
More information about the ffmpeg-devel
mailing list