4

我想降低 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];

}
4

3 回答 3

1

这是部分答案:我相信 iOS 5 和 iOS 6 之间的 Quicktime 视频捕获引擎发生了变化。在 iOS 5 中,可以以 60 FPS 的速度捕获视频,并且有一些应用程序利用了这一点以流畅的慢动作录制回放(例如 SloPro 应用程序)。在 iOS 6 中,使用相同的方法不再可能达到 60 FPS。MacRumors 论坛帖子中对此问题进行了长时间的讨论:

iPhone 4S、iOS 6.1 越狱后可以录制 60 FPS 视频吗?

希望您可以在那里找到一些可能为您的问题提供解决方案的信息。我很想知道是否有人可以再次进行这项工作。我怀念以 60 FPS 录制...

于 2013-02-21T14:30:06.103 回答
1

我不确定您正在运行什么 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 不支持它。

于 2013-02-23T20:50:12.237 回答
0

看起来 OP 已经知道如何设置帧速率,但不知道代码为什么不起作用。

在将输入和输出添加到捕获会话之前,不会创建 AVCaptureConnection:AVCaptureConnection 文档

所以我怀疑'conn'是空的。将“设置帧速率”中的代码移到“设置输入和输出并将委托设置为自身”中的代码之后。

于 2020-08-13T16:47:56.697 回答