Reputation: 69
I have a problem that is driving me crazy the last few days. It's about AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer method. No matter what I do, it always cause EXC_BAD_ACCESS on this line. I know there're a couple of posts talking about it, but none can help me.
This is my situation: I'm rendering into a texture with OpenGLES and I want to create a video from those textures. Here's my code:
Creating FBO, attached texture and pixelBuffer to fill in render:
glGenFramebuffers(1, &_secondFrameBuffer);
glGenRenderbuffers(1, &_depthRenderBuffer);
CVPixelBufferPoolCreatePixelBuffer(NULL, [_videoWriter.pixelBufferInput pixelBufferPool], &_fboTexturePixelBuffer);
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
_textureCache,
_fboTexturePixelBuffer,
NULL,
GL_TEXTURE_2D,
GL_RGBA,
(int)size.width,
(int)size.height,
GL_BGRA,
GL_UNSIGNED_BYTE,
0,
&_fboTexture);
glBindTexture(CVOpenGLESTextureGetTarget(_fboTexture), CVOpenGLESTextureGetName(_fboTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.width, size.height);
glBindFramebuffer(GL_FRAMEBUFFER, _secondFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(_fboTexture), 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _secondFrameBuffer);
AVAssetWriter creation :
_dataQueue = dispatch_queue_create("data_queue", NULL);
_assetWriter = [[AVAssetWriter alloc] initWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:nil];
int width = [UIScreen mainScreen].applicationFrame.size.width * [UIScreen mainScreen].scale;
int height = [UIScreen mainScreen].applicationFrame.size.height * [UIScreen mainScreen].scale;
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:width], AVVideoWidthKey,
[NSNumber numberWithInt:height], AVVideoHeightKey,
nil];
_assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
_assetWriterInput.expectsMediaDataInRealTime = YES;
NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,
[NSNumber numberWithBool:YES], kCVPixelBufferOpenGLESCompatibilityKey,
nil];
_assetWriterInputPixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:_assetWriterInput sourcePixelBufferAttributes:bufferAttributes];
[_assetWriter addInput:_assetWriterInput];
_presentationTime = kCMTimeZero;
[_assetWriter startWriting];
[_assetWriter startSessionAtSourceTime:_presentationTime];
And then, I just try to append the pixel Buffer ...
- (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
dispatch_async(_dataQueue, ^{
if (pixelBuffer != NULL) {
[_assetWriterInputPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:_presentationTime];
CMTime frameTime = CMTimeMake(1, 30);
_presentationTime = CMTimeAdd(_presentationTime, frameTime);
} else {
NSLog(@"NULL PixelBuffer !");
}
});
}
CRASH -> EXC_BAD_ACCESS
Can anyone help me PLEASE !?
THANKS !
Upvotes: 1
Views: 2231
Reputation: 3526
I see your problem in method - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer
. If you use ARC please make sure your pixelBuffer is not release on async queue to make it sure please try this code.
- (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
CVPixelBufferRetain(pixelBuffer);
dispatch_async(_dataQueue, ^{
if (pixelBuffer != NULL) {
[_assetWriterInputPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:_presentationTime];
CMTime frameTime = CMTimeMake(1, 30);
_presentationTime = CMTimeAdd(_presentationTime, frameTime);
CVPixelBufferRelease(pixelBuffer);
} else {
NSLog(@"NULL PixelBuffer !");
}
});
}
Upvotes: 0