【问题标题】:Set a custom AVFrameRateRange for an AVCaptureSession为 AVCaptureSession 设置自定义 AVFrameRateRange
【发布时间】:2014-03-03 22:43:02
【问题描述】:

我正在尝试使用 AVCaptureSession 每秒拍摄 5 张照片,但我不确定我是否理解 AVFrameRange 的含义。目前我有一些设置设备的代码:

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

并尝试将activeVideoMinFrameDurationactiveVideoMaxFrameDuration 设置为自定义值CMTimeMake(1, 5)。 Apple 告诉我我只能使用他们提供的 AVFrameRanges 之一。

当我对它们进行 NSLogged 时,我得到 (2, 30)、(2,60) 和 (2,24)。我首先想知道这意味着什么?这是相机运行的帧速率还是捕获帧的间隔(即我正在尝试做的事情)?

如果不是,我该怎么做才能在我的 sampleBufferDelegate 方法上每秒保存 5 帧?目前它给了我每一帧,因为每次有帧时都会调用该方法,所以我只需要一些关于如何每秒抓取 5 帧的指针。

【问题讨论】:

标签: ios objective-c avcapturesession avcapturedevice


【解决方案1】:

选择自定义帧率的代码如下 - 为Apple RosyWriter 添加检查以验证当前格式是否支持所选的 FPS

- (void)configureCamera:(AVCaptureDevice *)videoDevice withFrameRate:(int)desiredFrameRate
{
    BOOL isFPSSupported = NO;
    AVCaptureDeviceFormat *currentFormat = [videoDevice activeFormat];
    for ( AVFrameRateRange *range in currentFormat.videoSupportedFrameRateRanges ) {
        if ( range.maxFrameRate >= desiredFrameRate && range.minFrameRate <= desiredFrameRate )        {
            isFPSSupported = YES;
            break;
        }
    }

    if( isFPSSupported ) {
        if ( [videoDevice lockForConfiguration:NULL] ) {
            videoDevice.activeVideoMaxFrameDuration = CMTimeMake( 1, desiredFrameRate );
            videoDevice.activeVideoMinFrameDuration = CMTimeMake( 1, desiredFrameRate );
            [videoDevice unlockForConfiguration];
        }
    }
}

如果当前格式 (activeFormat) 不支持您选择的 FPS,请使用以下代码更改 activeFormat,然后选择 FPS。不过需要获取格式尺寸以满足您的需求。

- (void)configureCamera:(AVCaptureDevice *)device withFrameRate:(int)desiredFrameRate
{
    AVCaptureDeviceFormat *desiredFormat = nil;
    for ( AVCaptureDeviceFormat *format in [device formats] ) {
        for ( AVFrameRateRange *range in format.videoSupportedFrameRateRanges ) {
            if ( range.maxFrameRate >= desiredFrameRate && range.minFrameRate <= desiredFrameRate ) {
                desiredFormat = format;
                goto desiredFormatFound;
            }
        }
    }

    desiredFormatFound:
    if ( desiredFormat ) {
        if ( [device lockForConfiguration:NULL] == YES ) {
            device.activeFormat = desiredFormat ;
            device.activeVideoMinFrameDuration = CMTimeMake ( 1, desiredFrameRate );
            device.activeVideoMaxFrameDuration = CMTimeMake ( 1, desiredFrameRate );
            [device unlockForConfiguration];
        }
    }
}

注意:不推荐使用 AVCaptureConnection videoMinFrameDuration 来设置 FPS。

【讨论】:

  • 这对我来说是正确的答案。一个提示是调用avSession.addInput后,activeFormat会发生变化。所以我在 addInput 之后调用该方法。对我来说,它在分辨率为 640x480 的 iphone7 上正常工作,但在分辨率为 1280x720 的情况下就不行了,在这种情况下,图像似乎被分割并错误填充。
【解决方案2】:

这是我们使用的将帧速率设置为每秒 5 的工作代码。

如果您在使用此代码时测量对 CaptureOutput 的调用,您可以看到每 200 毫秒调用一次相机帧(即每秒 5 帧。)(我们刚刚对此进行了测试以确认。)

更改 desiredFrameRate 以获得其他相机帧速率。

- (void)attemptToConfigure5FPS
{
    NSError *error;
    if (![self lockForConfiguration:&error]) {
        NSLog(@"Could not lock device %@ for configuration: %@", self, error);
        return;
    }

    AVCaptureDeviceFormat *format = self.activeFormat;
    double epsilon = 0.00000001;

    int desiredFrameRate = 5;

    for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {

            if (range.minFrameRate <= (desiredFrameRate + epsilon) &&
            range.maxFrameRate >= (desiredFrameRate - epsilon)) {

            self.activeVideoMaxFrameDuration = (CMTime){
                .value = 1,
                .timescale = desiredFrameRate,
                .flags = kCMTimeFlags_Valid,
                .epoch = 0,
            };
            self.activeVideoMinFrameDuration = (CMTime){
                .value = 1,
                .timescale = desiredFrameRate,
                .flags = kCMTimeFlags_Valid,
                .epoch = 0,
            };           
            break;
        }
    }

    [self unlockForConfiguration];
}

【讨论】:

  • 请务必记住在帧速率更改时致电-[AVCaptureDevice lockForConfiguration:]。在我这样做之前,我得到了例外。
猜你喜欢
  • 1970-01-01
  • 2017-04-19
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多