9

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?

Richard Slater
  • 6,313
  • 4
  • 53
  • 81
davidbitton
  • 818
  • 10
  • 20
  • Were you ever able to track this down? Having the same issue now. – smdvlpr Apr 08 '14 at 15:24
  • There was an internal error. It's been so long now that I do not remember what it was. Thanks. – davidbitton Apr 09 '14 at 17:07
  • My hacky solution is to re-encode the first pixel buffer I read before appending it, which seems to fix the internal issue the adapter/pool had. Trying other methods still because I don't like that. – smdvlpr Apr 09 '14 at 17:26
  • When you say 'internal error'. what does that mean? Something in your code, or something in AVFoundation? Mine works anywhere from 1 to 4 frames and then goes nil (Swift 4). – drewster Jan 03 '18 at 18:32
  • I just don't remember. There's a decent sample from a few WWDCs ago. – davidbitton Jan 04 '18 at 23:11

2 Answers2

6

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.

Dominik Seibold
  • 2,439
  • 1
  • 23
  • 29
  • Do you have a timescale you would recommend? I am currently using 240 and getting this error on an iPhoneX. – JCutting8 Jun 30 '20 at 12:09
4

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.

AlexeyVMP
  • 2,386
  • 3
  • 24
  • 31
  • Thank you. This is exactly my error. In my refactoring of my codebase, I was referencing a variable that no longer is being updated for the presentation time and resulted in the adapter returning a nil for the pixel buffer pool. – Shiun Dec 09 '14 at 21:37