Prerequisites
- A working iOS quickstart
- An app-owned BGRA
CVPixelBuffersource with stable dimensions
When to use this guide
Use off-screen mode when the host supplies external frames. If Nosmai owns the camera and another component only needs processed output, use NosmaiCore.liveFrameStreamCallback instead.
Prepare the output callback
NosmaiSDK *sdk = [NosmaiSDK sharedInstance];
[sdk setCVPixelBufferCallback:^(CVPixelBufferRef output, double timestamp) {
CVPixelBufferRetain(output);
dispatch_async(encoderQueue, ^{
[consumer consumePixelBuffer:output timestamp:timestamp];
CVPixelBufferRelease(output);
});
}];
Retain the output only when the consumer continues after the callback returns.
Initialize off-screen mode
BOOL ready = [sdk initializeOffscreenWithWidth:width height:height];
if (ready) {
[sdk setProcessingMode:NosmaiProcessingModeOffscreen];
}
Input buffers must use kCVPixelFormatType_32BGRA and keep stable dimensions.
Submit a frame
BOOL accepted = [sdk processFrame:inputPixelBuffer mirror:NO];
You can pass a CMSampleBufferRef with processSampleBuffer:mirror:. For asynchronous submission, retain the input until processFrameAsync:mirror:completion: finishes.
Return to live camera mode
Stop the external source first, then clear its callback:
[sdk setCVPixelBufferCallback:nil]; [sdk setProcessingMode:NosmaiProcessingModeLive];
Verify it worked
Apply a visible effect and confirm the output buffer orientation, colors, timestamps, and ownership on a physical device. Use getProcessingMetrics during development to inspect processed and dropped frames.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
processFrame returns NO | Off-screen mode is not ready or the pixel format is unsupported | Initialize the exact dimensions and submit kCVPixelFormatType_32BGRA |
| Output crashes after the callback | The consumer kept a borrowed buffer without retaining it | Retain before asynchronous use and release after consumption |