Bindings for video4linux2 - zig-v4l2

Hi everyone, happy to share what I’ve been working on, for anyone wanting to use the video4linux2 API from Zig, there’s now a
0.16.0 package ready to go: GitHub - pierrelgol/zig-v4l2: typed v4l2-bindings for Zig · GitHub.

This is something I’ll be using at work, so it will be maintained for the foreseeable future. The V4L2 API itself is extremely
stable and cool :grinning_face: and the package has a lot of ABI test coverage to make
sure it stays that way, rather than silently producing garbage with ioctl calls.

  zig fetch --save git+https://github.com/pierrelgol/zig-v4l2#main

then in build.zig

  const zig_v4l2 = b.dependency("zig_v4l2", .{ .target = target, .optimize = optimize });
  exe.root_module.addImport("z4l2", zig_v4l2.module("z4l2"));

Then from your code:

  const z4l2 = @import("z4l2");

  var cap: z4l2.capability.Capability = undefined;
  // fill via VIDIOC_QUERYCAP ioctl...

  // pixel formats, controls, everything namespaced
  const fmt: z4l2.pixel.Format = .yuyv;
  const brightness_id = z4l2.control.brightness.id;

My wrist is wrecked because it was a lot of tedious typing - the C headers are ~4k lines of #define mixed with structs, enums, #define that are actually enums anyway, a lot of very inconsistent naming. Multicursor, macros, and AI agents at the end to batch-split things into cleaner namespaced modules were lifesavers.

Right now it’s purely hand-written typed bindings with full ABI compatibility. But the bigger goal is a layer-2 abstraction on top of that which is actually what got me into V4L2 in the first place.

The story: libcamera is built on top of V4L2 and is the Linux industry standard. It’s genuinely great for the common cases, well-documented, easy to use. But the moment you try to do something non-standard it gets in the way. Hard to reason about, full of abstractions that don’t compose well. So the idea that i want to implement is a declarative API with a builder pattern to express a complete media graph

something more manual than libcamera pipeline handler, but also simpler and more composable for the cases where you actually need control.

Long road ahead, but I’d love reviews or critique if anyone’s interested :slight_smile:

I also forgot to mention that you don’t need this package at all if you work with v4l2, you can always just use addTranslateC directly, but in my opinion the v4l2 api is already quite noisy even in C, and when used from C in Zig it’s even worse the bindings, is just there to get decls literals and more consistent namespacing, and easier to review code, most files are short enough

9 Likes