From aa3b6a11e076b609163b7454bea990e65cb5a9e7 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Wed, 11 May 2022 16:20:42 +0200 Subject: [PATCH] vpxenc: enforce strictly increasing pts From vpx_codec_encode() documentation: "The presentation time stamp (PTS) MUST be strictly increasing." Part-of: --- subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c | 26 ++++++++++++++++++++++-- subprojects/gst-plugins-good/ext/vpx/gstvpxenc.h | 3 +++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c b/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c index 69d8475..569a9f0 100644 --- a/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c +++ b/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c @@ -1611,6 +1611,10 @@ gst_vpx_enc_destroy_encoder (GstVPXEnc * encoder) encoder->cfg.rc_twopass_stats_in.buf = NULL; encoder->cfg.rc_twopass_stats_in.sz = 0; } + + encoder->last_pts = GST_CLOCK_TIME_NONE; + encoder->last_input_duration = GST_CLOCK_TIME_NONE; + g_mutex_unlock (&encoder->encoder_lock); } @@ -1735,6 +1739,8 @@ gst_vpx_enc_set_format (GstVideoEncoder * video_encoder, vpx_codec_destroy (&encoder->encoder); encoder->inited = FALSE; encoder->multipass_cache_idx++; + encoder->last_pts = GST_CLOCK_TIME_NONE; + encoder->last_input_duration = GST_CLOCK_TIME_NONE; } else { g_mutex_lock (&encoder->encoder_lock); } @@ -2128,14 +2134,20 @@ gst_vpx_enc_drain (GstVideoEncoder * video_encoder) vpx_codec_err_t status; gint64 deadline; vpx_codec_pts_t pts; + GstClockTime gst_pts = 0; encoder = GST_VPX_ENC (video_encoder); g_mutex_lock (&encoder->encoder_lock); deadline = encoder->deadline; + if (GST_CLOCK_TIME_IS_VALID (encoder->last_pts)) + gst_pts = encoder->last_pts; + if (GST_CLOCK_TIME_IS_VALID (encoder->last_input_duration)) + gst_pts += encoder->last_input_duration; + pts = - gst_util_uint64_scale (encoder->last_pts, + gst_util_uint64_scale (gst_pts, encoder->cfg.g_timebase.den, encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND); @@ -2265,6 +2277,16 @@ gst_vpx_enc_handle_frame (GstVideoEncoder * video_encoder, gst_segment_to_running_time (&video_encoder->input_segment, GST_FORMAT_TIME, frame->pts); + /* vpx_codec_encode() enforces us to pass strictly increasing pts */ + if (GST_CLOCK_TIME_IS_VALID (encoder->last_pts) + && pts_rt <= encoder->last_pts) { + GST_WARNING_OBJECT (encoder, + "decreasing pts %" GST_TIME_FORMAT " previous buffer was %" + GST_TIME_FORMAT " enforce increasing pts", GST_TIME_ARGS (pts_rt), + GST_TIME_ARGS (encoder->last_pts)); + pts_rt = encoder->last_pts + 1; + } + pts = gst_util_uint64_scale (pts_rt, encoder->cfg.g_timebase.den, @@ -2277,7 +2299,7 @@ gst_vpx_enc_handle_frame (GstVideoEncoder * video_encoder, encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND); if (duration > 0) { - encoder->last_pts += frame->duration; + encoder->last_input_duration = frame->duration; } else { /* We force the path ignoring the duration if we end up with a zero * value for duration after scaling (e.g. duration value too small) */ diff --git a/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.h b/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.h index fbf6d67..ad458f2 100644 --- a/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.h +++ b/subprojects/gst-plugins-good/ext/vpx/gstvpxenc.h @@ -114,7 +114,10 @@ struct _GstVPXEnc vpx_image_t image; + /* last input pts, in running time */ GstClockTime last_pts; + /* duration of the last input buffer */ + GstClockTime last_input_duration; GstVideoCodecState *input_state; }; -- 2.7.4