summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Murino <nicola.murino@gmail.com>2016-11-21 11:48:58 +0100
committerSebastian Dröge <sebastian@centricular.com>2016-11-21 13:38:08 +0200
commit0ef3a71b89c7448da1ad0a19c60f99e0e8be74bd (patch)
treea6fb89a8daea4d00918b2df2995bdd1e26c7873c
parent20ed9e823731cc93f8583440d2718385f40258b0 (diff)
downloadgstreamer-plugins-good-0ef3a71b89c7448da1ad0a19c60f99e0e8be74bd.tar.gz
matroskademux: add support for skipping invalid data in push mode
https://bugzilla.gnome.org/show_bug.cgi?id=774566
-rw-r--r--gst/matroska/matroska-demux.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index bceda520e..ae787453b 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -87,6 +87,7 @@ enum
};
#define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
+#define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -4375,8 +4376,21 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
break;
case GST_MATROSKA_READ_STATE_SCANNING:
if (id != GST_MATROSKA_ID_CLUSTER &&
- id != GST_MATROSKA_ID_CLUSTERTIMECODE)
+ id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
+ if (demux->common.start_resync_offset != -1) {
+ /* we need to skip byte per byte if we are scanning for a new cluster
+ * after invalid data is found
+ */
+ read = 1;
+ }
goto skip;
+ } else {
+ if (demux->common.start_resync_offset != -1) {
+ GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
+ demux->common.start_resync_offset = -1;
+ demux->common.state = demux->common.state_to_restore;
+ }
+ }
/* fall-through */
case GST_MATROSKA_READ_STATE_HEADER:
case GST_MATROSKA_READ_STATE_DATA:
@@ -4831,9 +4845,29 @@ next:
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;
+ demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
+ return GST_FLOW_OK;
+ } else {
+ gint64 bytes_scanned;
+ if (demux->common.start_resync_offset == -1) {
+ demux->common.start_resync_offset = demux->common.offset;
+ demux->common.state_to_restore = demux->common.state;
+ }
+ bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
+ if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
+ GST_WARNING_OBJECT (demux,
+ "parse error, looking for next cluster, actual offset %"
+ G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
+ demux->common.offset, demux->common.start_resync_offset);
+ demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
+ ret = GST_FLOW_OK;
+ } else {
+ GST_WARNING_OBJECT (demux,
+ "unrecoverable parse error, next cluster not found and threshold "
+ "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
+ return ret;
+ }
+ }
}
GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
@@ -4927,7 +4961,8 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
}
case GST_EVENT_EOS:
{
- if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
+ if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
+ && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
gst_event_unref (event);
GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
(NULL), ("got eos and didn't receive a complete header object"));