使用Metal进行屏幕撕裂和相机捕捉

问题描述 投票:0回答:1

为了避免同时从 gpu 和 cpu 写入常量缓冲区,Apple 建议在信号量的帮助下使用三缓冲系统,以防止 cpu 领先于 gpu 太多(这很好并已涵盖)现阶段至少有三个 Metal 视频)。

但是,当常量资源是 MTLTexture 并且 AVCaptureVideoDataOutput 委托与渲染循环(CADisplaylink)分开运行时,类似的三缓冲系统(如 Apple 示例代码 MetalVideoCapture 中使用的)如何保证同步?如果您采用 MetalVideoCapture 代码并简单地渲染全屏四边形并将预设更改为 AVCaptureSessionPresetHigh(此时撕裂被旋转四边形和低质量预设遮盖),则可以观察到屏幕撕裂(纹理撕裂)。

我意识到渲染循环和 captureOutput 委托方法(在本例中)都在主线程上,并且信号量(在渲染循环中)保持检查 _constantDataBufferIndex 整数(它索引到 MTLTexture 中以进行创建和编码) ,但仍然可以观察到屏幕撕裂,这让我感到困惑(如果 GPU 写入纹理不是编码后的下一帧而是编码后 2 或 3 帧,那么这是有意义的,但我不认为这是案件)。另外,还有一点:对于缓冲纹理系统,渲染循环和 captureOutput 不应该具有相同的帧速率,这样旧帧就不会与最近的帧交错渲染。

对此事的任何想法或澄清将不胜感激; McZonk 还有另一个例子,它不使用三重缓冲系统,但我也观察到这种方法会出现撕裂(但情况较少)。显然,如果我使用 waitUntilCompleted(相当于 Open GL 的 glfinish),则不会观察到撕裂,但这就像将一只手臂绑在背后拉手风琴一样!

ios objective-c video opengl-es metal
1个回答
0
投票

根据我的评论,我应该在几年前发布一个答案,但是通过对 Y 和 CbCr 的 CVMetalTextureRef 使用三重缓冲实例变量,撕裂消失了。在Apple发布的所有第一个示例代码中,只有Y和CbCr MTLTextures是实例变量。

© www.soinside.com 2019 - 2024. All rights reserved.