video: Don't overshoot QoS earliest time by a factor of 2

By setting the earliest time to timestamp + 2 * diff there would be a difference
of 1 * diff between the current clock time and the earliest time the element
would let through in the future. If e.g. a frame is arriving 30s late at the
sink, then not just all frames up to that point would be dropped but also 30s of
frames after the current clock time.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7459>
This commit is contained in:
Sebastian Dröge 2024-09-05 22:07:24 +03:00 committed by GStreamer Marge Bot
parent cd5d03811d
commit 396ef0cbcf
10 changed files with 19 additions and 14 deletions

View file

@ -1917,7 +1917,7 @@ gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
gst_event_parse_qos (event, NULL, NULL, &diff, &timestamp);
/* Only take into account lateness if late */
if (diff > 0)
earliest_time = timestamp + 2 * diff;
earliest_time = timestamp + MIN (2 * diff, GST_SECOND);
else
earliest_time = timestamp;

View file

@ -1264,7 +1264,7 @@ gst_audio_visualizer_src_event (GstPad * pad, GstObject * parent,
if (diff >= 0)
/* we're late, this is a good estimate for next displayable
* frame (see part-qos.txt) */
scope->priv->earliest_time = timestamp + 2 * diff +
scope->priv->earliest_time = timestamp + MIN (2 * diff, GST_SECOND) +
scope->priv->frame_duration;
else
scope->priv->earliest_time = timestamp + diff;

View file

@ -1667,7 +1667,8 @@ gst_video_aggregator_update_qos (GstVideoAggregator * vagg, gdouble proportion,
if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
if (!live && G_UNLIKELY (diff > 0))
vagg->priv->earliest_time =
timestamp + 2 * diff + gst_util_uint64_scale_int_round (GST_SECOND,
timestamp + MIN (2 * diff,
GST_SECOND) + gst_util_uint64_scale_int_round (GST_SECOND,
GST_VIDEO_INFO_FPS_D (&vagg->info),
GST_VIDEO_INFO_FPS_N (&vagg->info));
else

View file

@ -1834,7 +1834,8 @@ gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
priv->proportion = proportion;
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
if (G_UNLIKELY (diff > 0)) {
priv->earliest_time = timestamp + 2 * diff + priv->qos_frame_duration;
priv->earliest_time =
timestamp + MIN (2 * diff, GST_SECOND) + priv->qos_frame_duration;
} else {
priv->earliest_time = timestamp + diff;
}

View file

@ -1372,7 +1372,8 @@ gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
priv->proportion = proportion;
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
if (G_UNLIKELY (diff > 0)) {
priv->earliest_time = timestamp + 2 * diff + priv->qos_frame_duration;
priv->earliest_time =
timestamp + MIN (2 * diff, GST_SECOND) + priv->qos_frame_duration;
} else {
priv->earliest_time = timestamp + diff;
}
@ -2172,7 +2173,7 @@ gst_video_encoder_release_frame_unlocked (GstVideoEncoder * enc,
* @encoder: a #GstVideoEncoder
* @frame: (transfer full): a #GstVideoCodecFrame
*
* Removes @frame from list of pending frames and releases it, similar
* Removes @frame from list of pending frames and releases it, similar
* to calling gst_video_encoder_finish_frame() without a buffer attached
* to the frame, but does not post a QoS message or do any additional
* processing. Events from @frame are moved to the pending events list.
@ -2198,11 +2199,11 @@ gst_video_encoder_release_frame (GstVideoEncoder * enc,
* @encoder: a #GstVideoEncoder
* @frame: (transfer full): a #GstVideoCodecFrame
*
* Removes @frame from the list of pending frames, releases it
* Removes @frame from the list of pending frames, releases it
* and posts a QoS message with the frame's details on the bus.
* Similar to calling gst_video_encoder_finish_frame() without a buffer
* Similar to calling gst_video_encoder_finish_frame() without a buffer
* attached to @frame, but this function additionally stores events
* from @frame as pending, to be pushed out alongside the next frame
* from @frame as pending, to be pushed out alongside the next frame
* submitted via gst_video_encoder_finish_frame().
*
* Since: 1.26

View file

@ -2561,7 +2561,7 @@ gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
gst_event_parse_qos (event, NULL, NULL, &diff, &timestamp);
/* Only take into account lateness if late */
if (diff > 0)
earliest_time = timestamp + 2 * diff;
earliest_time = timestamp + MIN (2 * diff, GST_SECOND);
else
earliest_time = timestamp;

View file

@ -1288,7 +1288,7 @@ gst_deinterlace_update_qos (GstDeinterlace * self, gdouble proportion,
if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
if (G_UNLIKELY (diff > 0))
self->earliest_time =
timestamp + 2 * diff + ((self->fields ==
timestamp + MIN (2 * diff, GST_SECOND) + ((self->fields ==
GST_DEINTERLACE_ALL) ? self->field_duration : 2 *
self->field_duration);
else

View file

@ -534,7 +534,7 @@ gst_monoscope_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
/* we're late, this is a good estimate for next displayable
* frame (see part-qos.txt) */
monoscope->earliest_time =
timestamp + 2 * diff + monoscope->frame_duration;
timestamp + MIN (2 * diff, GST_SECOND) + monoscope->frame_duration;
else
monoscope->earliest_time = timestamp + diff;
GST_OBJECT_UNLOCK (monoscope);

View file

@ -695,7 +695,8 @@ gst_shape_wipe_update_qos (GstShapeWipe * self, gdouble proportion,
self->proportion = proportion;
if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
if (G_UNLIKELY (diff > 0))
self->earliest_time = timestamp + 2 * diff + self->frame_duration;
self->earliest_time =
timestamp + MIN (2 * diff, GST_SECOND) + self->frame_duration;
else
self->earliest_time = timestamp + diff;
} else {

View file

@ -816,7 +816,8 @@ gst_videomixer2_update_qos (GstVideoMixer2 * mix, gdouble proportion,
if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
if (!mix->live && G_UNLIKELY (diff > 0))
mix->earliest_time =
timestamp + 2 * diff + gst_util_uint64_scale_int_round (GST_SECOND,
timestamp + MIN (2 * diff,
GST_SECOND) + gst_util_uint64_scale_int_round (GST_SECOND,
GST_VIDEO_INFO_FPS_D (&mix->info), GST_VIDEO_INFO_FPS_N (&mix->info));
else
mix->earliest_time = timestamp + diff;