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

时间:2013-12-12 09:00:12

标签: ios memory video

我创建了一个使用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 {}来包装这部分。它有效地停止了峰值内存使用量的累积,但即使没有运行错误,它也不会再成功写入视频文件。

以上说明来自实际设备调试。

我想到可能的解决方案是分段写入,或者在写入周期中暂停几次以允许写入器真正释放缓冲区。但我找不到办法做到这一点。我很感激任何知道解决这个峰值记忆问题的方法的人。

1 个答案:

答案 0 :(得分:0)

我和你有同样的问题

我尝试在

中使用sleepForTimeInterval
  • (无效)didReceiveMemoryWarning

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

但我不知道这是否有效