zzy*_*yzy 5 drawrect avplayer metal cvpixelbuffer metalkit
我正在寻找有关如何正确实现 Metal 渲染循环的一些指导。我的渲染循环正在从AVPlayer.
这是我当前的实现:
CVDisplayLink查询播放器的频率。AVPlayerItemVideoOutput如果存在新帧,则会将其捕获/保存*作为它将渲染到的CVPixelBufferRef属性。MTKView(此时,先前捕获的视频帧被释放)。MTKView设置是用isPaused和enableSetNeedsDisplayto NO。换句话说,内部定时器的任务MTKView是定期调用其drawRect方法。drawRect首先将新到达的 * 转换CVPixelBuffer为 a MTLTexture,然后发生一堆渲染阶段。presentDrawable结束时调用drawRect。*注意:对 的互斥访问由和CVPixelBufferRef配对控制 。dispatch_semaphore_waitdispatch_semaphore_signal
这是正确的做事方式吗? 尽管偶尔会丢失一些帧,但它看起来性能相当不错。在时间方面,Metal 的 Xcode 分析告诉我,我的MTLCommandBuffer运行时间通常不到 3 毫秒。
话虽如此,我看到了一些替代的可能性:
CVDisplayLink实现并获取其中的框架drawRectMTLTexturedrawRectcommitpresentDrawabledrawRectdrawRect另一个问题:我的印象是,使用此配置CVDisplayLink, 和drawRect方法都没有在主线程上运行。让我感到困扰的是,每当我放松应用程序的一个菜单时,视频帧的传输就会出现明显的卡顿——这是主线程执行 UI 更新并且被阻塞的症状。当重新加载屏幕上的NSCollectionView内容并且其内容在屏幕上呈现动画时,会观察到相同的行为。这让我相信我的假设是错误的。如何MTKView制作这些渲染循环来避免这些问题? 想知道整个打开/配置是否AVPlayer也需要脱离主线程。
我修复了将鼠标悬停在任何项目上时会发生的“另一个问题NSMenu”口吃问题。这是我的解决方案:
MTKView使用isPaused=YES和配置每个enableSetNeedsDisplay=NO。这意味着视图draw需要显式调用来呈现其内容。CVDisplayLink回调中,发出draw对MTKViewa 的调用dispatch_global_queue,因此:__block MTKView *aView = ....;
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(aQueue, ^{ [aView draw]; });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
894 次 |
| 最近记录: |