I need to hold some video frames from a captureSession in memory and write them to a file when 'something' happens.
Similar to this solution, i use this code to put a frame into a NSMutableArray:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
{
//...
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
uint8 *baseAddress = (uint8*)CVPixelBufferGetBaseAddress(imageBuffer);
NSData *rawFrame = [[NSData alloc] initWithBytes:(void*)baseAddress length:(height * bytesPerRow)];
[m_frameDataArray addObject:rawFrame];
[rawFrame release];
//...
}
And this to write the video file:
-(void)writeFramesToFile
{
//...
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:640], AVVideoWidthKey,
[NSNumber numberWithInt:480], AVVideoHeightKey,
AVVideoCodecH264, AVVideoCodecKey,
nil ];
AVAssetWriterInput *bufferAssetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings];
AVAssetWriter *bufferAssetWriter = [[AVAssetWriter alloc]initWithURL:pathURL fileType:AVFileTypeQuickTimeMovie error:&error];
[bufferAssetWriter addInput:bufferAssetWriterInput];
[bufferAssetWriter startWriting];
[bufferAssetWriter startSessionAtSourceTime:startTime];
for (NSInteger i = 1; i < m_frameDataArray.count; i++){
NSData *rawFrame = [m_frameDataArray objectAtIndex:i];
CVImageBufferRef imgBuf = [rawFrame bytes];
[pixelBufferAdaptor appendPixelBuffer:imgBuf withPresentationTime:CMTimeMake(1,10)]; //<-- EXC_BAD_ACCESS
[rawFrame release];
}
//... (finishing video file)
}
But something is wrong with the imgBuf reference. Any suggestions? Thanks in advance.
You're supposed to lock base address before accessing imageBuffer's properties.
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
uint8 *baseAddress = (uint8*)CVPixelBufferGetBaseAddress(imageBuffer);
NSData *rawFrame = [[NSData alloc] initWithBytes:(void*)baseAddress length:(height * bytesPerRow)];
[m_frameDataArray addObject:rawFrame];
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
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