I use AVAssetWriter
to generate a video with frame images (UIImage
array). When it is doing the encoding work, memory usage sometimes spikes to more than 700MB. On my iPhone (with 3GB MEM), this doesn't cause OOM issue, but I am afraid it would cause trouble in older iPhones.
Can I somehow limit AVAssetWriter
memory usage? I guess internally it may use some queue to cache the frame bytes, if I can specify the size of the cache, then I can set an upper limit of memory. But I didn't find such options/settings in the documentation.
Here is my code:
let settings:[String:Any] = [
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: FRAME_SIZE,
AVVideoHeightKey: FRAME_SIZE
]
let assetWriter = AVAssetWriter(url: self.url!, fileType: AVFileType.mov)
let assetWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: settings)
self.assetWriter?.add(assetWriterInput)
let bufferAttributes:[String: Any] = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32ARGB)]
let bufferAdapter = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: assetWriterInput, sourcePixelBufferAttributes: bufferAttributes)
let frameTime = CMTimeMake(1, 30)
self.assetWriter?.startWriting()
self.assetWriter?.startSession(atSourceTime: kCMTimeZero)
let mediaInputQueue = DispatchQueue(label: "mediaInputQueue")
var i = 0
assetWriterInput.requestMediaDataWhenReady(on: mediaInputQueue){
var localframes = frames
while(true){
if(localframes.isEmpty){
break
}
if (assetWriterInput.isReadyForMoreMediaData){
let image = localframes.removeFirst()
let pixelBuffer = self.newPixelBufferFrom(cgImage: image.cgImage!)
var time:CMTime
if i == 0 {
time = kCMTimeZero
} else {
time = CMTimeMake(Int64(i), frameTime.timescale)
}
bufferAdapter.append(pixelBuffer!, withPresentationTime: time)
// TODO: how to release memory?
i += 1
}
}
assetWriterInput.markAsFinished()
self.assetWriter?.finishWriting(completionHandler: {
finishedHandler()
})
}
Not sure if it will help, but I had a similar problem inside a while
loop. You can check this answer: Is the ios iPhone simulator causing memory usage analysis to swell?
You can give it a try, and see if it improves:
let pixelBuffer = autoreleasepool { return self.newPixelBufferFrom(cgImage: image.cgImage!) }