#phonecamera #linuxphone #librem5

Librem 5 camera/kernel can do three possible resolutions, ~1024x768 @ ~24fps, ~2048x.. @ ~31 fps and ~4096x.. @ ~15fps. Debayering is actually easier and better quality if we downscale at the same time, and that allows best framerate, so we do that (2048x.. resolution).

ARM has problems with cache coherency w.r.t. DMA, and kernel solution is to simply disable cache on DMAbufs for userspace, which means accessing video data is 10x slower than it should be on the CPU. Which means debayering on GPU is attractive, and that's what we do. (gold.frag). GPU can do more image signal processing functions easily, too, so we do some of that.

Unfortunately, we hit the same uncached memory problem at the GPU output. So we use separate thread to copy. All this unfortunately does not fit on one core, so we need two threads, one controlling GPU debayer on frame n+1, while the other one copies video data from frame n. (heart.c). We save resulting RGBA data to ramdisk. This all costs maybe 80% of one core.

From there, Python scripts can pick them up: ucam.py displaying the viewfinder and mpegize.py handling the video encoding via gstreamer. There's basically 0% cpu left, but I can encode ~1024x.. video. Unfortunately that's without audio and with viewfinder at 1fps. Plus, combination of C + Python is great for prototyping, but may not be that great for performance.

Code is here: https://gitlab.com/tui/tui/-/tree/master/icam?ref_type=heads .

At this point I'd like viewfinder functionality merged into the rest of GPU processing. Ideally, I'd like to have a bitmap with GUI elements, combine it with scaled RGBA data, and rendering it to screen. I know SDL and Gtk, SDL looked like better match, but I could not get SDL and GPU debayering to work in single process (template SDL code is here https://gitlab.com/tui/debayer-gpu/-/blob/master/sdl/main.c?ref_type=heads ).

If you can integrate main.c and heart.c, that would be welcome. If you have example code that combines SDL with processing on GPU, that would be nice, too. If you know someone who can do GPU/SDL, boost would not be bad, I guess.

@datenwolf
@NekoCWD
@dcz
@martijnbraam

@pavel @datenwolf @dcz @martijnbraam @NekoCWD I played with it over the last days and I already have 526x390 30 FPS encoding with live viewfinder, perfectly synced audio, color correction, lens shading correction, tone mapping, AWB and AE - consuming about 40% CPU. Still needs chromatic shading correction and AF, and I started experimenting with enabling PDAF.

I can also make the sensor output 60 FPS and RAW10. Patches incoming ;) Still only 2 MIPI lanes though, so no 13MP 30FPS yet.

BTW. Recording 30 minutes with screen off ate about 15% of battery, so 3 hours of recording should be possible.

Follow

I think both left- and right-masked PDAF pixels are accessible in 1:2 mode with binning disabled, though I haven't done the math yet to be 100% sure. Enabling/disabling it on demand will be somewhat clunky though. I can also read calibration data from OTP, but AFAIK there are no kernel APIs to expose that to userspace :(
source.puri.sm/Librem5/linux/-

Note that the picture is shifted down-left a bit because the driver was misconfiguring the output parameters to include dummy pixels - fixed that too, along with several out-of-range clocks 👻

Sign in to participate in the conversation
Librem Social

Librem Social is an opt-in public network. Messages are shared under Creative Commons BY-SA 4.0 license terms. Policy.

Stay safe. Please abide by our code of conduct.

(Source code)

image/svg+xml Librem Chat image/svg+xml