Some images coming soon…!
Background
The idea for this port came from my friend Devin (espidev).
After I finished a lot of the porting work I was stalled by some issues and when university began again I didn’t have much time to work on it anymore. Big thanks to him for picking it up again to push the changes to completion. This post will probability cover a lot of the same ground that his does.
libcamera
V4L2 has long been the standard Linux video capture interface, however, as hardware and software advancements have introduced new features and complexities that people demand as standard, application developers are becoming increasingly burdened. The goal of libcamera as a successor to V4L2 is to wrap these advances into a single, simplified model that is much easier for developers to interact with. Integrating libcamera as a backend for Plasma Camera would give better support for modern cameras and make it easier to add future hardware.
Thanks to the work done by postmarketOS libcamera supports the Pixel 3a’s IMX363 back camera and at the time of writing this are working on the front camera and other improvements to the back camera drivers.
Porting Plasma Camera
The main work I did for this was writing a replacement for QCamera and CaptureSession in the form of PlasmaCamera to manage the camera and PlasmaCameraManager to provide a higher level interface to capture images and record.
Viewfinder
PlasmaCamera spins off a worker thread that allocates some memory for frames then continuously queues requests
to libcamera to take pictures. When a picture is taken libcamera executes a callback function that handles copying the data then returning it to PlasmaCamera.
Photos
When starting a camera, libcamera gives an option for a stream role:
- StillCapture: capture high-resolution, high-quality still images with low frame rate
- VideoRecording: capture video for recording or streaming
- Viewfinder: capture video for display on the local screen (trade-offs between quality and usage of resources)
In an early version of this I wanted to switch to StillCapture when taking a photo however the time it takes to stop and start the camera with the new stream role simply made it a very cumbersome experience. As a result, I choose that when a photo is taken we simply take that image from the viewfinder stream. In the future I would to some sort of computational photography algorithm possibly get an improved image from multiple frames.
Videos
For video recording I simply pass the viewfinder frames to a QVideoFrameInput which passes them to a QMediaCaptureSession. This class handles the encoding of the series of frames into a compressed video format and the muxing of the audio and video streams using ffmpeg.
On the Pixel 3a the default encoding method that ffmpeg tries to use is hardware encoding h264_v4l2m2m
however when it just freezes when trying to encode anything. As a result, I needed to force ffmpeg to use the software encoder libx264
which appears to work well enough.
Settings
The last item I was working on was to connect the more general settings autofocus, exposure value (EV), white balance, exposure time, contrast, saturation, and ISO to libcamera’s config options. While the translation for these settings were done I did not do the final step of connecting the output to the libcamera settings.
Future
I wish I had more time!
Some notes for the future:
The method for recording videos is not very robust as I assume that we can encode at the same rate as we can record however with software encoding this is not always true. I think that this issue could be resolved by getting hardware encoding working or by saving the video into temporary uncompressed chunks and encoding it after recording.
There is currently being work being done to get calibration data for the Pixel 3a so that color tuning files could be created (see here and here)
The libcamera drivers for the phone cameras currently don’t support many controls so while the settings can be implemented they can only be tested on cameras with more support (e.g. a webcam or Raspberry PI)
Features to add in the near or far future:
- resolution settings
- raw capture mode
- pinch to zoom (will crop then upscale image)
- different aspect ratios
- pause the camera stream in the background
- focus area
- exposure compensation for focus area
- exif data (e.g. gps, camera settings, etc)
- image stacking computational photography (see HDR+)
- panorama mode