我创建了一个使用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 {}来包装这部分。它有效地停止了峰值内存使用量的累积,但即使没有运行错误,它也不会再成功写入视频文件。
以上说明来自实际设备调试。
我想到可能的解决方案是分段写入,或者在写入周期中暂停几次以允许写入器真正释放缓冲区。但我找不到办法做到这一点。我很感激任何知道解决这个峰值记忆问题的方法的人。
答案 0 :(得分:0)
我和你有同样的问题
我尝试在
中使用sleepForTimeInterval我希望当这个事件触发时,它会暂停主要过程并且给予一点时间 系统刷新未使用的内存
但我不知道这是否有效