Hello
I'am trying to display a CVPixelBuffer via AVSampleBufferDisplayLayer. The problem is that it's not working on actual iOS device (nothing is rendered), but it works without any problem on iOS simulator. There is a code of sample app i've created for that:
@implementation ViewController {
AVSampleBufferDisplayLayer *videoLayer;
}
- (void)viewDidLoad {
[super viewDidLoad];
videoLayer = [[AVSampleBufferDisplayLayer alloc] init];
videoLayer.frame = CGRectMake(50, 50, 300, 300);
videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:videoLayer];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self startVideo];
}
- (void)startVideo {
[self drawPixelBuffer];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(drawPixelBuffer) userInfo:nil repeats:YES];
}
- (void)drawPixelBuffer {
int imageSize = 100;
static const uint8_t pixel[] = {0x00, 0xAA, 0xFF, 0xFF};
NSMutableData *frame = [NSMutableData data];
for (int i = 0; i < imageSize * imageSize; i++) {
[frame appendBytes:pixel length:4];
}
CVPixelBufferRef pixelBuffer = NULL;
CVPixelBufferCreateWithBytes(NULL, imageSize, imageSize, kCVPixelFormatType_32BGRA, [frame bytes], imageSize * 4, NULL, NULL, NULL, &pixelBuffer);
CMSampleBufferRef sampleBuffer = [self sampleBufferFromPixelBuffer:pixelBuffer];
if (sampleBuffer) {
[videoLayer enqueueSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);
}
}
- (CMSampleBufferRef)sampleBufferFromPixelBuffer:(CVPixelBufferRef)pixelBuffer {
CMSampleBufferRef sampleBuffer = NULL;
OSStatus err = noErr;
CMVideoFormatDescriptionRef formatDesc = NULL;
err = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &formatDesc);
if (err != noErr) {
return nil;
}
CMSampleTimingInfo sampleTimingInfo = kCMTimingInfoInvalid;
err = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer, formatDesc, &sampleTimingInfo, &sampleBuffer);
if (sampleBuffer) {
CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES);
CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0);
CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
}
if (err != noErr) {
return nil;
}
formatDesc = nil;
return sampleBuffer;
}
@end
I am not getting any error, the video layer's error property always returns nil and status is always equal to AVQueuedSampleBufferRenderingStatusRendering.
Does anybody know why it doesn't work on iOS device and how to fix it?
Thanks,
Lukas