Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAssetWriterInputPixelBufferAdaptor pixelBufferPool goes NULL after some time

I'm using the pixelBufferPool within an AVAssetWriterInputPixelBufferAdaptor to create pixel buffers for use with the append method. After creating 4 buffers, the pixelBufferPool property becomes NULL;

I setup my writer, input and adaptor like this:

- (BOOL) setupRecorder {
    NSError *error = nil;
    if([[NSFileManager defaultManager] fileExistsAtPath:[[self tempFileURL] path]])
        [[NSFileManager defaultManager] removeItemAtURL:[self tempFileURL] error:&error];


    assetWriter = [[AVAssetWriter alloc] initWithURL: [self tempFileURL] 
                                            fileType:AVFileTypeQuickTimeMovie
                                               error:&error]; 
    if (error) {
        NSLog(@"Error creating asset writer: %@", error);
        [assetWriter release];
        return NO;
    }
    // writer

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey, 
                                   [NSNumber numberWithInt:videoWidth], AVVideoWidthKey, 
                                   [NSNumber numberWithInt:videoHeight], AVVideoHeightKey,
                                   nil];

    assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo 
                                                      outputSettings:videoSettings];

    NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
                                      [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, 
                                      nil];

    adaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:bufferAttributes];  
    [adaptor retain];
    assetWriterInput.expectsMediaDataInRealTime = YES;
    [assetWriter addInput:assetWriterInput];

    return YES;
}

and I hand out pixel buffers with this:

- (CVPixelBufferRef) createPixelBufferRef {
    CVPixelBufferPoolRef pixelBufferPool = adaptor.pixelBufferPool;
    CVPixelBufferRef pixelBuffer = NULL;
    CVReturn cvReturn = CVPixelBufferPoolCreatePixelBuffer(NULL, pixelBufferPool, &pixelBuffer);
    if(cvReturn != kCVReturnSuccess)
        NSLog(@"CVPixelBuffePoolCreatePixelBuffer: %d", cvReturn);
    bufferCreatedCount++;
    return pixelBuffer;
}

when I'm done passing the pixel buffer to appendPixelBuffer i release the pixel buffer with CVPixelBufferRelease. At no point before this going NULL do I call markAsFinished, endSessionAtSourceTime or finishWriting. Further, the adaptor itself does not go NULL.

Most posts I read talk about the pool being absent from the beginning due to a misconfigured adaptor, however mine is there, but only for a short time. Anyone else seen this behavior?

like image 640
davidbitton Avatar asked Jun 20 '11 16:06

davidbitton


2 Answers

I had the same problem. As I figured out, this happens, if some of the CMTimes, you put into appendPixelBuffer:withPresentationTime:, are equal. This can happen for instance, if you use CMTimeMakeWithSeconds with a too coarse timescale.

like image 54
Dominik Seibold Avatar answered Nov 11 '22 23:11

Dominik Seibold


It may happen in case of an pixel buffer adapter error. Pixel buffer adapter may go into error state in cause of frames pushed out of order or with the same presentation time.

like image 4
AlexeyVMP Avatar answered Nov 11 '22 23:11

AlexeyVMP