adaptivedemux: prepare for supporting seeks in live streams

Add function to allow subclasses to specify seeking range for
live streams

https://bugzilla.gnome.org/show_bug.cgi?id=725435
This commit is contained in:
Thiago Santos 2015-01-05 17:58:54 -03:00
parent fbd4cf9810
commit af78e2501c
2 changed files with 69 additions and 16 deletions

View file

@ -772,6 +772,32 @@ gst_adaptive_demux_stream_free (GstAdaptiveDemuxStream * stream)
g_free (stream);
}
static gboolean
gst_adaptive_demux_get_live_seek_range (GstAdaptiveDemux * demux,
gint64 * range_start, gint64 * range_stop)
{
GstAdaptiveDemuxClass *klass;
klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
g_return_val_if_fail (klass->get_live_seek_range, FALSE);
return klass->get_live_seek_range (demux, range_start, range_stop);
}
static gboolean
gst_adaptive_demux_can_seek (GstAdaptiveDemux * demux)
{
GstAdaptiveDemuxClass *klass;
klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
if (gst_adaptive_demux_is_live (demux)) {
return klass->get_live_seek_range != NULL;
}
return klass->seek != NULL;
}
static gboolean
gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
GstEvent * event)
@ -798,15 +824,8 @@ gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
GST_INFO_OBJECT (demux, "Received seek event");
if (demux_class->seek == NULL) {
GST_DEBUG_OBJECT (demux, "Subclass doesn't implement seeking");
return FALSE;
}
GST_MANIFEST_LOCK (demux);
if (gst_adaptive_demux_is_live (demux)) {
/* TODO not supported yet */
GST_WARNING_OBJECT (demux, "Received seek event for live stream");
if (!gst_adaptive_demux_can_seek (demux)) {
GST_MANIFEST_UNLOCK (demux);
gst_event_unref (event);
return FALSE;
@ -821,6 +840,20 @@ gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
return FALSE;
}
if (gst_adaptive_demux_is_live (demux)) {
gint64 range_start, range_stop;
if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
&range_stop)) {
gst_event_unref (event);
return FALSE;
}
if (start < range_start || start >= range_stop) {
GST_WARNING_OBJECT (demux, "Seek to invalid position");
gst_event_unref (event);
return FALSE;
}
}
seqnum = gst_event_get_seqnum (event);
GST_DEBUG_OBJECT (demux,
@ -981,6 +1014,7 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
case GST_QUERY_SEEKING:{
GstFormat fmt;
gint64 stop = -1;
gint64 start = 0;
GST_MANIFEST_LOCK (demux);
if (demux->priv->manifest_buffer == NULL) {
@ -991,16 +1025,23 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
GST_INFO_OBJECT (demux, "Received GST_QUERY_SEEKING with format %d", fmt);
if (fmt == GST_FORMAT_TIME) {
gboolean can_seek = demux_class->seek
&& !gst_adaptive_demux_is_live (demux);
GstClockTime duration;
duration = demux_class->get_duration (demux);
if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0)
stop = duration;
gst_query_set_seeking (query, fmt, can_seek, 0, stop);
gboolean can_seek = gst_adaptive_demux_can_seek (demux);
ret = TRUE;
GST_INFO_OBJECT (demux, "GST_QUERY_SEEKING returning with stop : %"
GST_TIME_FORMAT, GST_TIME_ARGS (stop));
if (can_seek) {
if (gst_adaptive_demux_is_live (demux)) {
ret = gst_adaptive_demux_get_live_seek_range (demux, &start, &stop);
} else {
duration = demux_class->get_duration (demux);
if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0)
stop = duration;
}
}
gst_query_set_seeking (query, fmt, can_seek, start, stop);
GST_INFO_OBJECT (demux, "GST_QUERY_SEEKING returning with start : %"
GST_TIME_FORMAT ", stop : %" GST_TIME_FORMAT,
GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
}
GST_MANIFEST_UNLOCK (demux);
break;

View file

@ -350,6 +350,18 @@ struct _GstAdaptiveDemuxClass
* Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error.
*/
GstFlowReturn (*chunk_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer ** buffer);
/**
* get_live_seek_range:
* @demux: #GstAdaptiveDemux
* @start: pointer to put the start position allowed to seek to
* @stop: pointer to put the stop position allowed to seek to
*
* Gets the allowed seek start and stop positions for the current live stream
*
* Return: %TRUE if successful
*/
gboolean (*get_live_seek_range) (GstAdaptiveDemux * demux, gint64 * start, gint64 * stop);
};
GType gst_adaptive_demux_get_type (void);