summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-12-08 11:35:33 +0100
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-12-08 11:37:30 +0100
commit5239e19e9cb33e9072af4fc700ec9901ae67f601 (patch)
tree32155edb5b16e7606db94a360a731476205beef2
parentd2948bb259ac070dbbb8ca1e1b0341e39ce1d87a (diff)
qtdemux: fix handling near end-of-file corner cases
Also, relax some error handling to not bail out completely when something feels amiss, but consider this EOF and continue with was obtained so far.
-rw-r--r--gst/qtdemux/qtdemux.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index b174ac763..134188e04 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -1856,9 +1856,10 @@ qtdemux_parse_uuid (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
}
}
+/* caller verifies at least 8 bytes in buf */
static void
-extract_initial_length_and_fourcc (const guint8 * data, guint64 * plength,
- guint32 * pfourcc)
+extract_initial_length_and_fourcc (const guint8 * data, guint size,
+ guint64 * plength, guint32 * pfourcc)
{
guint64 length;
guint32 fourcc;
@@ -1870,7 +1871,7 @@ extract_initial_length_and_fourcc (const guint8 * data, guint64 * plength,
if (length == 0) {
length = G_MAXUINT32;
- } else if (length == 1) {
+ } else if (length == 1 && size >= 16) {
/* this means we have an extended size, which is the 64 bit value of
* the next 8 bytes */
length = QT_UINT64 (data + 8);
@@ -2537,16 +2538,18 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, 16, &buf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto beach;
- if (G_LIKELY (GST_BUFFER_SIZE (buf) == 16))
- extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), &length, &fourcc);
+ if (G_LIKELY (GST_BUFFER_SIZE (buf) >= 8))
+ extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf), &length, &fourcc);
gst_buffer_unref (buf);
+ /* maybe we already got most we needed, so only consider this eof */
if (G_UNLIKELY (length == 0)) {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
- (_("This file is invalid and cannot be played.")),
+ GST_ELEMENT_WARNING (qtdemux, STREAM, DEMUX,
+ (_("Invalid atom size.")),
("Header atom '%" GST_FOURCC_FORMAT "' has empty length",
GST_FOURCC_ARGS (fourcc)));
- ret = GST_FLOW_ERROR;
+ ret = GST_FLOW_UNEXPECTED;
goto beach;
}
@@ -3887,7 +3890,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
data = gst_adapter_peek (demux->adapter, demux->neededbytes);
/* get fourcc/length, set neededbytes */
- extract_initial_length_and_fourcc ((guint8 *) data, &size, &fourcc);
+ extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes,
+ &size, &fourcc);
GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] "
"size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size);
if (size == 0) {
@@ -3978,7 +3982,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
data = gst_adapter_peek (demux->adapter, demux->neededbytes);
/* parse the header */
- extract_initial_length_and_fourcc (data, NULL, &fourcc);
+ extract_initial_length_and_fourcc (data, demux->neededbytes, NULL,
+ &fourcc);
if (fourcc == FOURCC_moov) {
GST_DEBUG_OBJECT (demux, "Parsing [moov]");
@@ -4977,11 +4982,13 @@ qtdemux_find_atom (GstQTDemux * qtdemux, guint64 * offset,
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto locate_failed;
if (G_LIKELY (GST_BUFFER_SIZE (buf) != 16)) {
+ /* likely EOF */
+ ret = GST_FLOW_UNEXPECTED;
gst_buffer_unref (buf);
- ret = GST_FLOW_ERROR;
goto locate_failed;
}
- extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), length, &lfourcc);
+ extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), 16, length,
+ &lfourcc);
gst_buffer_unref (buf);
if (G_UNLIKELY (*length == 0)) {