matroskademux: Defer seeks received before GST_MATROSKA_READ_STATE_DATA

This patch enables matroskademux to receive seeks before it reaches
GST_MATROSKA_READ_STATE_DATA.

Closes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/514

This also enables receiving seeks in the element READY state.

When such a seek is received, it is stored to be later handled when
GST_MATROSKA_READ_STATE_DATA is reached.
This commit is contained in:
Alicia Boya García 2018-11-14 08:57:55 +01:00 committed by Sebastian Dröge
parent 8fc8b7ee33
commit 753b7c17f3
2 changed files with 36 additions and 6 deletions

View file

@ -357,6 +357,11 @@ gst_matroska_demux_reset (GstElement * element)
demux->cached_length = G_MAXUINT64; demux->cached_length = G_MAXUINT64;
if (demux->deferred_seek_event)
gst_event_unref (demux->deferred_seek_event);
demux->deferred_seek_event = NULL;
demux->deferred_seek_pad = NULL;
gst_flow_combiner_clear (demux->flowcombiner); gst_flow_combiner_clear (demux->flowcombiner);
} }
@ -1898,9 +1903,13 @@ gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) { if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
/* no seeking until we are (safely) ready */ /* no seeking until we are (safely) ready */
if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) { if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
GST_DEBUG_OBJECT (demux, "not ready for seeking yet"); GST_DEBUG_OBJECT (demux,
gst_event_unref (event); "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
return FALSE; if (demux->deferred_seek_event)
gst_event_unref (demux->deferred_seek_event);
demux->deferred_seek_event = event;
demux->deferred_seek_pad = NULL;
return TRUE;
} }
res = gst_matroska_demux_handle_seek_event (demux, NULL, event); res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
} else { } else {
@ -3009,9 +3018,14 @@ gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
case GST_EVENT_SEEK: case GST_EVENT_SEEK:
/* no seeking until we are (safely) ready */ /* no seeking until we are (safely) ready */
if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) { if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
GST_DEBUG_OBJECT (demux, "not ready for seeking yet"); GST_DEBUG_OBJECT (demux,
gst_event_unref (event); "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
return FALSE; event);
if (demux->deferred_seek_event)
gst_event_unref (demux->deferred_seek_event);
demux->deferred_seek_event = event;
demux->deferred_seek_pad = pad;
return TRUE;
} }
{ {
@ -5324,6 +5338,20 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
demux->common.offset = demux->first_cluster_offset; demux->common.offset = demux->first_cluster_offset;
} }
if (demux->deferred_seek_event) {
GstEvent *seek_event;
GstPad *seek_pad;
seek_event = demux->deferred_seek_event;
seek_pad = demux->deferred_seek_pad;
demux->deferred_seek_event = NULL;
demux->deferred_seek_pad = NULL;
GST_DEBUG_OBJECT (demux,
"Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
gst_matroska_demux_handle_seek_event (demux, seek_pad,
seek_event);
gst_event_unref (seek_event);
}
/* send initial segment - we wait till we know the first /* send initial segment - we wait till we know the first
incoming timestamp, so we can properly set the start of incoming timestamp, so we can properly set the start of
the segment. */ the segment. */

View file

@ -100,6 +100,8 @@ typedef struct _GstMatroskaDemux {
gboolean building_index; gboolean building_index;
guint64 index_offset; guint64 index_offset;
GstEvent *seek_event; GstEvent *seek_event;
GstEvent *deferred_seek_event;
GstPad *deferred_seek_pad;
gboolean need_segment; gboolean need_segment;
guint32 segment_seqnum; guint32 segment_seqnum;