AVFoundation - Retiming CMSampleBufferRef Video Output

前端 未结 2 2082
抹茶落季
抹茶落季 2021-01-30 10:07

First time asking a question here. I\'m hoping the post is clear and sample code is formatted correctly.

I\'m experimenting with AVFoundation and time lapse photography.

相关标签:
2条回答
  • 2021-01-30 10:16

    With a little more searching and reading I have a working solution. Don't know that it is best method, but so far, so good.

    In my setup area I've setup an AVAssetWriterInputPixelBufferAdaptor. The code addition looks like this.

    InputWriterBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor
                assetWriterInputPixelBufferAdaptorWithAssetWriterInput: inputWriterBuffer
                sourcePixelBufferAttributes: nil];
    [inputWriterBufferAdaptor retain];
    

    For completeness to understand the code below, I also have these three lines in the setup method.

    fpsOutput = 30; //Some possible values: 30, 10, 15 24, 25, 30/1.001 or 29.97;
    cmTimeSecondsDenominatorTimescale = 600 * 100000; //To more precisely handle 29.97.
    cmTimeNumeratorValue = cmTimeSecondsDenominatorTimescale / fpsOutput;
    

    Instead of applying a retiming to a copy of the sample buffer. I now have the following three lines of code that effectively does the same thing. Notice the withPresentationTime parameter for the adapter. By passing my custom value to that, I gain the correct timing I'm seeking.

    CVPixelBufferRef myImage = CMSampleBufferGetImageBuffer( sampleBuffer );
    imageSourceTime = CMTimeMake( writtenFrames * cmTimeNumeratorValue, cmTimeSecondsDenominatorTimescale);
    appendSuccessFlag = [inputWriterBufferAdaptor appendPixelBuffer: myImage withPresentationTime: imageSourceTime];
    

    Use of the AVAssetWriterInputPixelBufferAdaptor.pixelBufferPool property may have some gains, but I haven't figured that out.

    0 讨论(0)
  • 2021-01-30 10:28

    OK, I found the bug in my first post.

    When using

    myStatus = CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault,
                                                     sampleBuffer,
                                                     1,
                                                     &sampleTimingInfo, 
                                                     &newSampleBuffer);
    

    you need to balance that with a CFRelease(newSampleBuffer);

    The same idea holds true when using a CVPixelBufferRef with a piexBufferPool of an AVAssetWriterInputPixelBufferAdaptor instance. You would use CVPixelBufferRelease(yourCVPixelBufferRef); after calling the appendPixelBuffer: withPresentationTime: method.

    Hope this is helpful to someone else.

    0 讨论(0)
提交回复
热议问题