我的目标是编写一个自定义摄像机视图控制器,用于:
实现(在iOS 4.2 / Xcode 3.2.5上):
由于需求(3),我需要跳转到AVFoundation。
我从技术问答QA1702开始并做了以下修改:
我遇到的问题是处理预览图像(预览“视频”的一个帧)的性能。
首先,我从UIImage获得imageFromSampleBuffer:在示例缓冲区上的captureOutput:didOutputSampleBuffer:fromConnection:结果。然后,我使用CGGraphicsContext缩放并旋转屏幕。
此时,帧速率已经低于会话的视频输出中指定的15 FPS,当我加上效果时,它会下降到10以下或10左右。由于内存不足,应用程序会很快崩溃。
我已经成功地将iPhone 4上的帧速率降到9 FPS,在iPod Touch上降低到8 FPS (第4代)。
我还添加了一些代码来“刷新”调度队列,但我不确定它到底有多大帮助。基本上,每8-10帧设置一个标志,该标志指示captureOutput:didOutputSampleBuffer:fromConnection:立即返回,而不是处理该帧。在输出分派队列上的同步操作完成后,将重置该标志。
在这一点上,我甚至不介意低帧率,但很明显,我们不能与低内存崩溃。在这种情况下,有谁知道如何采取行动防止内存不足(和/或更好的“刷新”调度队列的方法)?
发布于 2011-02-04 21:47:17
为了防止内存问题,只需在captureOutput:didOutputSampleBuffer:fromConnection:中创建一个自动释放池即可。
这是有意义的,因为imageFromSampleBuffer:返回一个自动释放的UIImage对象。另外,它会立即释放由图像处理代码创建的任何自动释放的对象。
// Delegate routine that is called when a sample buffer was written
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Create a UIImage from the sample buffer data
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
< Add your code here that uses the image >
[pool release];
}我的测试表明,这将在iPhone 4或iPod Touch (第4代)上没有内存警告的情况下运行,即使请求FPS非常高(例如60)并且图像处理非常慢(例如0.5+ secs)。
旧解决方案:
正如布拉德所指出的,苹果建议图像处理应该放在后台线程上,这样就不会干扰用户界面响应能力。在本例中,我没有注意到很大的滞后,但最佳实践是最佳实践,因此将以上解决方案与自动释放池一起使用,而不是在主分派队列/主线程上运行该解决方案。
为了防止内存问题,只需使用主分派队列而不是创建新的队列。
这也意味着当您想更新UI时,不必切换到captureOutput:didOutputSampleBuffer:fromConnection:中的主线程。
在setupCaptureSession中,更改如下:
// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);至:
// we want our dispatch to be on the main thread
[output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];https://stackoverflow.com/questions/4893620
复制相似问题