From aa51750767f722debbfbe9bda4cb59aef8901cd8 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Sun, 19 Sep 2021 17:18:09 +0200 Subject: [PATCH] avcapture: fix PTS conversion and usage CMTime is **not** equivalent to vlc_tick_t. In particular, the timescale doesn't match. So it should be converted before usage. In addition, GET_TIME is supposed to return where the access is currently reading, which should also match the timestamps of the output frames from the access. Fixes #26101 Cherry-picked from commit ca04b74fa6724c6d770cf277d97b1bfb4d18fe20. Signed-off-by: Alexandre Janniaux --- modules/access/avcapture.m | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/access/avcapture.m b/modules/access/avcapture.m index ac6d7c1e17..3e03bd1c9d 100644 --- a/modules/access/avcapture.m +++ b/modules/access/avcapture.m @@ -72,6 +72,14 @@ vlc_module_begin () set_callbacks(Open, Close) vlc_module_end () +static mtime_t vlc_CMTime_to_mtime(CMTime timestamp) +{ + CMTime scaled = CMTimeConvertScale( + timestamp, CLOCK_FREQ, + kCMTimeRoundingMethod_Default); + + return 1 + scaled.value; +} /***************************************************************************** * AVFoundation Bridge @@ -187,10 +195,11 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer CVBufferRetain(videoFrame); [self getVideoDimensions:sampleBuffer]; + @synchronized (self) { imageBufferToRelease = currentImageBuffer; currentImageBuffer = videoFrame; - currentPts = (mtime_t)presentationtimestamp.value; + currentPts = vlc_CMTime_to_mtime(presentationtimestamp); timeScale = (long)presentationtimestamp.timescale; } @@ -249,6 +258,7 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - (VLCAVCaptureDemux*)init:(demux_t *)demux; - (int)demux; +- (mtime_t)pts; - (void)dealloc; @end @@ -309,6 +319,7 @@ static int Demux(demux_t *p_demux) *****************************************************************************/ static int Control(demux_t *p_demux, int i_query, va_list args) { + VLCAVCaptureDemux *demux = (__bridge VLCAVCaptureDemux *)p_demux->p_sys; bool *pb; switch( i_query ) @@ -328,7 +339,7 @@ static int Control(demux_t *p_demux, int i_query, va_list args) return VLC_SUCCESS; case DEMUX_GET_TIME: - *va_arg(args, int64_t *) = mdate(); + *va_arg(args, mtime_t *) = [demux pts]; return VLC_SUCCESS; default: @@ -513,6 +524,11 @@ static int Control(demux_t *p_demux, int i_query, va_list args) return 1; } +- (mtime_t)pts +{ + return [_output currentPts]; +} + - (void)dealloc { // Perform this on main thread, as the framework itself will sometimes try to synchronously