I am looking for a way to wait for a CIContext
render to complete without blocking. For simplicity, here is an example where I render one CVPixelBufferRef
to another CVPixelBufferRef
using CIImage
and CIContext
. Obviously my actual pipeline would do more, but this is the simplest case.
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];
The code as it is blocks until the render is complete, because [CIContext render:toCVPixelBuffer:]
is blocking.
You can start the render task in a non-blocking way using [CIContext startTaskToRender:toDestination:error:]
, like so
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)
CIRenderDestination *destination = [[CIRenderDestination alloc] initWithPixelBuffer:output];
[context startTaskToRender:image toDestination:destination error:nil];
This is halfway there, the call doesn't block, but I have no idea when the render task is finished. That API returns a CIRenderTask, but that only has a single instance method on it, which is of course waitUntilCompletedAndReturnError
, which will block until the task is finished.
To be honest, besides providing a medium for an error callback I don't really understand the point of this API. Unless your pipeline doesn't need to know when the task is finished, you still have to block to get your results.
So, my question: Is it possible to get the results of a CIContext
render without blocking?