2015-10-16 5 views
0

Привет Я использую PBJVision для обработки видео iOS. При установке двойной частоты кадров по умолчанию 24 кадра в секунду -> 48 кадров в секунду. Я получаю следующую ошибку:48 fps вызывает sigart on activeVideoMinFrameDuration update

2015-10-16 15:02:48.929 RecordGram[2425:515618] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureVideoDevice setActiveVideoMinFrameDuration:] - the passed activeFrameDuration 1:48 is not supported by the device. Use -activeFormat.videoSupportedFrameRateRanges to discover valid ranges.' 

Вот этот метод из PBJVision, где произошла ошибка. Я выделил строку с ошибкой. Обратите внимание, что метод supportsVideoFrameRate: возвращает true.

// framerate 

- (void)setVideoFrameRate:(NSInteger)videoFrameRate 
{ 
if (![self supportsVideoFrameRate:videoFrameRate]) { 
    DLog(@"frame rate range not supported for current device format"); 
    return; 
} 

BOOL isRecording = _flags.recording; 
if (isRecording) { 
    [self pauseVideoCapture]; 
} 

CMTime fps = CMTimeMake(1, (int32_t)videoFrameRate); 

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { 

    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceFormat *supportingFormat = nil; 
    int32_t maxWidth = 0; 

    NSArray *formats = [videoDevice formats]; 
    for (AVCaptureDeviceFormat *format in formats) { 
     NSArray *videoSupportedFrameRateRanges = format.videoSupportedFrameRateRanges; 
     for (AVFrameRateRange *range in videoSupportedFrameRateRanges) { 

      CMFormatDescriptionRef desc = format.formatDescription; 
      CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(desc); 
      int32_t width = dimensions.width; 
      if (range.minFrameRate <= videoFrameRate && videoFrameRate <= range.maxFrameRate && width >= maxWidth) { 
       supportingFormat = format; 
       maxWidth = width; 
      } 

     } 
    } 

    if (supportingFormat) { 
     NSError *error = nil; 
     if ([_currentDevice lockForConfiguration:&error]) { 
      _currentDevice.activeVideoMinFrameDuration = fps; <<<<<<======ERROR IS HERE, THIS LINE IS WHERE THE ERROR OCCURS 
      _currentDevice.activeVideoMaxFrameDuration = fps; 
      _videoFrameRate = videoFrameRate; 
      [_currentDevice unlockForConfiguration]; 
     } else if (error) { 
      DLog(@"error locking device for frame rate change (%@)", error); 
     } 
    } 

    [self _enqueueBlockOnMainQueue:^{ 
     if ([_delegate respondsToSelector:@selector(visionDidChangeVideoFormatAndFrameRate:)]) 
      [_delegate visionDidChangeVideoFormatAndFrameRate:self]; 
    }]; 

} else { 

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wdeprecated-declarations" 
    AVCaptureConnection *connection = [_currentOutput connectionWithMediaType:AVMediaTypeVideo]; 
    if (connection.isVideoMaxFrameDurationSupported) { 
     connection.videoMaxFrameDuration = fps; 
    } else { 
     DLog(@"failed to set frame rate"); 
    } 

    if (connection.isVideoMinFrameDurationSupported) { 
     connection.videoMinFrameDuration = fps; 
     _videoFrameRate = videoFrameRate; 
    } else { 
     DLog(@"failed to set frame rate"); 
    } 

    [self _enqueueBlockOnMainQueue:^{ 
     if ([_delegate respondsToSelector:@selector(visionDidChangeVideoFormatAndFrameRate:)]) 
      [_delegate visionDidChangeVideoFormatAndFrameRate:self]; 
    }]; 
#pragma clang diagnostic pop 

} 

if (isRecording) { 
    [self resumeVideoCapture]; 
} 
} 

Вот supportsVideoFrameRate: метод

- (BOOL)supportsVideoFrameRate:(NSInteger)videoFrameRate 
{ 
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { 
    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    NSArray *formats = [videoDevice formats]; 
    for (AVCaptureDeviceFormat *format in formats) { 
     NSArray *videoSupportedFrameRateRanges = [format videoSupportedFrameRateRanges]; 
     for (AVFrameRateRange *frameRateRange in videoSupportedFrameRateRanges) { 
      if ((frameRateRange.minFrameRate <= videoFrameRate) && (videoFrameRate <= frameRateRange.maxFrameRate)) { 
       return YES; 
      } 
     } 
    } 

} else { 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wdeprecated-declarations" 
    AVCaptureConnection *connection = [_currentOutput connectionWithMediaType:AVMediaTypeVideo]; 
    return (connection.isVideoMaxFrameDurationSupported && connection.isVideoMinFrameDurationSupported); 
#pragma clang diagnostic pop 
} 

return NO; 
} 

Кто-нибудь есть какие-нибудь идеи?

ответ

0

Проблема заключается в том, что «Активное устройство» или «activeFormat» - это не то, что проверяет код из PBJVision. Он проверяет все форматы и устройство по умолчанию ...

Так что для лицевой камеры 48 кадров в секунду не поддерживается. простая проверка:

RGLog(@"default video frame rate = %ld", (long)[vision videoFrameRate]); 
bool supportsDouble = [vision supportsVideoFrameRate:2*[vision videoFrameRate]]; 
bool supportsQuad = [vision supportsVideoFrameRate:4*[vision videoFrameRate]]; 
bool supportsHalf = [vision supportsVideoFrameRate:[vision videoFrameRate]/2]; 
bool supportsQuarter = [vision supportsVideoFrameRate:[vision videoFrameRate]/4]; 
RGLog(@"x2 = %d, x4 = %d, /2 = %d, /4 = %d", supportsDouble, supportsQuad, supportsHalf, supportsQuarter); 

который регистрирует

2015-10-16 15:32:24.279 RecordGram[2436:519667] default video frame rate = 24 
2015-10-16 15:32:24.280 RecordGram[2436:519667] x2 = 0, x4 = 0, /2 = 1, /4 = 1 

После изменения метода supportsVideoFrameRate: посмотреть на _currentDevice вместо [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]

- (BOOL)supportsVideoFrameRate:(NSInteger)videoFrameRate 
{ 
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { 
    AVCaptureDevice *videoDevice = _currentDevice//[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    NSArray *formats = [videoDevice formats]; 
    for (AVCaptureDeviceFormat *format in formats) { 
     NSArray *videoSupportedFrameRateRanges = [format videoSupportedFrameRateRanges]; 
     for (AVFrameRateRange *frameRateRange in videoSupportedFrameRateRanges) { 
      if ((frameRateRange.minFrameRate <= videoFrameRate) && (videoFrameRate <= frameRateRange.maxFrameRate)) { 
       return YES; 
      } 
     } 
    } 

} else { 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wdeprecated-declarations" 
    AVCaptureConnection *connection = [_currentOutput connectionWithMediaType:AVMediaTypeVideo]; 
    return (connection.isVideoMaxFrameDurationSupported && connection.isVideoMinFrameDurationSupported); 
#pragma clang diagnostic pop 
} 

return NO; 
}