gpt4 book ai didi

iphone - 将效果应用于iPhone相机预览 "Video"

转载 作者:行者123 更新时间:2023-12-03 19:37:16 36 4
gpt4 key购买 nike

我的目标是编写一个自定义相机 View Controller :

  1. 可以使用后置摄像头和前置摄像头(如果有)以所有四个界面方向拍照。
  2. 正确旋转和缩放预览“视频”以及全分辨率照片。
  3. 允许将(简单)效果应用于预览“视频”和全分辨率照片。

实现(在 iOS 4.2/Xcode 3.2.5 上):

由于要求(3),我需要下拉到 AVFoundation。

我从 Technical Q&A QA1702 开始并进行了这些更改:

  1. 将 sessionPreset 更改为 AVCaptureSessionPresetPhoto。
  2. 在启动 session 之前添加了 AVCaptureStillImageOutput 作为附加输出。

我遇到的问题是处理预览图像(预览“视频”的一帧)的性能。

首先,我得到 imageFromSampleBuffer: 的 UIImage 结果在 captureOutput:didOutputSampleBuffer:fromConnection: 的样本缓冲区上。然后,我使用 CGGraphicsContext 在屏幕上缩放和旋转它。

此时,帧速率已经低于 session 视频输出中指定的 15 FPS,当我添加效果时,帧速率降至 10 以下或左右。由于内存不足,应用程序很快崩溃.

我成功地将 iPhone 4 上的帧速率降至 9 FPS,将 iPod Touch(第 4 代)的帧速率降至 8 FPS。

我还添加了一些代码来“刷新”调度队列,但我不确定它实际上有多大帮助。基本上,每 8-10 帧就会设置一个标志来指示 captureOutput:didOutputSampleBuffer:fromConnection:立即返回而不是处理帧。输出调度队列上的同步操作完成后,该标志会重置。

在这一点上,我什至不介意低帧速率,但显然我们不能忍受低内存崩溃。任何人都知道如何采取措施来防止这种情况下的低内存情况(和/或“刷新”调度队列的更好方法)?

最佳答案

要防止内存问题,只需在 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];
}

我的测试表明,即使请求的 FPS 非常高(例如 60)并且图像处理非常慢(例如 0.5+ 秒),这也将在 iPhone 4 或 iPod Touch(第 4 代)上运行而不会出现内存警告。

旧解决方案:

正如 Brad 指出的那样,Apple 建议在后台线程上进行图像处理,以免干扰 UI 响应能力。在这种情况下,我没有注意到太多延迟,但最佳实践就是最佳实践,因此将上述解决方案与自动释放池一起使用,而不是在主调度队列/主线程上运行它。

为了防止内存问题,只需使用主调度队列而不是创建新的队列。

这也意味着当您想要更新 UI 时,不必在 captureOutput:didOutputSampleBuffer:fromConnection: 中切换到主线程。

setupCaptureSession中,更改FROM:

// 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()];

关于iphone - 将效果应用于iPhone相机预览 "Video",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4893620/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com