使用 AVAssetWriter 将大量图像写入视频文件时的高峰值内存使用率

Posted

技术标签:

【中文标题】使用 AVAssetWriter 将大量图像写入视频文件时的高峰值内存使用率【英文标题】:high peak memory usage when writing large amount images to video file using AVAssetWriter 【发布时间】:2013-12-12 09:00:12 【问题描述】:

我创建了一个使用 AvAssetWriter 将图像组装成视频文件的函数。论坛中有一些关于此实现的主题。我已经使用 AVAssetWriter 成功编写了视频。我的问题不是这个实现,而是关于内存消耗。就我而言,当我编写 4 秒 30FPS 视频 1024*768 时,峰值内存使用量将在 300MB 左右。对于更长的时间,10 秒等,它会因内存警告而崩溃。问题是在将每个图像写入视频文件的循环过程中,内存使用量是累积的。循环后,内存使用量将恢复到正常水平而不会泄漏。

以下代码是循环的一次迭代。它将新图像附加到 avassetwriter

        CVPixelBufferRef buffer = [self pixelBufferFromCGImage:[newimg CGImage] 
            size:CGSizeMake(self.frameOrigWidth, self.frameOrigHeight) poolRef:adaptor.pixelBufferPool];
        BOOL append_ok = NO;
        int j = 0;
        CMTime frameTime = CMTimeMake(frameCount,(int32_t)FPS);
        while (!append_ok && j < 30) //attemp maximum 30 times
        
            if (adaptor.assetWriterInput.readyForMoreMediaData)
            
                if(frameCount==0) append_ok = [adaptor appendPixelBuffer:buffer 
                            withPresentationTime:kCMTimeZero];
                else append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
                [NSThread sleepForTimeInterval:0.05];//use sleep instead of runloop because it is not in main thread
            else
                [NSThread sleepForTimeInterval:0.1];
            
            j++;
        
        if(buffer) CVBufferRelease(buffer);

即使最后一行释放了缓冲区,在整个循环过程中内存也不会释放,我猜是因为编写器保留了这个缓冲区直到循环结束,编写器执行结束写入。

我尝试使用 @autoreleasepool 来包装这部分。它有效地阻止了峰值内存使用积累,但即使没有运行错误,它也不再成功写入视频文件。

以上解释来自真实设备调试。

我想到的可能的解决方案是分段写入,或者在写入周期中暂停几次,让缓冲区真正被写入器释放。但我没有找到办法做到这一点。我感谢任何知道解决此峰值内存问题的方法的人。

【问题讨论】:

我目前使用的解决方案是将写入任务分成不同的段,每个段写入一个文件。在循环结束时,我使用 AVMutableComposition 组合所有小文件。通过这种方法,峰值内存出现在每个段中。因为每个segment没有多少imgs要写,内存不会消耗太多。我很欣赏其他想法 【参考方案1】:

我和你有同样的问题

我尝试在里面使用 sleepForTimeInterval

(void)didReceiveMemoryWarning

我希望当这个事件触发时,它会暂停主进程并且给一点时间 系统刷新未使用的内存

但我不知道这是否有效

【讨论】:

只是为了让你知道我使用前面提到的方法来解决它。您可以将导出视频任务拆分为多个短视频生成。然后最后将它们合并在一起。这对我来说很好。我的应用程序已经上架了应用程序商店,您可以查看它以了解此方法可用于生成长时间视频。我的应用是“动画DIY”

以上是关于使用 AVAssetWriter 将大量图像写入视频文件时的高峰值内存使用率的主要内容,如果未能解决你的问题,请参考以下文章

AVAssetWriter - 设置自定义帧率

AVAssetWriter 停止在 iOS7 中写入文件

如何使用 AVAssetWriter 在 ios 中写入 AAC 音频?

AVAssetWriter 文件备份与恢复

如何对 AVAssetWriter 输出进行颜色管理

AVAssetWriter 内存错误