[PR] avcodec/videotoolboxenc: respect CMTime.timescale when computing timestamps (PR #23871)

Zhao Zhili via ffmpeg-devel <[email protected]> Wed, 22 Jul 2026 12:11:06 -0000
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178472226678.59.18303903989941819913@29965ddac10e>
PR #23871 opened by Zhao Zhili (quink)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23871
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23871.patch

# Summary of changes

vtenc_cm_to_avpacket converts output CMSampleBuffer timestamps back
to codec timebase by dividing pts.value by avctx->time_base.num.
This relies on the output CMTime having the same timescale as the
one passed to VTCompressionSessionEncodeFrame. Apple does not
guarantee this, and the output timescale can differ from the input.

Use av_rescale_q with the actual CMTime timescale so that the
conversion is correct regardless of what timescale VideoToolbox
returns.

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->



>From e7306597ca0aadb712c605df9f2bc8b9d13af503 Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Wed, 22 Jul 2026 19:35:41 +0800
Subject: [PATCH 1/2] avcodec/videotoolboxenc: check PTS validity before
 timestamp conversion

---
 libavcodec/videotoolboxenc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index de52923702..73f0ac161a 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2313,6 +2313,11 @@ static int vtenc_cm_to_avpacket(
     pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
     dts = CMSampleBufferGetDecodeTimeStamp      (sample_buffer);
 
+    if (CMTIME_IS_INVALID(pts)) {
+        av_log(avctx, AV_LOG_ERROR, "PTS is invalid.\n");
+        return AVERROR_EXTERNAL;
+    }
+
     if (CMTIME_IS_INVALID(dts)) {
         if (!vtctx->has_b_frames) {
             dts = pts;
-- 
2.52.0


>From cebb3dc13c267427089868a690d52231cf1a4ea4 Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Wed, 22 Jul 2026 17:52:15 +0800
Subject: [PATCH 2/2] avcodec/videotoolboxenc: respect CMTime.timescale when
 computing timestamps

vtenc_cm_to_avpacket converts output CMSampleBuffer timestamps back
to codec timebase by dividing pts.value by avctx->time_base.num.
This relies on the output CMTime having the same timescale as the
one passed to VTCompressionSessionEncodeFrame. Apple does not
guarantee this, and the output timescale can differ from the input.

Use av_rescale_q with the actual CMTime timescale so that the
conversion is correct regardless of what timescale VideoToolbox
returns.

Signed-off-by: Zhao Zhili <[email protected]>
---
 libavcodec/videotoolboxenc.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 73f0ac161a..85561c0479 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2221,7 +2221,6 @@ static int vtenc_cm_to_avpacket(
     size_t  out_buf_size;
     size_t  sei_nalu_size = 0;
     int64_t dts_delta;
-    int64_t time_base_num;
     int nalu_count;
     CMTime  pts;
     CMTime  dts;
@@ -2328,9 +2327,9 @@ static int vtenc_cm_to_avpacket(
     }
 
     dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
-    time_base_num = avctx->time_base.num;
-    pkt->pts = pts.value / time_base_num;
-    pkt->dts = dts.value / time_base_num - dts_delta;
+    pkt->pts = av_rescale_q(pts.value, (AVRational){1, pts.timescale}, avctx->time_base);
+    pkt->dts = av_rescale_q(dts.value, (AVRational){1, dts.timescale}, avctx->time_base)
+               - dts_delta;
 
     return 0;
 }
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]