adaptivedemux: Store QoS values on the element
authorEdward Hervey <edward@centricular.com>
Mon, 9 Nov 2020 10:41:10 +0000 (11:41 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 11 Nov 2020 20:18:11 +0000 (20:18 +0000)
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1021>

ext/dash/gstdashdemux.c
gst-libs/gst/adaptivedemux/gstadaptivedemux.c
gst-libs/gst/adaptivedemux/gstadaptivedemux.h

index 8aecfaf..93980b0 100644 (file)
  * 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;
     }
   }
 
index e74a009..26235d2 100644 (file)
@@ -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;
-
-      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, &timestamp);
-        /* 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);
+      GstClockTimeDiff diff;
+      GstClockTime timestamp;
+
+      gst_event_parse_qos (event, NULL, NULL, &diff, &timestamp);
+      /* 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;
+}
index 9de70da..61e0f0c 100644 (file)
@@ -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