AV 基础:AVCaptureVideoPreviewLayer 和帧持续时间

dan*_*elv 6 cocoa-touch objective-c avfoundation ios

我正在使用 AV Foundation 处理来自摄像机的帧(iPhone 4s、iOS 6.1.2)。我正在根据 AV Foundation 编程指南设置 AVCaptureSession、AVCaptureDeviceInput、AVCaptureVideoDataOutput。一切都按预期进行,我能够在captureOutput:didOutputSampleBuffer:fromConnection:代表中收到帧。

我还有一个这样的预览图层集:

AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[videoPreviewLayer setFrame:self.view.bounds];
videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer insertSublayer:videoPreviewLayer atIndex:0];
Run Code Online (Sandbox Code Playgroud)

问题是,我的帧处理不需要每秒 30 帧,而且无论如何我也无法如此快地处理它们。所以我使用此代码来限制帧持续时间:

// videoOutput is AVCaptureVideoDataOutput set earlier
AVCaptureConnection *conn = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
[conn setVideoMinFrameDuration:CMTimeMake(1, 10)];
[conn setVideoMaxFrameDuration:CMTimeMake(1, 2)];
Run Code Online (Sandbox Code Playgroud)

这工作正常并限制captureOutput委托接收的帧。

但是,这也限制了预览层的每秒帧数,并且预览视频变得非常无响应。

我从文档中了解到,帧持续时间是在连接上独立设置的,并且预览层确实具有不同的 AVCaptureConnection。检查混合/最大帧持续时间[videoPreviewLayer connection]表明它确实设置为默认值(1/30 和 1/24),并且与 AVCaptureVideoDataOutput 连接上设置的持续时间不同。

那么,是否可以仅在帧捕获输出上限制帧持续时间,而在预览视频上仍然看到 1/24-1/30 帧持续时间?如何?

谢谢。

Wil*_*ker 5

虽然您是正确的,有两个AVCaptureConnections,但这并不意味着它们可以独立设置最小和最大帧持续时间。这是因为它们共享相同的物理硬件

\n\n

如果连接 #1 以 5 帧/秒的速率激活卷帘快门,帧持续时间为 1/5 秒,则连接 #2不可能同时以 30 次/秒的速度激活卷帘快门持续时间 1/30 秒。

\n\n

要获得您想要的效果,需要两个摄像头!

\n\n

接近您想要的唯一方法是遵循 Kaelin Colclasure 在 3 月 22 日的答复中概述的方法。

\n\n

不过,您确实可以选择在该方法中变得更加复杂一些。例如,您可以使用计数器来决定丢弃哪些帧,而不是让线程休眠。您可以使该计数器响应正在通过的实际帧速率(您可以从与图像数据一起进入委托的元数据中获取该帧速率captureOutput:didOutputSampleBuffer:fromConnection:,或者您可以通过手动计时帧来自行计算) 。您甚至可以通过合成帧而不是丢弃它们来对较长的曝光进行非常合理的模仿\xe2\x80\x94,就像App Store中的许多“慢快门”应用程序所做的那样(不考虑细节\xe2\x80\x94,例如不同的卷帘快门伪像\xe2\x80\x94以 1/5 秒扫描一帧和每以 1/25 秒扫描五帧然后粘合在一起之间并没有太大区别)

\n\n

是的,这需要一些工作,但是您正试图让一台摄像机实时表现得像两台摄像机\xe2\x80\x94,而这绝非易事。

\n