I believe this used to be done with captureOutput.minFrameDuration
. However, this is deprecated in iOS 5.
Instead I apparently need to use AVCaptureConnection
's video.minFrameDuration
. So I have my input, my output, I add them both the the capture session - where can I get access to the capture connection? I think it is created for me by the session, but where?
I could try adding the I/O using addInputWithNoConnections
and addOutputWithNoConnections
and then maybe creating the connection manually. But this seems like a bit of hassle just to set a maximum frame rate. Plus, Xcode complains that these methods don't exist.
Chris, I think I have solved this problem:
(Edit -- See Tomas Camin's comment below on correct way of checking whether videoMinFrameDuration videoMaxFrameDuration are supported, although below code worked fine when posted)
The line below gives access to the AVCaptureConnection
object associated with the AVCaptureVideoDataOutput
object:
AVCaptureConnection *conn = [output connectionWithMediaType:AVMediaTypeVideo];
CMTimeShow(conn.videoMinFrameDuration);
CMTimeShow(conn.videoMaxFrameDuration);
if (conn.isVideoMinFrameDurationSupported)
conn.videoMinFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);
if (conn.isVideoMaxFrameDurationSupported)
conn.videoMaxFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);
CMTimeShow(conn.videoMinFrameDuration);
CMTimeShow(conn.videoMaxFrameDuration);
If you're using (as I am), the didOutputSampleBuffer
delegate, you can confirm that the video frame rate in the fromConnection
AVCaptureConnection * value passed in to the delegate has been correctly set and "remembered" by the above code.
Note that you need to set both videoMinFrameDuration
and videoMaxFrameDuration
to the same value to successfully clamp the frame rate -- setting min on its own did not seem to work when testing on an iPhone 4s. This doesn't seem to be documented.
Josh
AVCaptureConnection
videoMinFrameDuration
is deprecated. Use AVCaptureDevice
activeVideoMinFrameDuration
/activeVideoMaxFrameDuration
. First code snippet in AVCaptureDevice class reference answers the question.
Assume the following members.
AVCaptureConnection *videoConnection;
AVCaptureVideoDataOutput *videoOutput;
AVCaptureDeviceInput *videoInput;
Then you would do something like the following. I have not tested this. This is just a guess from reading the docs.
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ( videoDevice ) {
NSError *error;
videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
[captureSession addInput:videoInput];
}
videoOutput = [[AVCaptureVideoDataOutput alloc] init];
//setup video options
if ([captureSession canAddOutput:videoOutput])
[captureSession addOutput:videoOutput];
videoConnection = [[AVCaptureConnection alloc] initWithInputPorts:captureSession.inputs output:videoOutput];
videoConnection.videoMinFrameDuration = CMTimeMake(1, frameRate);
[captureSession addConnection:videoConnection];
I have not converted my own code over to this yet. I will respond back with working code when I do the conversion. If you have multiple inputs added to the captureSession then you may need to explicitly load the one you want into an array. e.g.
ports = [NSArray arrayWithObject:videoInput];
Then pass this into the initializer for the AVCaptureConnection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With