AVSampleBufferDisplayLayer without a frame is displayed
After a week of struggling, I decided to ask for help:
I've tried two approaches:
-
Just by inserting a sample (since this is a direct stream, frames appear intermittently):
- (void)drawSample:(CMSampleBufferRef)sample { CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sample, YES); CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0); CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue); if (CMSampleBufferIsValid(sample)) { NSLog(@"Valid sample: %@", sample); } else { NSLog(@"Invalid sample: %@", sample); } [self.videoLayer enqueueSampleBuffer:sample]; [self.videoLayer setNeedsDisplay]; if (self.colorIndex > 255) { self.colorIndex = 0; } self.videoLayer.backgroundColor = [UIColor colorWithWhite:self.colorIndex / 255.0f alpha:1.0f].CGColor; self.colorIndex += 1; }
With this approach, no frames are displayed (I added code for changing the background color for debugging purposes, which works fine).
-
The second approach was to display the frames as if they came from an unlimited source (although still using the same direct stream).
- (void)drawSample:(CMSampleBufferRef)sample { CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sample, YES); CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0); CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue); if (CMSampleBufferIsValid(sample)) { NSLog(@"Valid sample"); } else { NSLog(@"Invalid sample: %@", sample); } [self.videoLayer requestMediaDataWhenReadyOnQueue:self.dispatchQueue usingBlock: ^{ while( [_videoLayer isReadyForMoreMediaData] ) { if (CMSampleBufferIsValid(sample)) { [_videoLayer enqueueSampleBuffer:sample]; CFRelease(sample); } else { NSLog(@"Invalid sample inside block: %@", sample); } } NSLog(@"Layer isn't ready"); }]; }
Does not work. With this approach, I have 2 problems:
-
If I add
CFRelease(sample);
inside a block, the app crashes. When Zombie objects are enabled, I get the error:[Not A Type release]: message sent to deallocated instance 0x7fc6426a2120
Should I store CMSampleBufferRef objects in a container and retrieve inside the AVSampleBufferDisplayLayer request media block?
-
If I don't add
CFRelease(sample);
inside the block, only the first frame will be shown and the application will eventually crash due to a memory warning (obviously).
Any idea what I am doing wrong?
NOTE. I watched the video "Direct Access Media Encoding and Decoding" from WWDC 2014 and I seem to be doing it right. I created a video format description, replaced the start code with a NAL length code, and successfully created a CMSampleBuffer.
No one has answered this question yet
Check out similar questions: