iPhone Как установить частоту кадров и замедлить AVCapture didOutputSampleBuffer Delegate

Я хочу снизить частоту кадров видеоустройства на iPhone 4S, чтобы делегат didOutputSampleBuffer вызывался реже. Это сделано для повышения производительности, так как я обрабатываю каждый кадр и мне нужен большой кадр для детализации.

При настройке AVSession я пытался использовать следующее:

AVCaptureConnection *conn = [self.output connectionWithMediaType:AVMediaTypeVideo];
[conn setVideoMinFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];
[conn setVideoMaxFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];

Но это не имеет никакого эффекта, я могу изменить CAPTURE_FRAMES_PER_SECOND от 1 до 60 и не вижу разницы в производительности или замедления захвата видео. Почему это не имеет никакого эффекта? Как уменьшить частоту кадров захвата для видеоустройства?

Я настроил свою сессию со следующим кодом:

// Define the devices and the session and the settings
self.session = [[AVCaptureSession alloc] init];

//self.session.sessionPreset = AVCaptureSessionPresetPhoto;
//self.session.sessionPreset = AVCaptureSessionPresetHigh;
self.session.sessionPreset = AVCaptureSessionPreset1280x720;

self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

// Add the video frame output
self.output = [[AVCaptureVideoDataOutput alloc] init];
[self.output setAlwaysDiscardsLateVideoFrames:YES];
self.output.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                                                        forKey:(id)kCVPixelBufferPixelFormatTypeKey];

// A dispatch queue to get frames
dispatch_queue_t queue;
queue = dispatch_queue_create("frame_queue", NULL);

// Setup the frame rate    
AVCaptureConnection *conn = [self.output connectionWithMediaType:AVMediaTypeVideo];
[conn setVideoMinFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];
[conn setVideoMaxFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];

// Setup input and output and set the delegate to self
[self.output setSampleBufferDelegate:self queue:queue];
[self.session addInput:self.input];
[self.session addOutput:self.output];

// Start the session
[self.session startRunning];

Я захватываю кадры, используя реализацию делегата didOutputSampleBuffer ниже:

// The delegate method where we get our image data frames from
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection
{

    // Extract a UImage
    CVPixelBufferRef pixel_buffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixel_buffer];

    // Capture the image
    CGImageRef ref = [self.context createCGImage:ciImage fromRect:ciImage.extent];

    // This sets the captured image orientation correctly
    UIImage *image = [UIImage imageWithCGImage:ref scale:1.0 orientation:UIImageOrientationLeft];

    // Release the CGImage
    CGImageRelease(ref);

    // Update the UI on the main thread but throttle the processing
    [self performSelectorOnMainThread:@selector(updateUIWithCapturedImageAndProcessWithImage:) withObject:image waitUntilDone:YES];

}

person PhilBot    schedule 09.02.2013    source источник


Ответы (3)


Я не уверен, какую iOS вы используете, но обобщите свой код следующим образом:

AVCaptureConnection *conn = [self.output connectionWithMediaType:AVMediaTypeVideo];
if ([conn isVideoMaxFrameDurationSupported] && [conn isVideoMinFrameDurationSupported])
{
  [conn setVideoMinFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];
  [conn setVideoMaxFrameDuration:CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND)];
}

else
  NSLog(@"Setting Max and/or Min frame duration is unsupported";

Тогда идите оттуда. Я подозреваю, что это не поддерживается на вашей iOS.

person Khaled Barazi    schedule 23.02.2013
comment
Здорово. Если это сработало, пожалуйста, отметьте это как правильный ответ. Спасибо - person Khaled Barazi; 25.02.2013

Это частичный ответ: я считаю, что между iOS 5 и iOS 6 произошли изменения в механизме захвата видео Quicktime. В iOS 5 можно было записывать видео со скоростью 60 кадров в секунду, и были некоторые приложения, которые использовали это. для записи для воспроизведения в плавном замедленном темпе (например, приложение SloPro). В iOS 6 уже нельзя было добиться 60 FPS тем же методом. В ветке форума MacRumors есть продолжительное обсуждение этого вопроса:

Позволит ли джейлбрейк iPhone 4S с iOS 6.1 записывать видео с частотой 60 кадров в секунду?

Надеюсь, вы найдете там информацию, которая поможет решить вашу проблему. Мне было бы очень интересно услышать, если кто-нибудь может сделать эту работу снова. Я скучаю по записи в 60 FPS...

person jjw141    schedule 21.02.2013

Похоже, ОП уже знал, как установить частоту кадров, но не знал, почему код не работает.

AVCaptureConnection не будет создан, пока вы не добавите ввод и вывод в сеанс захвата: Документация по AVCaptureConnection.

Поэтому я подозреваю, что «conn» равно нулю. Переместите код в «Установите частоту кадров» после кода в «Настройка ввода и вывода и установите делегата на себя».

person Matt    schedule 13.08.2020