summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-09-04 16:21:20 +0300
committerSebastian Dröge <sebastian@centricular.com>2014-09-11 17:09:41 +0300
commit249dd95d59387bc3fc37502c8080b94478151c4b (patch)
treeafe92d8a7dac4a6075129b2674588d4f1fadd49f
parentc19bcb6c60b4cd6d4f48b2a5ac522ac31d2c0da2 (diff)
matroska-demux: Don't handle parse errors at the end of file as an error
But only if they happen after the Matroska segment. https://bugzilla.gnome.org/show_bug.cgi?id=735833
-rw-r--r--gst/matroska/matroska-demux.c35
-rw-r--r--gst/matroska/matroska-read-common.h3
2 files changed, 28 insertions, 10 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index adef916bc..37b39eb92 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -3890,7 +3890,7 @@ gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
}
/* returns TRUE if we truely are in error state, and should give up */
-static inline gboolean
+static inline GstFlowReturn
gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
{
if (!demux->streaming && demux->next_cluster_offset > 0) {
@@ -3899,22 +3899,23 @@ gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
G_GUINT64_FORMAT, demux->next_cluster_offset);
demux->common.offset = demux->next_cluster_offset;
demux->next_cluster_offset = 0;
- return FALSE;
+ return GST_FLOW_OK;
} else {
gint64 pos;
+ GstFlowReturn ret;
/* sigh, one last attempt above and beyond call of duty ...;
* search for cluster mark following current pos */
pos = demux->common.offset;
GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
- if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
+ if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
/* did not work, give up */
- return TRUE;
+ return ret;
} else {
GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
/* try that position */
demux->common.offset = pos;
- return FALSE;
+ return GST_FLOW_OK;
}
}
}
@@ -4113,11 +4114,14 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
/* eat segment prefix */
GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
GST_DEBUG_OBJECT (demux,
- "Found Segment start at offset %" G_GUINT64_FORMAT,
- demux->common.offset);
+ "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
+ G_GUINT64_FORMAT, demux->common.offset, length);
/* seeks are from the beginning of the segment,
* after the segment ID/length */
demux->common.ebml_segment_start = demux->common.offset;
+ if (length == 0)
+ length = G_MAXUINT64;
+ demux->common.ebml_segment_length = length;
demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
break;
default:
@@ -4385,7 +4389,15 @@ gst_matroska_demux_loop (GstPad * pad)
} else if (ret == GST_FLOW_FLUSHING) {
goto pause;
} else if (ret != GST_FLOW_OK) {
- if (gst_matroska_demux_check_parse_error (demux))
+ ret = gst_matroska_demux_check_parse_error (demux);
+
+ /* Only handle EOS as no error if we're outside the segment already */
+ if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
+ && demux->common.offset >=
+ demux->common.ebml_segment_start +
+ demux->common.ebml_segment_length))
+ goto eos;
+ else if (ret != GST_FLOW_OK)
goto pause;
else
return;
@@ -4552,8 +4564,13 @@ next:
ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
GST_ELEMENT_CAST (demux), &id, &length, &needed);
- if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
+ if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
+ if (demux->common.ebml_segment_length != G_MAXUINT64
+ && demux->common.offset >=
+ demux->common.ebml_segment_start + demux->common.ebml_segment_length)
+ ret = GST_FLOW_EOS;
return ret;
+ }
GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
"size %" G_GUINT64_FORMAT ", needed %d, available %d",
diff --git a/gst/matroska/matroska-read-common.h b/gst/matroska/matroska-read-common.h
index be0329648..6495e831a 100644
--- a/gst/matroska/matroska-read-common.h
+++ b/gst/matroska/matroska-read-common.h
@@ -76,8 +76,9 @@ typedef struct _GstMatroskaReadCommon {
GstToc *toc;
gboolean toc_updated;
- /* start-of-segment */
+ /* start-of-segment and length */
guint64 ebml_segment_start;
+ guint64 ebml_segment_length;
/* a cue (index) table */
GArray *index;