I am trying to crop image in CMSampleBufferRef
to a specific size. I am making 5 steps - 1. Getting PixelBuffer
from SampleBuffer
2. Converting PixelBuffer
to CIImage
3. Cropping CIImage
4. Rendering CIImage
back to PixelBuffer
5. Attaching PixelBuffer
to SampleBuffer
. So far I am having trouble with step 4 - rendering image back to PixelBuffer
(can not check beyond this point) nothing is rendered to buffer (I check it using same CIImage imageWithCVPixelBuffer
and get NULL as a return). Would greatly appreciate any tip or help.
CGRect cropRect = CGRectMake(0, 0, 640, 480);
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:(CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer)]; //options: [NSDictionary dictionaryWithObjectsAndKeys:[NSNull null], kCIImageColorSpace, nil]];
ciImage = [ciImage imageByCroppingToRect:cropRect];
CVPixelBufferRef pixelBuffer;
CVPixelBufferCreate(kCFAllocatorSystemDefault, 640, 480, kCVPixelFormatType_32BGRA, NULL, &pixelBuffer);
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
CIContext * ciContext = [CIContext contextWithOptions: nil];
[ciContext render:ciImage toCVPixelBuffer:pixelBuffer];
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
CMSampleTimingInfo sampleTime = {
.duration = CMSampleBufferGetDuration(sampleBuffer),
.presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer),
.decodeTimeStamp = CMSampleBufferGetDecodeTimeStamp(sampleBuffer)
};
CMVideoFormatDescriptionRef videoInfo = NULL;
CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &videoInfo);
CMSampleBufferRef oBuf;
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, true, NULL, NULL, videoInfo, &sampleTime, &oBuf);
So I found the reason why I was having problem. Apparently I have to add kCVPixelBufferIOSurfacePropertiesKey key when initializing pixel buffer, by creating dictionary and passing it to initializer. Here's a code if anyone stumbles upon this problem:
CFDictionaryRef empty; // empty value for attr value.
CFMutableDictionaryRef attrs;
empty = CFDictionaryCreate(kCFAllocatorDefault, // our empty IOSurface properties dictionary
NULL,
NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs,
kCVPixelBufferIOSurfacePropertiesKey,
empty);
Then you just have to pass this dictionary as an argument to CVPixelBufferCreate
I found this solution here: http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With