qtdemux: Send instant-rate-change event if requested in the SEEK event

Handle an instant rate change seek immediately by reflecting
it downstream as an instant-rate-change event, and do no
further seek handling.
This commit is contained in:
Sebastian Dröge 2018-06-08 13:12:01 +03:00 committed by Seungha Yang
parent 5d0657d4ae
commit f757fbe0f7

View file

@ -1496,6 +1496,31 @@ gst_qtdemux_do_push_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
&cur_type, &cur, &stop_type, &stop); &cur_type, &cur, &stop_type, &stop);
seqnum = gst_event_get_seqnum (event); seqnum = gst_event_get_seqnum (event);
/* Directly send the instant-rate-change event here before taking the
* stream-lock so that it can be applied as soon as possible */
if (flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE) {
GstEvent *ev;
/* instant rate change only supported if direction does not change. All
* other requirements are already checked before creating the seek event
* but let's double-check here to be sure */
if ((qtdemux->segment.rate > 0 && rate < 0) ||
(qtdemux->segment.rate < 0 && rate > 0) ||
cur_type != GST_SEEK_TYPE_NONE ||
stop_type != GST_SEEK_TYPE_NONE || (flags & GST_SEEK_FLAG_FLUSH)) {
GST_ERROR_OBJECT (qtdemux,
"Instant rate change seeks only supported in the "
"same direction, without flushing and position change");
return FALSE;
}
ev = gst_event_new_instant_rate_change (rate / qtdemux->segment.rate,
(GstSegmentFlags) flags);
gst_event_set_seqnum (ev, seqnum);
gst_qtdemux_push_event (qtdemux, ev);
return TRUE;
}
/* only forward streaming and seeking is possible */ /* only forward streaming and seeking is possible */
if (rate <= 0) if (rate <= 0)
goto unsupported_seek; goto unsupported_seek;
@ -1658,12 +1683,12 @@ gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment,
static gboolean static gboolean
gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event) gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
{ {
gdouble rate; gdouble rate = 1.0;
GstFormat format; GstFormat format;
GstSeekFlags flags; GstSeekFlags flags;
GstSeekType cur_type, stop_type; GstSeekType cur_type, stop_type;
gint64 cur, stop; gint64 cur, stop;
gboolean flush; gboolean flush, instant_rate_change;
gboolean update; gboolean update;
GstSegment seeksegment; GstSegment seeksegment;
guint32 seqnum = GST_SEQNUM_INVALID; guint32 seqnum = GST_SEQNUM_INVALID;
@ -1684,7 +1709,33 @@ gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (qtdemux, "seek format %s", gst_format_get_name (format)); GST_DEBUG_OBJECT (qtdemux, "seek format %s", gst_format_get_name (format));
flush = flags & GST_SEEK_FLAG_FLUSH; flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
instant_rate_change = ! !(flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE);
/* Directly send the instant-rate-change event here before taking the
* stream-lock so that it can be applied as soon as possible */
if (instant_rate_change) {
GstEvent *ev;
/* instant rate change only supported if direction does not change. All
* other requirements are already checked before creating the seek event
* but let's double-check here to be sure */
if ((qtdemux->segment.rate > 0 && rate < 0) ||
(qtdemux->segment.rate < 0 && rate > 0) ||
cur_type != GST_SEEK_TYPE_NONE ||
stop_type != GST_SEEK_TYPE_NONE || flush) {
GST_ERROR_OBJECT (qtdemux,
"Instant rate change seeks only supported in the "
"same direction, without flushing and position change");
return FALSE;
}
ev = gst_event_new_instant_rate_change (rate / qtdemux->segment.rate,
(GstSegmentFlags) flags);
gst_event_set_seqnum (ev, seqnum);
gst_qtdemux_push_event (qtdemux, ev);
return TRUE;
}
/* stop streaming, either by flushing or by pausing the task */ /* stop streaming, either by flushing or by pausing the task */
if (flush) { if (flush) {
@ -1793,6 +1844,9 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
break; break;
case GST_EVENT_SEEK: case GST_EVENT_SEEK:
{ {
GstSeekFlags flags = 0;
gboolean instant_rate_change;
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
GstClockTime ts = gst_util_get_timestamp (); GstClockTime ts = gst_util_get_timestamp ();
#endif #endif
@ -1800,6 +1854,9 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
qtdemux->received_seek = TRUE; qtdemux->received_seek = TRUE;
gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
instant_rate_change = ! !(flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE);
if (seqnum == qtdemux->segment_seqnum) { if (seqnum == qtdemux->segment_seqnum) {
GST_LOG_OBJECT (pad, GST_LOG_OBJECT (pad,
"Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum); "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
@ -1818,16 +1875,17 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
&qtdemux->trickmode_interval); &qtdemux->trickmode_interval);
/* Build complete index for seeking; /* Build complete index for seeking;
* if not a fragmented file at least */ * if not a fragmented file at least and we're really doing a seek,
if (!qtdemux->fragmented) * not just an instant-rate-change */
if (!qtdemux->fragmented && !instant_rate_change) {
if (!qtdemux_ensure_index (qtdemux)) if (!qtdemux_ensure_index (qtdemux))
goto index_failed; goto index_failed;
}
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
ts = gst_util_get_timestamp () - ts; ts = gst_util_get_timestamp () - ts;
GST_INFO_OBJECT (qtdemux, GST_INFO_OBJECT (qtdemux,
"Time taken to parse index %" GST_TIME_FORMAT, GST_TIME_ARGS (ts)); "Time taken to parse index %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
#endif #endif
}
if (qtdemux->pullbased) { if (qtdemux->pullbased) {
res = gst_qtdemux_do_seek (qtdemux, pad, event); res = gst_qtdemux_do_seek (qtdemux, pad, event);
} else if (gst_pad_push_event (qtdemux->sinkpad, gst_event_ref (event))) { } else if (gst_pad_push_event (qtdemux->sinkpad, gst_event_ref (event))) {
@ -1843,6 +1901,7 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
res = FALSE; res = FALSE;
} }
gst_event_unref (event); gst_event_unref (event);
}
break; break;
default: default:
upstream: upstream: