tsdemux: implement seeking in push mode

This commit is contained in:
Arnaud Vrac 2013-05-24 18:18:35 +02:00 committed by Edward Hervey
parent 388c28381f
commit 024aa47f64
2 changed files with 24 additions and 10 deletions

View File

@ -1007,6 +1007,7 @@ static gboolean
mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{ {
gboolean res = TRUE; gboolean res = TRUE;
gboolean hard;
MpegTSBase *base = GST_MPEGTS_BASE (parent); MpegTSBase *base = GST_MPEGTS_BASE (parent);
GST_DEBUG_OBJECT (base, "Got event %s", GST_DEBUG_OBJECT (base, "Got event %s",
@ -1040,12 +1041,12 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
break; break;
case GST_EVENT_FLUSH_STOP: case GST_EVENT_FLUSH_STOP:
res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event); res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
mpegts_packetizer_flush (base->packetizer, TRUE); hard = (base->mode != BASE_MODE_SEEKING);
mpegts_base_flush (base, TRUE); mpegts_packetizer_flush (base->packetizer, hard);
mpegts_base_flush (base, hard);
gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
base->seen_pat = FALSE; base->seen_pat = FALSE;
break; break;
/* Passthrough */
default: default:
res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event); res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
} }
@ -1340,10 +1341,24 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
GST_DEBUG ("upstream handled SEEK event"); GST_DEBUG ("upstream handled SEEK event");
return TRUE; return TRUE;
} }
/* FIXME : Actually ... it is supported, we just need to convert
* the seek event to BYTES */ /* If the subclass can seek, do that */
GST_ERROR ("seeking in push mode not supported"); if (klass->seek) {
goto push_mode; ret = klass->seek (base, event);
if (G_UNLIKELY (ret != GST_FLOW_OK))
GST_WARNING ("seeking failed %s", gst_flow_get_name (ret));
else {
base->mode = BASE_MODE_SEEKING;
if (!gst_pad_push_event (base->sinkpad, gst_event_new_seek (rate,
GST_FORMAT_BYTES, flags,
GST_SEEK_TYPE_SET, base->seek_offset,
GST_SEEK_TYPE_NONE, -1)))
ret = GST_FLOW_ERROR;
base->mode = BASE_MODE_PUSHING;
}
}
return ret == GST_FLOW_OK;
} }
GST_DEBUG ("seek event, rate: %f start: %" GST_TIME_FORMAT GST_DEBUG ("seek event, rate: %f start: %" GST_TIME_FORMAT
@ -1404,7 +1419,7 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
done: done:
gst_pad_start_task (base->sinkpad, (GstTaskFunction) mpegts_base_loop, base, gst_pad_start_task (base->sinkpad, (GstTaskFunction) mpegts_base_loop, base,
NULL); NULL);
push_mode:
GST_PAD_STREAM_UNLOCK (base->sinkpad); GST_PAD_STREAM_UNLOCK (base->sinkpad);
return ret == GST_FLOW_OK; return ret == GST_FLOW_OK;
} }

View File

@ -460,8 +460,7 @@ gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
/* If upstream is not seekable in TIME format we use /* If upstream is not seekable in TIME format we use
* our own values here */ * our own values here */
if (!seekable) if (!seekable)
gst_query_set_seeking (query, GST_FORMAT_TIME, gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0,
demux->parent.mode != BASE_MODE_PUSHING, 0,
demux->segment.duration); demux->segment.duration);
} else { } else {
GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking"); GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking");