Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knowing resolution of AVCaptureSession's session presets

I'm accessing the camera in iOS and using session presets as so:

captureSession.sessionPreset = AVCaptureSessionPresetMedium;

Pretty standard stuff. However, I'd like to know ahead of time the resolution of the video I'll be getting due to this preset (especially because depending on the device it'll be different). I know there are tables online you can look this up (such as here: http://cmgresearch.blogspot.com/2010/10/augmented-reality-on-iphone-with-ios40.html ). But I'd like to be able to get this programmatically so that I'm not just relying on magic numbers.

So, something like this (theoretically):

[captureSession resolutionForPreset:AVCaptureSessionPresetMedium];

which might return a CGSize of { width: 360, height: 480}. I have not been able to find any such API, so far I've had to resort to waiting to get my first captured image and querying it then (which for other reasons in my program flow is not good).

like image 422
Francisco Ryan Tolmasky I Avatar asked Oct 17 '11 07:10

Francisco Ryan Tolmasky I


3 Answers

I am no AVFoundation pro, but I think the way to go is:

captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureInput *input = [captureSession.inputs objectAtIndex:0]; // maybe search the input in array
AVCaptureInputPort *port = [input.ports objectAtIndex:0];
CMFormatDescriptionRef formatDescription = port.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);

I'm not sure about the last step and I didn't try it myself. Just found that in the documentation and think it should work.

Searching for CMVideoDimensions in Xcode you'll find the RosyWriter example project. Have a look at that code (I don't have time to do that now).

like image 146
Christian Beer Avatar answered Oct 21 '22 13:10

Christian Beer


You can programmatically get the resolution from activeFormat before capture begins, though not before adding inputs and outputs: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureDevice_Class/index.html#//apple_ref/occ/instp/AVCaptureDevice/activeFormat

private func getCaptureResolution() -> CGSize {
    // Define default resolution
    var resolution = CGSize(width: 0, height: 0)

    // Get cur video device
    let curVideoDevice = useBackCamera ? backCameraDevice : frontCameraDevice

    // Set if video portrait orientation
    let portraitOrientation = orientation == .Portrait || orientation == .PortraitUpsideDown

    // Get video dimensions
    if let formatDescription = curVideoDevice?.activeFormat.formatDescription {
        let dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription)
        resolution = CGSize(width: CGFloat(dimensions.width), height: CGFloat(dimensions.height))
        if (portraitOrientation) {
            resolution = CGSize(width: resolution.height, height: resolution.width)
        }
    }

    // Return resolution
    return resolution
}
like image 8
Crashalot Avatar answered Oct 21 '22 14:10

Crashalot


FYI, I attach here an official reply from Apple.


This is a follow-up to Bug ID# 13201137.

Engineering has determined that this issue behaves as intended based on the following information:

There are several problems with the included code:

1) The AVCaptureSession has no inputs. 2) The AVCaptureSession has no outputs.

Without at least one input (added to the session using [AVCaptureSession addInput:]) and a compatible output (added using [AVCaptureSession addOutput:]), there will be no active connections, therefore, the session won't actually run in the input device. It doesn't need to -- there are no outputs to which to deliver any camera data.

3) The JAViewController class assumes that the video port's -formatDescription property will be non nil as soon as [AVCaptureSession startRunning] returns.

There is no guarantee that the format description will be updated with the new camera format as soon as startRunning returns. -startRunning starts up the camera and returns when it is completely up and running, but doesn't wait for video frames to be actively flowing through the capture pipeline, which is when the format description would be updated.

You're just querying too fast. If you waited a few milliseconds more, it would be there. But the right way to do this is to listen for the AVCaptureInputPortFormatDescriptionDidChangeNotification.

4) Your JAViewController class creates a PVCameraInfo object in retrieveCameraInfo: and asks it a question, then lets it fall out of scope, where it is released and dealloc'ed.

Therefore, the session doesn't have long enough to run to satisfy your dimensions request. You stop the camera too quickly.

We consider this issue closed. If you have any questions or concern regarding this issue, please update your report directly (http://bugreport.apple.com).

Thank you for taking the time to notify us of this issue.

Best Regards,

Developer Bug Reporting Team Apple Worldwide Developer Relations

like image 7
JongAm Park Avatar answered Oct 21 '22 12:10

JongAm Park