diff options
author | René Stadler <mail@renestadler.de> | 2007-03-08 16:01:42 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-03-08 16:01:42 +0000 |
commit | 654ad41f259ffcb204ddc7a8001f3edf6a4bee60 (patch) | |
tree | 0bb615e81b340f5de2715487e49a5f4cff45c241 /gst/avi | |
parent | 7a71c68fa858b1db6d08ba62bd7da723c03d9d05 (diff) |
gst/avi/gstavidemux.c: Make avidemux accept optional header chunks in any order.
Original commit message from CVS:
Patch by: René Stadler <mail at renestadler dot de>
* gst/avi/gstavidemux.c: (gst_avi_demux_parse_stream),
(gst_avi_demux_push_event), (gst_avi_demux_process_next_entry),
(gst_avi_demux_stream_data), (gst_avi_demux_chain):
Make avidemux accept optional header chunks in any order.
Fixes #415446.
Diffstat (limited to 'gst/avi')
-rw-r--r-- | gst/avi/gstavidemux.c | 129 |
1 files changed, 71 insertions, 58 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 1cce3797..0177e5a8 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -1156,70 +1156,71 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf) GstCaps *caps = NULL; GstPad *pad; GstElement *element; + gboolean got_strh = FALSE, got_strf = FALSE; element = GST_ELEMENT_CAST (avi); GST_DEBUG_OBJECT (avi, "Parsing stream"); - /* read strh */ - if (!gst_riff_parse_chunk (element, buf, &offset, &tag, &sub) || - tag != GST_RIFF_TAG_strh) { - GST_ERROR_OBJECT (avi, - "Failed to find strh chunk (bufsize: %d, tag: %" GST_FOURCC_FORMAT ")", - GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag)); - goto fail; - } else if (!gst_riff_parse_strh (element, sub, &stream->strh)) { - GST_WARNING_OBJECT (avi, "Failed to parse strh chunk"); - goto fail; - } - - /* read strf */ - if (!gst_riff_parse_chunk (element, buf, &offset, &tag, &sub) || - tag != GST_RIFF_TAG_strf) { - GST_ERROR_OBJECT (avi, - "Failed to find strf chunk (size: %d, tag: %" - GST_FOURCC_FORMAT ")", GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag)); - goto fail; - } else { - gboolean res = FALSE; - - switch (stream->strh->type) { - case GST_RIFF_FCC_vids: - stream->is_vbr = TRUE; - res = gst_riff_parse_strf_vids (element, sub, - &stream->strf.vids, &stream->extradata); - GST_DEBUG_OBJECT (element, "marking video as VBR, res %d", res); - break; - case GST_RIFF_FCC_auds: - stream->is_vbr = (stream->strh->samplesize == 0) - && stream->strh->scale > 1; - res = - gst_riff_parse_strf_auds (element, sub, &stream->strf.auds, - &stream->extradata); - GST_DEBUG_OBJECT (element, "marking audio as VBR:%d, res %d", - stream->is_vbr, res); - break; - case GST_RIFF_FCC_iavs: - stream->is_vbr = TRUE; - res = gst_riff_parse_strf_iavs (element, sub, - &stream->strf.iavs, &stream->extradata); - GST_DEBUG_OBJECT (element, "marking iavs as VBR, res %d", res); - break; - default: - GST_ERROR_OBJECT (avi, - "Don´t know how to handle stream type %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (stream->strh->type)); - break; - } - - if (!res) - goto fail; - } - - /* read strd/strn */ while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) { /* sub can be NULL if the chunk is empty */ switch (tag) { + case GST_RIFF_TAG_strh: + if (got_strh) { + GST_WARNING_OBJECT (avi, "Ignoring additional strh chunk"); + break; + } + if (!gst_riff_parse_strh (element, sub, &stream->strh)) { + GST_WARNING_OBJECT (avi, "Failed to parse strh chunk"); + goto fail; + } + got_strh = TRUE; + break; + case GST_RIFF_TAG_strf: + { + gboolean res = FALSE; + + if (got_strf) { + GST_WARNING_OBJECT (avi, "Ignoring additional strf chunk"); + break; + } + if (!got_strh) { + GST_ERROR_OBJECT (avi, "Found strf chunk before strh chunk"); + goto fail; + } + switch (stream->strh->type) { + case GST_RIFF_FCC_vids: + stream->is_vbr = TRUE; + res = gst_riff_parse_strf_vids (element, sub, + &stream->strf.vids, &stream->extradata); + GST_DEBUG_OBJECT (element, "marking video as VBR, res %d", res); + break; + case GST_RIFF_FCC_auds: + stream->is_vbr = (stream->strh->samplesize == 0) + && stream->strh->scale > 1; + res = + gst_riff_parse_strf_auds (element, sub, &stream->strf.auds, + &stream->extradata); + GST_DEBUG_OBJECT (element, "marking audio as VBR:%d, res %d", + stream->is_vbr, res); + break; + case GST_RIFF_FCC_iavs: + stream->is_vbr = TRUE; + res = gst_riff_parse_strf_iavs (element, sub, + &stream->strf.iavs, &stream->extradata); + GST_DEBUG_OBJECT (element, "marking iavs as VBR, res %d", res); + break; + default: + GST_ERROR_OBJECT (avi, + "Don´t know how to handle stream type %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (stream->strh->type)); + break; + } + if (!res) + goto fail; + got_strf = TRUE; + break; + } case GST_RIFF_TAG_strd: if (stream->initdata) gst_buffer_unref (stream->initdata); @@ -1260,6 +1261,16 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf) } } + if (!got_strh) { + GST_ERROR_OBJECT (avi, "Failed to find strh chunk"); + goto fail; + } + + if (!got_strf) { + GST_ERROR_OBJECT (avi, "Failed to find strf chunk"); + goto fail; + } + /* get class to figure out the template */ klass = GST_ELEMENT_GET_CLASS (avi); @@ -2410,8 +2421,10 @@ gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event) for (i = 0; i < avi->num_streams; i++) { avi_stream_context *stream = &avi->stream[i]; - gst_event_ref (event); - result &= gst_pad_push_event (stream->pad, event); + if (stream->pad) { + gst_event_ref (event); + result &= gst_pad_push_event (stream->pad, event); + } } } else { /* return error, as the event was not send */ |