Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAssetWriter: specify key frames

I'm using an AVAssetWriter on iOS to encode an MP4 video. I'm currently passing data in with an AVAssetWriterInputPixelBufferAdaptor, but I'm flexible on that front.

How can I specify which of my input frames are key frames?

Currently, I can control the number of key frames (or make all frames key frames) by setting AVVideoMaxKeyFrameIntervalKey, but my encoded video is a straightforward slideshow-with-transitions, and I'd like to ensure key frames at the main images without sacrificing compression.

like image 860
Michael Brewer-Davis Avatar asked Feb 22 '26 04:02

Michael Brewer-Davis


1 Answers

If you make CMSampleBufferRefs (via CMSampleBufferCreateReadyWithImageBuffer(…) to pass in to your AVAssetWriterInput directly (instead of going through an AVAssetWriterInputPixelBufferAdaptor), you can then use CMSetAttachment(…) to set kCMSampleBufferAttachmentKey_ForceKeyFrame to kCFBooleanTrue on your frame to ensure that it will become a key frame.

A potential downside to moving away from AVAssetWriterInputPixelBufferAdaptor is that you lose the memory efficiency that comes with having a shared pixel buffer pool.

If the memory efficiency is important, you might want to consider looking into VideoToolbox and VTCompressionSession instead. VTCompressionSession is more complex than AVAssetWriter* is, but also exposes the pixel buffer pool that's used internally.

If you do go down this route, you'll want to use the kVTEncodeFrameOptionKey_ForceKeyFrame key set to kCFBooleanTrue as a frame attribute when submitting a frame to VTCompressionSessionEncodeFrame(…) for compression.

like image 72
zadr Avatar answered Feb 24 '26 16:02

zadr