Switching AVCaptureSessionPreset before capturing photo

Hello, I'm making live camera filter app following AVCamPhotoFilter sample proejct by Apple.


I use 'AVCaptureVideoDataOutput' to pass samplebuffer to MTKView for rendering preview and 'AVCapturePhotoOutput' for capturing photos.

And my app has some aspect ratio options for capturing photos. (including 16:9 and 4:3)


What I want to do is to make the preview in full screen size (which is 16:9 but anything closer to this would also be fine) although users select 4:3 option.

Of course I'm planning to show border lines inside the preview so that users can figure out the photo ouput size.


I need 16:9 preset option like 1280*720 for the preview and photo preset option for capturing photo.

I came up with few ideas.

1. Having two AVCaptureSessions with different preset --> not good for performance

2. Use 1280*720 preset for capturing and crop the photo output to 4:3 aspect ratio --> low-resolution photos

3. Switch preset just before call 'photoOutput.capturePhoto' method. --> preview freezes for a moment because AVCaptureSession has to be updated


I decided to go with 3, but it gives me an error.

(if there is a better way, please let me know)


this is my code.

@IBAction func takePhoto(_ sender: UIButton) {
     captureSessionQueue.async {
          var photoSettings = AVCapturePhotoSettings()
          photoSettings.isHighResolutionPhotoEnabled = true
     
          // switch preset from .hd1280*720 to .photo
          self.session.beginConfiguration()
          if self.session.canSetSessionPreset(.photo) {
               self.session.sessionPreset = .photo
          }
          self.session.commitConfiguration()

          self.photoOutput.capturePhoto(with: photoSettings, delegate: self)

          self.session.beginConfiguration()
          self.session.sessionPreset = .hd1280*720
          self.session.commitConfiguration()
     }
}

the error is,

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16800), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x280013720 {Error Domain=NSOSStatusErrorDomain Code=-16800 "(null)"}}


I think this is because I call capturePhoto method before the session completes the update to new preset.

when I call 'self.photoOutput.capturePhoto' method 1 or 2 seconds after the commitConfiguration(), it works.


So, is there any way that I can know the completion of AVCaptureSession updates or is there a better solution dealing with different aspect ratio between the video data output and photo output?