我有下面的代码以30fps捕获jpeg帧并以mp4格式记录视频。我正在尝试将processFrame方法包装在dispatch_async调用中,以便录制过程不会锁定视频播放器。这个问题是我的内存警告级别为2,应用程序最终会在几秒钟后崩溃。我可以看到dispatch_async方法在尝试在记录的视频输出中追加每个帧时将内存加载到内存中,并且在30fps时,它没有足够的时间来处理帧并释放已用的内存。我尝试使用dispatch_after延迟processFrame的执行,但它没有帮助。有任何想法吗?我应该这样做吗?
此方法每秒调用约30次。
//Process the data sent by the server and send follow-up commands if needed
-(void)processServerData:(NSData *)data{
//render the video in the UIImage control
UIImage *image =[UIImage imageWithData:data];
imageCtrl.image = image;
//record the frame in the background
dispatch_async(recordingQueue,^{[self processFrame:image];});
}
}
processFrame方法
//function for processing each frame for recording
-(void) processFrame:(UIImage *) image {
if (myRecorder.frameCounter < myRecorder.maxFrames)
{
if([myRecorder.writerInput isReadyForMoreMediaData])
{
CMTime frameTime = CMTimeMake(1, myRecorder.timeScale);
CMTime lastTime=CMTimeMake(myRecorder.frameCounter, myRecorder.timeScale);
CMTime presentTime=CMTimeAdd(lastTime, frameTime);
buffer = [Recorder pixelBufferFromCGImage:image.CGImage size:myRecorder.imageSize];
if(buffer)
{
[myRecorder.adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
myRecorder.frameCounter++;
CVBufferRelease(buffer);
if (myRecorder.frameCounter==myRecorder.maxFrames)
{
[myRecorder finishSession];
myRecorder.frameCounter=0;
myRecorder.isRecording = NO;
}
}
else
{
NSLog(@"Buffer is empty");
}
}
else
{
NSLog(@"adaptor not ready frameCounter=%d ",myRecorder.frameCounter );
}
}
}
答案 0 :(得分:3)
解决!我发现我可以使用dispatch_async_semaphore来防止队列过多请求它没有足够的时间来释放分配的资源。
这是我更新的代码:
long success = dispatch_semaphore_wait(recordingSemaphore, DISPATCH_TIME_FOREVER);
if (success != 0 )
{
NSLog(@"Frame skipped");
}
else
{
dispatch_async(recordingQueue,^{
dispatch_semaphore_signal(recordingSemaphore);
[self processFrame:image];
});
}
dispatch_semaphore在我的代码中的某处创建。在这里,我告诉信号量首先接受最多50个请求并完成处理,然后再接受请求。
dispatch_semaphore_t recordingSemaphore = dispatch_semaphore_create((long) 50); //so far stable at 50