objective-cmacosavcapturesessionavcaptureavcaptureoutput

AVCaptureSession resolution doesn't change with AVCaptureSessionPreset


I want to change the resolution of pictures I take with the camera on OS X with AV Foundation.

But even if I change the resolution of my AVCaptureSession, the output picture size doesn't change. I always have a 1280x720 picture.

I want a lower resolution because I use these pictures in a real time process and I want the program to be faster.

This is a sample of my code:

 session = [[AVCaptureSession alloc] init];

if([session canSetSessionPreset:AVCaptureSessionPreset640x360]) {
    [session setSessionPreset:AVCaptureSessionPreset640x360];
}

AVCaptureDeviceInput *device_input = [[AVCaptureDeviceInput alloc] initWithDevice:
                                       [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0] error:nil];

if([session canAddInput:device_input])
    [session addInput:device_input];

still_image = [[AVCaptureStillImageOutput alloc] init];

NSDictionary *output_settings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[still_image setOutputSettings : output_settings];

[session addOutput:still_image];

What should I change in my code?


Solution

  • I have also run into this issue and found a solution that seems to work. For some reason on OS X, StillImageOutput breaks the capture session presets.

    What I did was change the AVCaptureDevice's active format directly. Try this code right after you add your StillImageOutput to your Capture Session.

    //Get a list of supported formats for the device
    NSArray *supportedFormats = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0] formats];
    
    //Find the format closest to what you are looking for
    //  this is just one way of finding it
    NSInteger desiredWidth = 640;
    AVCaptureDeviceFormat *bestFormat;
    for (AVCaptureDeviceFormat *format in supportedFormats) {
        CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions((CMVideoFormatDescriptionRef)[format formatDescription]);
        if (dimensions.width <= desiredWidth) {
            bestFormat = format;
        }
    }
    
    [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0] lockForConfiguration:nil];
    [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0] setActiveFormat:bestFormat]; 
    [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0] unlockForConfiguration];
    

    It is possible that there are other ways of fixing this issue but this is fixed it for me.