# Announcing libobscura

Let me formally introduce you to my most recent overly-ambitious experiment: *libobscura*.

libobscura

**Libobscura is a friendly library to use cameras on Linux.**

At least that's the goal.

## What does "friendly" mean?

TL;DR: with the simple buffer API you can get a frame in 6 calls, and map it to CPU in another 2:

```
let cameras_list = vidi::actors::camera_list::spawn()?;
let cameras = cameras_list.cameras();
let camera = cameras_list.create(&cameras[0].info.id)
    .expect("No such camera")
    .expect("Failed to create camera");

let mut camera = camera.acquire();
if let Ok(ref mut camera) = camera {
    let mut stream = camera.start(
        Config{fourcc: FourCC::new(b"YUYV")},
        4
    ).unwrap();
    loop {
        let (buf, meta, _next) = stream.next().unwrap();
        let mmap = buf.memory_map_ro().unwrap();
        let data = mmap.as_slice();
    }
}
```

Go to project examples for more.

A baby placing a missing block. They are stacked in the Bayer pattern.

Figure 1: Libobscura will never be friendly enough for every audience.

## What cameras?

Any webcams, industrial cameras, image sensors working exposed by the V4L2 interface are currently in scope.

## What does "experiment" mean?

There are already other libraries for camera support on Linux. You can use the V4L2 APIs directly, or use libcamera, or libmegapixels.

They all strike various middle points on the power vs user-friendliness scale. Having worked with all of them while developing camera support for the Librem 5, I never got the impression that any of them are particularly easy to use.

Libobscura is an experiment because it tries to find an API that fulfills the needs of most people and remains hard to use wrong.

A diagram showing two axes: vertically ease of use and horizontally covered use cases. A couple of projects are positioned below an area called "unexplored", whichis itself under am area called "unachievable". The borders are roughly moving to less easy to use as covered use cases grow.

Figure 2: My "Perfect tool" conjecture. Imagine you have a perfectly well useable tool covering some of your needs. If your needs grow, the perfect tool covering those tools cannot be easier to use than your old tool. And humans are imperfect. This applies to APIs, as well. I put my rough idea of where I think a couple of examples fall. Libcamera tries to be as general as possible, so it's on the far right. OpenCV has Python bindings, so it's up top. Libobscura starts out a bit to the left and top, and I hope to push it to the right, to explore how many use cases can be added while staying easy.

Perhaps it's impossible to improve on what current libraries do. But now libobscura is a space where it's possible to try out radical changes without bothering the maintainers of existing libraries – for example, to try out an entirely new approach.

## Radical approaches

There are a couple of radical approaches in libobscura that earn it the "experiment" status.

### Rust

Rust is a memory-safe systems language. Libobscura uses it to ensure that the APIs are hard to use wrong. A Rust API built with a little care does not let you crash with a segfault – the compiler will alert you before you can create problems.

The Linux kernel started its own Rust experiment in 2020. Linux is a low-level project. Camera support is a low-level topic (many people working on libcamera also work on the kernel). If Rust is interesting for Linux, then it's interesting for libobscura.

### Get RGB data

A camera library can't be described as easy to use if the pictures it gives you need to be processed before displaying.

The typical format to display data is RGB while cameras return either Bayer or YUV data. With libobscura, the goal is to provide those conversions transparently, without any extra effort on behalf of the user or camera backend.

### GPU acceleration

The conversions might not be implemented in hardware, but don't worry, libobscura has your back! It comes with a GPU-accelerated image processing library called crispy-img.

Why GPU? The idea started with the Librem 5, which will often record video while running on battery. Offloading this work to the GPU is a clear win, and I expect most Linux video-capable devices to have some form of GPU. And we're open to a CPU decoder if you want to contribute!

A painter looking at a canvas with 4 colored strokes: 2 colored, 2 gray, representing YUYV. The painter holds a brush at a canvas on the other side with 3 colored strokes: red, green, and blue.

Figure 3: An artist's impression of a pixel format conversion shader.

## Status

Because libobscura is only two months old as a funded project, the current status is "proof of concept". There's a safe and limited user API, another more tricky but zero-copy API, the GPU accelerated library can handle some conversions, and camera support is relatively simple. USB camera demo works.

But there are still goals to achieve:

Those will be the next steps for the project. First implement all the functionality and then extend support for more devices. This way we can catch corner cases in the API that are bound to appear with unusual setups.

## The future is YOU

I'm making libobscura in the hope that it will be useful to people. As a base to build software, or to ship devices, or to learn what software architectures fit this problem.

When I sent my funding request to Prototype Fund, I didn't expect to be taken seriously. After all, what motivated me most was that it was a cool challenge. Apparently they believed in me more than I did, because I got funding until March 2025.

What happens until then and what happens next depends on how useful this work actually is to YOU. The ultimate goal of any software is to be useful, otherwise what's the point?

So I invite YOU to analyze it, try it out, give feedback, experiment with it, copy the concepts, contribute to docs, illustrations, and code, fork it entirely! Regardless if you come from the Mobile Linux community, or Raspberry Pi, or you have a laptop with this IPU thing, or if you're from libcamera. When you improve, libobscura fulfills its goals.

So see you on the project page!

## Thanks

Thank you to Purism, for inviting me to the Linux camera work and funding the base which I'm using now.

Thank you to all the libcamera people! I stol... was inspired by libcamera's architecture, and you also answered my countless questions both during Librem 5 development and recently.

Thank you Martijn Braam for showing how to create simple config files for many mobile phones.

Thank you BMBF for providing the funding money, and thanks Prototype Fund for connecting me to it :)

Logo: sponsored by the Federal Ministry of Education and Research

Written on .

Comments

dcz's projects

Thoughts on software and society.

Atom feed