Hey all, I have a pretty complicated camera setup so bear with me.
You know how Instagram's Camera supports recording a video and flipping Camera devices while recording?
I built the same thing using AVCaptureVideoDataOutput and it works fine, but it does not support rotation. (neither does Instagram, but I still need it, lol)
So there's two ways to implement rotation (and mirroring) in AVCaptureVideoDataOutput
:
1. Set it on the AVCaptureConnection
Rotation and vertical mirror mode can be set directly on the AVCaptureVideoDataOutput
's connection to the Camera:
let output = AVCaptureVideoDataOutput(...)
cameraSession.addOutput(output)
for connection in output.connections {
connection.videoRotation = 90
connection.isVideoMirrored = true
}
But according to the documentation this is expensive and comes with a performance overhead. I haven't really benchmarked it yet, but I assume rotating and mirroring 4k buffers isn't cheap.
I'm building a camera library that is used by a lot of people, so all performance decisions have a big impact.
2. Set it on AVAssetWriter
Instead of actually physically rotating large pixel buffers, we can also just set the AVAssetWriter
's transform
property to some affine transformation - which is comparable to how EXIF tags work.
We can set both rotation and mirror modes using CGAffineTransform
s.
Obviously this is much more efficient and does not come with a performance overhead on the camera pipeline at all, so I'd prefer to go this route.
Problem
The problem is that when I start recording with the front Camera (AVAssetWriter.transform
has a mirror on the CGAffineTransform
), and then flip to the back Camera, the back Camera is also mirrored.
Now I thought I could just avoid rotation on my buffers and only use isVideoMirrored
on the AVCaptureConnection
when we are using the front camera, which is a fair performance compromise - but this won't work because isVideoMirrored
applies mirroring alongside the vertical axis - and since the video stream is naturally in landscape orientation, this will flip the image upside down instead of mirroring it alongside the vertical axis... whoops! 😅
This is pretty obvious as the transform
applies to the entire video stream, but now I am not sure if the AVAssetWriter
approach will work for my use-case.
I think I will need to eagerly physically rotate the pixel buffers by setting the AVCaptureConnection
's videoRotation
& isVideoMirrored
properties, but I wanted to ask here in case someone knows any alternatives to doing that in order to avoid the performance and memory overhead of rotating buffers?
Thanks!