From dd425fe0fdfef6d24ee8ac8b59dc1a6e1858cabd Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 9 Nov 2020 11:41:10 +0100 Subject: [PATCH] adaptivedemux: Store QoS values on the element Storing it per-stream requires taking the manifest lock which can apparenly be hold for aeons. And since the QoS event comes from the video rendering thread we *really* do not want to do that. Storing it as-is in the element is fine, the important part is knowing the earliest time downstream. Part-of: --- ext/dash/gstdashdemux.c | 12 ++-- gst-libs/gst/adaptivedemux/gstadaptivedemux.c | 57 ++++++++++++------- gst-libs/gst/adaptivedemux/gstadaptivedemux.h | 5 +- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index 8aecfafa48..93980b0400 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -218,8 +218,7 @@ * GstDashDemuxStream->actual_position. * * The downstream position of the pipeline is obtained via QoS events and - * is stored in GstAdaptiveDemuxStream->qos_earliest_time (note: it's a - * running time value). + * is stored in GstAdaptiveDemux (note: it's a running time value). * * The estimated buffering level between dashdemux and downstream is * therefore: @@ -1764,6 +1763,7 @@ gst_dash_demux_stream_get_target_time (GstDashDemux * dashdemux, GstClockTimeDiff diff; GstClockTime ret = cur_position; GstClockTime deadline; + GstClockTime upstream_earliest_time; GstClockTime earliest_time = GST_CLOCK_TIME_NONE; g_assert (min_skip > 0); @@ -1785,7 +1785,9 @@ gst_dash_demux_stream_get_target_time (GstDashDemux * dashdemux, * flush, as otherwise base_time and clock might not be correct because of a * still pre-rolling sink */ - if (stream->qos_earliest_time != GST_CLOCK_TIME_NONE) { + upstream_earliest_time = + gst_adaptive_demux_get_qos_earliest_time ((GstAdaptiveDemux *) dashdemux); + if (upstream_earliest_time != GST_CLOCK_TIME_NONE) { GstClock *clock; clock = gst_element_get_clock (GST_ELEMENT_CAST (dashdemux)); @@ -1803,9 +1805,9 @@ gst_dash_demux_stream_get_target_time (GstDashDemux * dashdemux, gst_object_unref (clock); - earliest_time = MAX (now_time, stream->qos_earliest_time); + earliest_time = MAX (now_time, upstream_earliest_time); } else { - earliest_time = stream->qos_earliest_time; + earliest_time = upstream_earliest_time; } } diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c index e74a009815..26235d2de4 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c @@ -205,6 +205,8 @@ struct _GstAdaptiveDemuxPrivate * without needing to stop tasks when they just want to * update the segment boundaries */ GMutex segment_lock; + + GstClockTime qos_earliest_time; }; typedef struct _GstAdaptiveDemuxTimer @@ -1203,12 +1205,12 @@ gst_adaptive_demux_prepare_streams (GstAdaptiveDemux * demux, stream->pending_segment = gst_event_new_segment (&stream->segment); gst_event_set_seqnum (stream->pending_segment, demux->priv->segment_seqnum); - stream->qos_earliest_time = GST_CLOCK_TIME_NONE; GST_DEBUG_OBJECT (demux, "Prepared segment %" GST_SEGMENT_FORMAT " for stream %p", &stream->segment, stream); } + demux->priv->qos_earliest_time = GST_CLOCK_TIME_NONE; return TRUE; } @@ -1526,8 +1528,8 @@ gst_adaptive_demux_update_streams_segment (GstAdaptiveDemux * demux, gst_event_unref (seg_evt); /* Make sure the first buffer after a seek has the discont flag */ stream->discont = TRUE; - stream->qos_earliest_time = GST_CLOCK_TIME_NONE; } + demux->priv->qos_earliest_time = GST_CLOCK_TIME_NONE; } #define IS_SNAP_SEEK(f) (f & (GST_SEEK_FLAG_SNAP_BEFORE | \ @@ -1907,25 +1909,19 @@ gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent, return TRUE; } case GST_EVENT_QOS:{ - GstAdaptiveDemuxStream *stream; + GstClockTimeDiff diff; + GstClockTime timestamp; - GST_MANIFEST_LOCK (demux); - stream = gst_adaptive_demux_find_stream_for_pad (demux, pad); - - if (stream) { - GstClockTimeDiff diff; - GstClockTime timestamp; - - gst_event_parse_qos (event, NULL, NULL, &diff, ×tamp); - /* Only take into account lateness if late */ - if (diff > 0) - stream->qos_earliest_time = timestamp + 2 * diff; - else - stream->qos_earliest_time = timestamp; - GST_DEBUG_OBJECT (stream->pad, "qos_earliest_time %" GST_TIME_FORMAT, - GST_TIME_ARGS (stream->qos_earliest_time)); - } - GST_MANIFEST_UNLOCK (demux); + gst_event_parse_qos (event, NULL, NULL, &diff, ×tamp); + /* Only take into account lateness if late */ + GST_OBJECT_LOCK (demux); + if (diff > 0) + demux->priv->qos_earliest_time = timestamp + 2 * diff; + else + demux->priv->qos_earliest_time = timestamp; + GST_OBJECT_UNLOCK (demux); + GST_DEBUG_OBJECT (demux, "qos_earliest_time %" GST_TIME_FORMAT, + GST_TIME_ARGS (demux->priv->qos_earliest_time)); break; } default: @@ -2197,10 +2193,10 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates) stream->download_error_count = 0; stream->need_header = TRUE; - stream->qos_earliest_time = GST_CLOCK_TIME_NONE; } list_to_process = demux->prepared_streams; } + demux->priv->qos_earliest_time = GST_CLOCK_TIME_NONE; } /* must be called with manifest_lock taken */ @@ -4659,3 +4655,22 @@ gst_adaptive_demux_clock_callback (GstClock * clock, g_mutex_unlock (timer->mutex); return TRUE; } + +/** + * gst_adaptive_demux_get_qos_earliest_time: + * + * Returns: The QOS earliest time + * + * Since: 1.18 + */ +GstClockTime +gst_adaptive_demux_get_qos_earliest_time (GstAdaptiveDemux * demux) +{ + GstClockTime earliest; + + GST_OBJECT_LOCK (demux); + earliest = demux->priv->qos_earliest_time; + GST_OBJECT_UNLOCK (demux); + + return earliest; +} diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h index 9de70dafec..61e0f0c606 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h @@ -184,7 +184,7 @@ struct _GstAdaptiveDemuxStream guint moving_index; guint64 *fragment_bitrates; - /* QoS data */ + /* QoS data : UNUSED !!! */ GstClockTime qos_earliest_time; GstAdaptiveDemuxStreamFragment fragment; @@ -532,6 +532,9 @@ GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux); GST_ADAPTIVE_DEMUX_API gboolean gst_adaptive_demux_is_running (GstAdaptiveDemux * demux); +GST_ADAPTIVE_DEMUX_API +GstClockTime gst_adaptive_demux_get_qos_earliest_time (GstAdaptiveDemux *demux); + G_END_DECLS #endif