使用AVAssetWriter将大量图像写入视频文件时,峰值内存使用率很高 [英] high peak memory usage when writing large amount images to video file using AVAssetWriter

查看:366
本文介绍了使用AVAssetWriter将大量图像写入视频文件时,峰值内存使用率很高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

以上说明来自真实设备调试.

我认为可能的解决方案是分段写入,或在写入周期中暂停几次以允许写入器真正释放缓冲区.但是我没有找到一种方法来做到这一点.我感谢任何知道解决此峰值内存问题方法的人.

解决方案

我和您有相同的问题

我尝试在内部使用sleepForTimeInterval

  • (void)didReceiveMemoryWarning

我希望在触发此事件时,它将暂停主进程,并且不会给您太多时间 系统刷新未使用的内存

但是我不知道这是否有效

I create a function to assemble images into video file by using AvAssetWriter. There are a few threads in forum about this implementation. I have successfully written the video using AVAssetWriter. My question is not this implementation but about memory consumption. In my case, when I write 4 sec 30FPS video 1024*768, the peak memory usage will be around 300MB. For longer time, 10sec etc. it will crash with memory warning. The problem is that the memory usage is accumulated during the loop which write each image into the video file.After the loop, memory usage will drop back to normal level without leakage.

The following code is one iterate of the loop. It appends a new image to the 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);

even there is buffer release at the last line, the memory will not be released during the whole loop procedure, I guess it is because the writer retains this buffer till after loop and the writer execute finishwriting.

I tried using @autoreleasepool{} to wrap this part. It effectively stopped the peak memory usage accumulation, but it also does not successfully write video file anymore even there is no running error.

The above explanation is from real device debug.

I thought of possible solution is to segment the writing, or pause a few times during the writing cycle to allow buffer really released by the writer. But i do not find a way to do that. I appreciate anyone who knows the method to solve this peak memory problem.

解决方案

i have same issue with you

i try use sleepForTimeInterval inside

  • (void)didReceiveMemoryWarning

i was hope when this event triggered, it will pause main process nad give little time to system to flush unused memory

but i dont know if this effective or not

这篇关于使用AVAssetWriter将大量图像写入视频文件时,峰值内存使用率很高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆