问题描述
我正在寻找一种无需阻塞即可等待 if(api_version == "ext2") {
implementation project(":ext2")
}else{
implementation project(":ext1")
}
渲染完成的方法。为简单起见,这里有一个示例,我使用 CIContext
和 CVPixelBufferRef
将一个 CVPixelBufferRef
渲染到另一个 CIImage
。显然,我的实际管道会做得更多,但这是最简单的情况。
CIContext
代码在渲染完成之前一直阻塞,因为 CIContext *context = [CIContext new];
// sourceBuffer provided from something like a camera
CIImage *image = [CIImage imageWithCVPixelBuffer:sourceBuffer];
CVPixelBufferRef output;
// pool was allocated elsewhere
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault,bufferPool,&output)
[context render:image toCVPixelBuffer:output];
正在阻塞。
您可以使用 [CIContext render:toCVPixelBuffer:]
以非阻塞方式启动渲染任务,就像这样
[CIContext startTaskToRender:toDestination:error:]
这已经进行了一半,调用没有阻塞,但我不知道渲染任务何时完成。该 API 返回一个 CIRenderTask,但它只有一个实例方法,当然是 CIContext *context = [CIContext new];
// sourceBuffer provided from something like a camera
CIImage *image = [CIImage imageWithCVPixelBuffer:sourceBuffer];
CVPixelBufferRef output;
// pool was allocated elsewhere
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault,&output)
CIRenderDestination *destination = [[CIRenderDestination alloc] initWithPixelBuffer:output];
[context startTaskToRender:image toDestination:destination error:nil];
,它将阻塞直到任务完成。
老实说,除了为错误回调提供媒介之外,我并没有真正理解这个 API 的意义。除非您的管道不需要知道任务何时完成,否则您仍然需要阻塞以获取结果。
那么,我的问题是:是否可以在不阻塞的情况下获得 waitUntilCompletedAndReturnError
渲染的结果?
解决方法
第一个 render
调用实际上不应该是阻塞调用。如this answer中所述,
“Core Image 推迟渲染,直到客户端请求访问帧缓冲区,即 CVPixelBufferLockBaseAddress
”。
但是,您也可以使用 CIRenderDestiantion
API 并像这样自己使其异步:
CIRenderTask *task = [context startTaskToRender:image toDestination:destination error:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0),^{
[task waitUntilCompletedAndReturnError: NULL];
// do async stuff here,e.g. call a callback block
});