繁体   English   中英

在iOS中使用dispatch_async时出现内存警告

[英]Memory warning when using dispatch_async in iOS

我有下面的代码以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 );
        }
    }

}

解决了! 我发现我可以使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM