diff options
author | Nicola Murino <nicola.murino@gmail.com> | 2016-11-21 11:48:58 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-11-21 13:38:08 +0200 |
commit | 0ef3a71b89c7448da1ad0a19c60f99e0e8be74bd (patch) | |
tree | a6fb89a8daea4d00918b2df2995bdd1e26c7873c | |
parent | 20ed9e823731cc93f8583440d2718385f40258b0 (diff) | |
download | gstreamer-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.c | 45 |
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")); |