From: jiyong.min Date: Mon, 13 Feb 2023 05:39:45 +0000 (+0900) Subject: avvidenc: Don't take ffmpeg timestamps verbatim but only use them to calculate DTS X-Git-Tag: accepted/tizen/unified/20230215.155637~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47da9736872f5cc66e16e5a92316258687e5dc6e;p=platform%2Fupstream%2Fgstreamer.git avvidenc: Don't take ffmpeg timestamps verbatim but only use them to calculate DTS The ffmpeg timestamps are inaccurate and only in framerate granularity. To avoid generating inaccurate output timestamps, especially with variable framerate streams, only use the ffmpeg timestamps for calculating the DTS. Fixes #1544(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1544) again. Part-of: Change-Id: I7bf166986e5fc9b9a43a62eb32c496d4459cd445 --- diff --git a/packaging/gstreamer.spec b/packaging/gstreamer.spec index a4ea0a943e..a9bbaf5f78 100644 --- a/packaging/gstreamer.spec +++ b/packaging/gstreamer.spec @@ -62,7 +62,7 @@ Name: %{_name} Version: 1.22.0 -Release: 8 +Release: 9 Summary: Streaming-Media Framework Runtime License: LGPL-2.0+ Group: Multimedia/Framework diff --git a/subprojects/gst-libav/ext/libav/gstavvidenc.c b/subprojects/gst-libav/ext/libav/gstavvidenc.c index 34d4165a2e..4689959066 100644 --- a/subprojects/gst-libav/ext/libav/gstavvidenc.c +++ b/subprojects/gst-libav/ext/libav/gstavvidenc.c @@ -717,19 +717,25 @@ gst_ffmpegvidenc_receive_packet (GstFFMpegVidEnc * ffmpegenc, GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame); } - if (pkt->dts != AV_NOPTS_VALUE) { - frame->dts = - gst_ffmpeg_time_ff_to_gst (pkt->dts + ffmpegenc->pts_offset, - ffmpegenc->context->time_base); - } - /* This will lose some precision compared to setting the PTS from the input - * buffer directly, but that way we're sure PTS and DTS are consistent, in - * particular DTS should always be <= PTS + /* calculate the DTS by taking the PTS/DTS difference from the ffmpeg side + * and applying it to our PTS. We don't use the ffmpeg timestamps verbatim + * because they're too inaccurate and in the framerate time_base */ - if (pkt->pts != AV_NOPTS_VALUE) { - frame->pts = - gst_ffmpeg_time_ff_to_gst (pkt->pts + ffmpegenc->pts_offset, - ffmpegenc->context->time_base); + if (pkt->dts != AV_NOPTS_VALUE) { + gint64 pts_dts_diff = pkt->dts - pkt->pts; + if (pts_dts_diff < 0) { + GstClockTime gst_pts_dts_diff = gst_ffmpeg_time_ff_to_gst (-pts_dts_diff, + ffmpegenc->context->time_base); + + if (gst_pts_dts_diff > frame->pts) + frame->pts = 0; + else + frame->dts = frame->pts - gst_pts_dts_diff; + } else { + frame->dts = frame->pts + + gst_ffmpeg_time_ff_to_gst (pts_dts_diff, + ffmpegenc->context->time_base); + } } ret = gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (ffmpegenc), frame);