gpt4 book ai didi

iphone - 如何修改 GLCameraRipple 示例以在后台线程上处理?

转载 作者:行者123 更新时间:2023-12-03 19:57:31 24 4
gpt4 key购买 nike

我正在尝试修改 GLCameraRipple Apple 的示例应用程序,用于在后台线程上处理视频帧。在此示例中,它使用以下代码处理主线程上的每个帧:

// Set dispatch to be on the main thread so OpenGL can do things with the data
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

如果我更改此代码以在后台线程中处理:

dispatch_queue_t videoQueue = dispatch_queue_create("com.test.queue", NULL);
[dataOutput setSampleBufferDelegate:self queue:videoQueue];

然后程序崩溃。

当我尝试创建第二个具有共享功能的 EAGLContext 时(如 Apple 文档中所述),我只能看到绿屏或黑屏。

如何修改此示例应用程序以在后台线程上运行?

最佳答案

在我修改了示例之后,这实际上相当有趣。这里的问题在于 CVOpenGLESTextureCacheCreateTextureFromImage() 函数。如果您在获得绿色纹理时查看控制台,您将看到类似以下内容的记录:

Error at CVOpenGLESTextureCacheCreateTextureFromImage -6661

-6661,根据标题(目前我可以找到有关这些新函数的文档的唯一位置),是一个 kCVReturnInvalidArgument 错误。该函数的参数之一显然有问题。

事实证明,问题出在 CVImageBufferRef 上。看起来在处理此纹理缓存更新的 block 正在发生时,它正在被释放或以其他方式更改。

我尝试了几种方法来解决这个问题,最终使用了调度队列和调度信号量,就像我在this answer中描述的那样。 ,让委托(delegate)仍然在主线程上回调,并在委托(delegate)内执行如下操作:

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0)
{
return;
}

CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
CFRetain(pixelBuffer);

dispatch_async(openGLESContextQueue, ^{
[EAGLContext setCurrentContext:_context];

// Rest of your processing

CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
CFRelease(pixelBuffer);

dispatch_semaphore_signal(frameRenderingSemaphore);
});
}

通过在主线程上创建 CVImageBufferRef,锁定它指向的字节并保留它,然后将其交给异步 block ,这似乎可以修复此错误。显示此修改的完整项目可以从 here 下载。 .

我应该在这里说一件事:这似乎不会给你带来任何好处。如果您查看 GLCameraRipple 示例的设置方式,就会发现应用程序中最繁重的操作(波纹效果的计算)已被分派(dispatch)到后台队列。这还使用新的快速上传路径向 OpenGL ES 提供相机数据,因此在主线程上运行时这不是瓶颈。

在双核 iPhone 4S 上的 Instruments 分析中,我发现此示例应用程序的原始版本与在后台队列上运行帧上传的修改版本之间的渲染速度或 CPU 使用率没有显着差异。尽管如此,诊断这个问题仍然很有趣。

关于iphone - 如何修改 GLCameraRipple 示例以在后台线程上处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9128999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com