videoencoder: Use the correct segment and buffer timestamp in the chain function

The only thing that can be used in the chain function is the input segment. The
output segment might not be available at all yet or out of sync with the current
input segment.

Also because of that, the unadjusted timestamp has to be used for the
calculations as the adjustment is only part of the output segment.

This fixes the deadline calculation and the handling of force-keyunit events for
encoders using frame reordering (i.e. setting a minimum PTS).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8842>
This commit is contained in:
Sebastian Dröge 2025-04-15 14:24:12 +03:00
parent 9adf26cfd1
commit 37629385d0

View File

@ -1549,6 +1549,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
GstClockTime pts, duration;
GstFlowReturn ret = GST_FLOW_OK;
guint64 start, stop, cstart, cstop;
guint64 cstart_adjusted;
encoder = GST_VIDEO_ENCODER (parent);
priv = encoder->priv;
@ -1597,12 +1598,14 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
}
if (priv->time_adjustment != GST_CLOCK_TIME_NONE) {
cstart += priv->time_adjustment;
cstart_adjusted = cstart + priv->time_adjustment;
} else {
cstart_adjusted = cstart;
}
/* incoming DTS is not really relevant and does not make sense anyway,
* so pass along _NONE and maybe come up with something better later on */
frame = gst_video_encoder_new_frame (encoder, buf, cstart,
frame = gst_video_encoder_new_frame (encoder, buf, cstart_adjusted,
GST_CLOCK_TIME_NONE, duration);
GST_OBJECT_LOCK (encoder);
@ -1613,7 +1616,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
GQueue matching_fevt = G_QUEUE_INIT;
running_time =
gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
gst_segment_to_running_time (&encoder->input_segment, GST_FORMAT_TIME,
cstart);
throttled = (priv->min_force_key_unit_interval != 0 &&
@ -1727,7 +1730,7 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
frame->deadline =
gst_segment_to_running_time (&encoder->input_segment, GST_FORMAT_TIME,
frame->pts);
cstart);
ret = klass->handle_frame (encoder, frame);