美文网首页
ios/macOS 视频采集-分辨率,帧率(4)

ios/macOS 视频采集-分辨率,帧率(4)

作者: yxibng | 来源:发表于2021-04-06 14:40 被阅读0次

    参考demo AppleVideoCapturer

    分辨率

    1. 通过 AVCaptureSession的sessionPreset来控制采集分辨率
    2. 通过AVCaptureDevice的activeFormat来控制。
    3. 其中通过activeFormat还可以实现高帧率模式的采集

    sessionPreset

    A constant value indicating the quality level or bit rate of the output.

    决定了输出的质量还有比特率。

    You use this property to customize the quality level or bit rate of the output. For possible values of sessionPreset, see AVCaptureSessionPreset. The default value is
    AVCaptureSessionPresetHigh.
    You can set this value while the session is running.
    You can only set a preset if canSetSessionPreset: returns YES f or that preset.

    通过该属性,可以设置输出的视频质量还有比特率。默认是AVCaptureSessionPresetHigh。 可以在运行中设置,设置前需要检查是否支持canSetSessionPreset:返回YES

        if ([self.session canSetSessionPreset:AVCaptureSessionPreset640x480]) {
            [self.session setSessionPreset:AVCaptureSessionPreset640x480];
        }
    

    activeFormat

    The currently active media data format of the capture device.

    当前设备处于激活状态的媒体数据格式。

    1. ios平台,通过设置 AVCaptureSession sessionPreset 来配置图片和视频的采集。通过AVAudioSession 来配置音频采集。
    2. 当使用sessionPreset的时候,AVCaptureSession会自动控制采集设备的activeFormat。 但是一些特殊的配置选项,例如(高帧率),不可以使用sessionPreset来配置。
    3. 设置一个不存在的formats,会抛出异常
    4. 修改属性之前,需要保证线程安全,配置前调用lockForConfiguration:,结束调用unlockForConfiguration
    5. 当修改了activeFormat之后,AVCaptureSession的sessionPreset会自动被修改为AVCaptureSessionPresetInputPriority。 此时采集的配置以activeFormat为主。

    macOS 设置采集分辨率

    参考: mac-osx-avfoundation-video-capture

    _session = [[AVCaptureSession alloc] init];
    _sessionInput = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
    _sessionOutput = [[AVCaptureVideoDataOutput alloc] init];
    
    NSDictionary *pixelBufferOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithDouble:width], (id)kCVPixelBufferWidthKey,
                                  [NSNumber numberWithDouble:height], (id)kCVPixelBufferHeightKey,
                                  [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,
                                  nil];
    [_sessionOutput setVideoSettings:pixelBufferOptions];
    

    帧率的控制

    通过 AVCaptureDevice 的activeVideoMinFrameDurationactiveVideoMaxFrameDuration 来控制采集帧率

    if ([self.videoDeviceInput.device lockForConfiguration:nil]) {
        //最小帧间隔,反过来就是最大帧率, 20fps
        self.videoDeviceInput.device.activeVideoMinFrameDuration = CMTimeMake(1, 20);
        //最大帧间隔,反过来就是最小帧率,15fps
        self.videoDeviceInput.device.activeVideoMaxFrameDuration = CMTimeMake(1, 15);
        [self.videoDeviceInput.device unlockForConfiguration];
    }
    

    高帧率

    如何获取ios设备的最高帧率, 参考Apple code

    func configureCameraForHighestFrameRate(device: AVCaptureDevice) {
        
        var bestFormat: AVCaptureDevice.Format?
        var bestFrameRateRange: AVFrameRateRange?
    
        for format in device.formats {
            for range in format.videoSupportedFrameRateRanges {
                if range.maxFrameRate > bestFrameRateRange?.maxFrameRate ?? 0 {
                    bestFormat = format
                    bestFrameRateRange = range
                }
            }
        }
        
        if let bestFormat = bestFormat, 
           let bestFrameRateRange = bestFrameRateRange {
            do {
                try device.lockForConfiguration()
                
                // Set the device's active format.
                device.activeFormat = bestFormat
                
                // Set the device's min/max frame duration.
                let duration = bestFrameRateRange.minFrameDuration
                device.activeVideoMinFrameDuration = duration
                device.activeVideoMaxFrameDuration = duration
                
                device.unlockForConfiguration()
            } catch {
                // Handle error.
            }
        }
    }
    

    webrtc 设置帧率的代码

    - (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device {
      NSArray<AVCaptureDeviceFormat *> *formats =
          [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:device];
      int targetWidth = [_settings currentVideoResolutionWidthFromStore];
      int targetHeight = [_settings currentVideoResolutionHeightFromStore];
      AVCaptureDeviceFormat *selectedFormat = nil;
      int currentDiff = INT_MAX;
      for (AVCaptureDeviceFormat *format in formats) {
        CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
        FourCharCode pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription);
        int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height);
        if (diff < currentDiff) {
          selectedFormat = format;
          currentDiff = diff;
        } else if (diff == currentDiff && pixelFormat == [_capturer preferredOutputPixelFormat]) {
          selectedFormat = format;
        }
      }
      return selectedFormat;
    }
    - (NSInteger)selectFpsForFormat:(AVCaptureDeviceFormat *)format {
      Float64 maxSupportedFramerate = 0;
      for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) {
        maxSupportedFramerate = fmax(maxSupportedFramerate, fpsRange.maxFrameRate);
      }
      return fmin(maxSupportedFramerate, kFramerateLimit);
    }
    

    相关文章

      网友评论

          本文标题:ios/macOS 视频采集-分辨率,帧率(4)

          本文链接:https://www.haomeiwen.com/subject/qaiskltx.html