opengl 核心视频-显示链接I need help interpreting CVTimeStamp

iaqfqrcu  于 2023-10-18  发布在  其他
关注(0)|答案(2)|浏览(94)

核心视频Maven,我正在为.mov文件创建一个自定义视频播放器。我有.mov解析器工作,并使用QTCoreVideo 101示例,我试图播放视频。
我的问题是显示链接getFrameForTime我不知道如何使用时间值来找到正确的帧。
CVTimeStamp中包含的值对我来说没有任何意义。下面是一个1秒视频请求值的示例。谁能解释一下我如何使用这些值在.mov文件中找到正确的帧?
前三个请求-CVTimeStamp的值
1.视频时间:489150134353920.000000 hostTime:2026048145326080.000000视频时标:241500000.000000比率标量:1.000000视频刷新周期:4028320.000000
1.视频时间:489150201462784.000000 hostTime:2026048279543808.000000视频时标:241500000.000000比率标量:0.999985视频刷新周期:4028320.000000
1.视频时间:489156643913728.000000 hostTime:2026074988871680.000000 videoTimeScale:241500000.000000比率标量:1.000000视频刷新周期:4028320.000000

mlnl4t2r

mlnl4t2r1#

CVTimeStamp s在CVTimeStamp参考文档中有解释。videoTimeScale是一秒钟被划分成的单位数。因此,对于30 fps的视频,它至少需要30(尽管它可以是30 - 60,120,30000等的任何倍数)。videoTime是当前帧(或场)开始的时间。所以如果你的时基是30000,你在第15帧,你的videoTimeScale将是30000,你的videoTime将是15000。
您可以通过检查smpteTime字段并查看它是否与您期望的匹配来检查是否正确解释了该值。在上面的示例中,它将是0小时、0分钟、0秒、15帧(或00:00:00:15)。
有什么原因可以让你只使用操作系统内置的视频解码设备吗?

hc8w905p

hc8w905p2#

这是一个很好的问题,cvdisplay链接是可悲的记录不足,我不得不做了大量的阅读和实验,以弄清楚它。首先,你应该阅读http://litherum.blogspot.com/2021/05/understanding-cvdisplaylink.html,它给出了字段的一个很好的概述。正如那里所解释的,在其核心CVDisplayLink让你访问显示时钟(尽管苹果非常努力地掩盖这一事实),以及一种在它和系统单调时钟之间转换的方法。显示时钟在概念上是vsync定时的,在一个vsync之后,增加videoRefreshPeriod。
但事情比这更微妙一些。您可能认为CVDisplayLink回调在每个vsync开始时调用。不幸的是,情况并非如此。正如https://thume.ca/2017/12/09/cvdisplaylink-doesnt-link-to-your-display/和https://twitter.com/natbro/status/939857260313899008#m中所描述的,在现代osx(10.11+)上,回调实际上发生在vsync事件之间的中途。(在旧版本的OSX上,它确实接近开始)。
因此,DisplayLink的outTime参数实际上不能保证是下一个vsync的时间。相反,在现代的osx上,它是vsync * 在那之后 *。(在旧的OSX上,它实际上是下一个vsync)。我相信这个想法是,CVDisplayLink假设你将采取略低于1 vsync长度来渲染你的帧,所以因为在现代osx上,它在vsync的中间调用你,它给你的目标是2 vsync。
inTime参数被认为是回调被触发的时刻。然而有趣的是,虽然主机时间确实是这样,但inTime的videoTime正好对应于最后一个vsync的时刻。至少从osx 13.5开始,视频时间似乎有更强的属性,它永远不会在小于视频刷新周期的分辨率下增加。(不过,我并不认为这种行为是面向未来的,因为苹果文档中没有任何内容可以保证它不会发生)。
下面是示例代码,它显示了在vsync周期内CVDisplayLink被触发的确切时间。它这样做是基于inTime的videoTime对应于最后一个vsync的假设。这可以转换为主机时间,以给予您上一个vsync的单调主机时间。

#import <Foundation/Foundation.h>
#import <CoreVideo/CoreVideo.h>
#include <inttypes.h>
#include <mach/mach_time.h>
#include <unistd.h>
#include <CoreServices/CoreServices.h>

CVDisplayLinkRef _link;

CVReturn MyDisplayCallback(CVDisplayLinkRef displayLink,
    const CVTimeStamp *inTime,
    const CVTimeStamp *outTime,
    CVOptionFlags flagsIn,
    CVOptionFlags *flagsOut,
    void *displayLinkContext) {

        uint64_t inVBase = inTime->videoTime;
        uint64_t inTBase = inTime->hostTime;
        
        CVTimeStamp inTstamp;
        inTstamp.videoTime = inTime->videoTime;
        inTstamp.videoTimeScale = inTime->videoTimeScale;
        inTstamp.flags = kCVTimeStampVideoTimeValid;
        CVTimeStamp outTstamp;
        outTstamp.flags = kCVTimeStampHostTimeValid;
        CVDisplayLinkTranslateTime(_link, &inTstamp, &outTstamp);
        
        uint64_t vsyncStartHostTime = outTstamp.hostTime;
        inTstamp.videoTime = inTime->videoTime + inTime->videoRefreshPeriod;
        
        CVDisplayLinkTranslateTime(_link, &inTstamp, &outTstamp);
        uint64_t vsyncEndHostTime = outTstamp.hostTime;
        printf("%.2f\n", ((double)(inTime->hostTime - vsyncStartHostTime))/(vsyncEndHostTime - vsyncStartHostTime));
        

        
        return kCVReturnSuccess;
}


int main(int argc, char *argv[]) {
    @autoreleasepool {
        CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(),&_link);
        CVDisplayLinkSetOutputCallback(_link, MyDisplayCallback, NULL);
        CVDisplayLinkStart(_link);
        CFRunLoopRun();
    }
}

因此,考虑到所有这些,如果你想做的是找出上一次vsync发生的时间或下一次vsync将发生的时间,你不应该使用outTime来实现这一目的。我所能看到的最好的方法(尽管依赖于未记录的行为)是将inTime(如果你想成为未来的话,四舍五入到最近的displayRefreshPeriod)作为最后一个vsync,然后添加refreshPeriod以获得下一个vsync。由于你可以将显示时间转换为主机时间,你甚至可以设置自己的计时器[1],以在实际的vsync时间间隔关闭。
最后,应该注意的是,有一些CoreVideo帮助函数,如CVGetHostClockFrequency()。这些基本上只是 Package 器,以避免直接与mach_time_base接口[CVGetHostClockFrequency]只是返回(1/(time_num/time_denom))* 1 e9,即从主机秒到mach_absolute_time刻度的转换因子。
[1][https://developer.apple.com/library/archive/technotes/tn2169/_index.html](https://developer.apple.com/library/archive/technotes/tn2169/_index.html)

相关问题