我正在使用 AV Foundation 处理来自摄像机(iPhone 4s、iOS 6.1.2)的帧。我正在根据 AV Foundation 编程指南设置 AVCaptureSession、AVCaptureDeviceInput、AVCaptureVideoDataOutput。一切都按预期工作,我能够在 captureOutput:didOutputSampleBuffer:fromConnection:
委托(delegate)中接收帧。
我也有一个像这样设置的预览层:
AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[videoPreviewLayer setFrame:self.view.bounds];
videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer insertSublayer:videoPreviewLayer atIndex:0];
问题是,我的帧处理不需要每秒 30 帧,而且我也无法如此快速地处理它们。所以我使用这段代码来限制帧持续时间:
// videoOutput is AVCaptureVideoDataOutput set earlier
AVCaptureConnection *conn = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
[conn setVideoMinFrameDuration:CMTimeMake(1, 10)];
[conn setVideoMaxFrameDuration:CMTimeMake(1, 2)];
这工作正常并限制了 captureOutput 委托(delegate)接收的帧。
但是,这也限制了预览层上的每秒帧数,并且预览视频变得非常无响应。
我从文档中了解到,帧持续时间是在连接上独立设置的,预览层确实具有不同的 AVCaptureConnection。检查 [videoPreviewLayer connection]
上的混合/最大帧持续时间表明它确实设置为默认值(1/30 和 1/24)并且不同于 AVCaptureVideoDataOutput 连接上设置的持续时间。
那么,是否可以仅在帧捕获输出上限制帧持续时间,并在预览视频中仍然看到 1/24-1/30 帧持续时间?怎么办?
谢谢。
最佳答案
虽然您认为有两个 AVCaptureConnection
是正确的,但这并不意味着它们可以独立设置最小和最大帧持续时间。这是因为它们共享相同的物理硬件。
如果连接 #1 以(比如说)五帧/秒的速率激活卷帘快门,帧持续时间为 1/5 秒,不可能连接 #2 可以同时以 1/30 秒的帧持续时间激活快门 30 次/秒。
要获得您想要的效果,需要两个摄像头!
接近您想要的东西的唯一方法是遵循 Kaelin Colclasure 在 3 月 22 日的回答中概述的方法。
但是,您确实可以选择在该方法中稍微复杂一些。例如,您可以使用计数器来决定丢弃哪些帧,而不是让线程休眠。您可以使该计数器响应正在通过的实际帧速率(您可以从传入 captureOutput:didOutputSampleBuffer:fromConnection:
委托(delegate)的元数据中获取该帧速率以及图像数据,或者您可以通过手动为帧计时来计算自己)。您甚至可以通过合成帧而不是丢弃它们来非常合理地模仿更长的曝光时间——就像 App Store 中的许多“慢快门”应用程序所做的那样(撇开细节——例如不同的卷帘快门人工制品——实际上并没有 以 1/5 秒扫描一帧与以 1/25 秒扫描五帧然后粘合在一起之间有很大差异)。
是的,这需要做一些工作,但您正试图让一台摄像机像两台摄像机一样实时运行 — 这绝非易事。
关于ios - AV 基金会 : AVCaptureVideoPreviewLayer and frame duration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15527822/