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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1021>
This commit is contained in:
parent
e700a21993
commit
dd425fe0fd
@ -218,8 +218,7 @@
|
|||||||
* GstDashDemuxStream->actual_position.
|
* GstDashDemuxStream->actual_position.
|
||||||
*
|
*
|
||||||
* The downstream position of the pipeline is obtained via QoS events and
|
* The downstream position of the pipeline is obtained via QoS events and
|
||||||
* is stored in GstAdaptiveDemuxStream->qos_earliest_time (note: it's a
|
* is stored in GstAdaptiveDemux (note: it's a running time value).
|
||||||
* running time value).
|
|
||||||
*
|
*
|
||||||
* The estimated buffering level between dashdemux and downstream is
|
* The estimated buffering level between dashdemux and downstream is
|
||||||
* therefore:
|
* therefore:
|
||||||
@ -1764,6 +1763,7 @@ gst_dash_demux_stream_get_target_time (GstDashDemux * dashdemux,
|
|||||||
GstClockTimeDiff diff;
|
GstClockTimeDiff diff;
|
||||||
GstClockTime ret = cur_position;
|
GstClockTime ret = cur_position;
|
||||||
GstClockTime deadline;
|
GstClockTime deadline;
|
||||||
|
GstClockTime upstream_earliest_time;
|
||||||
GstClockTime earliest_time = GST_CLOCK_TIME_NONE;
|
GstClockTime earliest_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
g_assert (min_skip > 0);
|
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
|
* flush, as otherwise base_time and clock might not be correct because of a
|
||||||
* still pre-rolling sink
|
* 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;
|
GstClock *clock;
|
||||||
|
|
||||||
clock = gst_element_get_clock (GST_ELEMENT_CAST (dashdemux));
|
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);
|
gst_object_unref (clock);
|
||||||
|
|
||||||
earliest_time = MAX (now_time, stream->qos_earliest_time);
|
earliest_time = MAX (now_time, upstream_earliest_time);
|
||||||
} else {
|
} else {
|
||||||
earliest_time = stream->qos_earliest_time;
|
earliest_time = upstream_earliest_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,8 @@ struct _GstAdaptiveDemuxPrivate
|
|||||||
* without needing to stop tasks when they just want to
|
* without needing to stop tasks when they just want to
|
||||||
* update the segment boundaries */
|
* update the segment boundaries */
|
||||||
GMutex segment_lock;
|
GMutex segment_lock;
|
||||||
|
|
||||||
|
GstClockTime qos_earliest_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstAdaptiveDemuxTimer
|
typedef struct _GstAdaptiveDemuxTimer
|
||||||
@ -1203,12 +1205,12 @@ gst_adaptive_demux_prepare_streams (GstAdaptiveDemux * demux,
|
|||||||
|
|
||||||
stream->pending_segment = gst_event_new_segment (&stream->segment);
|
stream->pending_segment = gst_event_new_segment (&stream->segment);
|
||||||
gst_event_set_seqnum (stream->pending_segment, demux->priv->segment_seqnum);
|
gst_event_set_seqnum (stream->pending_segment, demux->priv->segment_seqnum);
|
||||||
stream->qos_earliest_time = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Prepared segment %" GST_SEGMENT_FORMAT " for stream %p",
|
"Prepared segment %" GST_SEGMENT_FORMAT " for stream %p",
|
||||||
&stream->segment, stream);
|
&stream->segment, stream);
|
||||||
}
|
}
|
||||||
|
demux->priv->qos_earliest_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1526,8 +1528,8 @@ gst_adaptive_demux_update_streams_segment (GstAdaptiveDemux * demux,
|
|||||||
gst_event_unref (seg_evt);
|
gst_event_unref (seg_evt);
|
||||||
/* Make sure the first buffer after a seek has the discont flag */
|
/* Make sure the first buffer after a seek has the discont flag */
|
||||||
stream->discont = TRUE;
|
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 | \
|
#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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case GST_EVENT_QOS:{
|
case GST_EVENT_QOS:{
|
||||||
GstAdaptiveDemuxStream *stream;
|
|
||||||
|
|
||||||
GST_MANIFEST_LOCK (demux);
|
|
||||||
stream = gst_adaptive_demux_find_stream_for_pad (demux, pad);
|
|
||||||
|
|
||||||
if (stream) {
|
|
||||||
GstClockTimeDiff diff;
|
GstClockTimeDiff diff;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
|
||||||
gst_event_parse_qos (event, NULL, NULL, &diff, ×tamp);
|
gst_event_parse_qos (event, NULL, NULL, &diff, ×tamp);
|
||||||
/* Only take into account lateness if late */
|
/* Only take into account lateness if late */
|
||||||
|
GST_OBJECT_LOCK (demux);
|
||||||
if (diff > 0)
|
if (diff > 0)
|
||||||
stream->qos_earliest_time = timestamp + 2 * diff;
|
demux->priv->qos_earliest_time = timestamp + 2 * diff;
|
||||||
else
|
else
|
||||||
stream->qos_earliest_time = timestamp;
|
demux->priv->qos_earliest_time = timestamp;
|
||||||
GST_DEBUG_OBJECT (stream->pad, "qos_earliest_time %" GST_TIME_FORMAT,
|
GST_OBJECT_UNLOCK (demux);
|
||||||
GST_TIME_ARGS (stream->qos_earliest_time));
|
GST_DEBUG_OBJECT (demux, "qos_earliest_time %" GST_TIME_FORMAT,
|
||||||
}
|
GST_TIME_ARGS (demux->priv->qos_earliest_time));
|
||||||
GST_MANIFEST_UNLOCK (demux);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2197,10 +2193,10 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates)
|
|||||||
|
|
||||||
stream->download_error_count = 0;
|
stream->download_error_count = 0;
|
||||||
stream->need_header = TRUE;
|
stream->need_header = TRUE;
|
||||||
stream->qos_earliest_time = GST_CLOCK_TIME_NONE;
|
|
||||||
}
|
}
|
||||||
list_to_process = demux->prepared_streams;
|
list_to_process = demux->prepared_streams;
|
||||||
}
|
}
|
||||||
|
demux->priv->qos_earliest_time = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must be called with manifest_lock taken */
|
/* must be called with manifest_lock taken */
|
||||||
@ -4659,3 +4655,22 @@ gst_adaptive_demux_clock_callback (GstClock * clock,
|
|||||||
g_mutex_unlock (timer->mutex);
|
g_mutex_unlock (timer->mutex);
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
@ -184,7 +184,7 @@ struct _GstAdaptiveDemuxStream
|
|||||||
guint moving_index;
|
guint moving_index;
|
||||||
guint64 *fragment_bitrates;
|
guint64 *fragment_bitrates;
|
||||||
|
|
||||||
/* QoS data */
|
/* QoS data : UNUSED !!! */
|
||||||
GstClockTime qos_earliest_time;
|
GstClockTime qos_earliest_time;
|
||||||
|
|
||||||
GstAdaptiveDemuxStreamFragment fragment;
|
GstAdaptiveDemuxStreamFragment fragment;
|
||||||
@ -532,6 +532,9 @@ GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux);
|
|||||||
GST_ADAPTIVE_DEMUX_API
|
GST_ADAPTIVE_DEMUX_API
|
||||||
gboolean gst_adaptive_demux_is_running (GstAdaptiveDemux * demux);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user