1
0
Fork
You've already forked libcamera-zig
0
Zig bindings for libcamera
  • C++ 45.9%
  • Zig 36.1%
  • C 18%
felixdrp 9bba16a5a6 fix: list camera formats and add YUYV support
- Add lc_camera_list_formats() C API with LcFormatDesc struct to
 enumerate supported pixel formats and resolutions per camera
- Fix StreamFormats iteration to use pixelformats()/sizes() API
- Replace CameraManager::get(string_view) with manual cameras() loop
 to avoid libc++ vs libstdc++ ABI symbol mismatch at runtime
- Switch build from zig c++ to g++ so wrapper uses the same
 libstdc++ ABI as the system libcamera
- Add LC_FMT_YUYV / .yuyv pixel format throughout
- Make LibCameraSource.open and .close pub for direct callers
- Update README with format enumeration feature and example
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026年04月02日 13:03:20 +00:00
src fix: list camera formats and add YUYV support 2026年04月02日 13:03:20 +00:00
.gitignore Initial commit 2026年04月01日 11:17:05 +02:00
build.zig fix: list camera formats and add YUYV support 2026年04月02日 13:03:20 +00:00
build.zig.zon fix: list camera formats and add YUYV support 2026年04月02日 13:03:20 +00:00
LICENSE Initial commit 2026年04月01日 11:17:05 +02:00
README.md fix: list camera formats and add YUYV support 2026年04月02日 13:03:20 +00:00

libcamera-zig

Zig bindings for libcamera, inspired by libcamera-rs.

Features

# Feature Status
1 Zero-copy frame capture via DMA-BUF mapping Implemented
2 C++ wrapper for the libcamera C++ API (opaque LcCamera pointer) Implemented
3 Simple Zig VideoSource vtable interface Implemented
4 Camera controls — brightness, contrast, saturation, sharpness, exposure time, analogue gain Implemented
5 AE/AWB enable & lockAeEnable, AwbEnable controls (AeLocked absent in libcamera 0.7) Implemented
6 AWB mode — Auto, Incandescent, Tungsten, Fluorescent, Indoor, Daylight, Cloudy, Custom Implemented
7 AE metering mode — CentreWeighted, Spot, Matrix, Custom Implemented
8 Stream roles — VideoRecording, StillCapture, Viewfinder, Raw Implemented
9 Raw Bayer output — SGRBG10, SRGGB10, SBGGR10, SGBRG10; LC_ROLE_RAW Implemented
10 Camera properties — sensor model string, pixel array size, focal length Implemented
11 Per-frame metadata — actual exposure time, analogue gain, focus FoM, lux Implemented
12 Hotplug events — callbacks on camera add/remove via persistent global CameraManager Implemented
13 Stub builds (no libcamera headers required) — all new functions have no-op stubs Implemented
14 Multi-stream (simultaneous preview + capture) Implemented
15 Digital zoom / crop rectangle control Implemented
16 Format enumeration — list supported pixel formats and resolutions (listFormats) Implemented
17 YUYV pixel formatLC_FMT_YUYV / .yuyv Implemented

Usage

Prerequisites

This library requires g++, libcamera, and libcamera-base development headers installed on your system.

# Debian/Ubuntu/Raspberry Pi OS
sudo apt install g++ libcamera-dev libcamera-base-dev

As a dependency

You can add libcamera-zig to your project using zig fetch:

zig fetch --save https://codeberg.org/felixdrp/libcamera-zig/archive/main.tar.gz

This will update your build.zig.zon:

.{.fingerprint=0x7725543516074afb,// Example fingerprint.name=.my_project,.version="0.1.0",.dependencies=.{.libcamera_zig=.{.url="https://codeberg.org/felixdrp/libcamera-zig/archive/main.tar.gz",.hash="...",},},}

And in your build.zig:

constlibcamera_dep=b.dependency("libcamera_zig",.{.target=target,.optimize=optimize,.libcamera=true,// Set to false to build with stubs only});constlibcamera_mod=libcamera_dep.module("libcamera-zig");// Use the link helper from the dependency to compile and link the C++ wrapperconstlibcamera_lib=@import("libcamera_zig");libcamera_lib.link(b,libcamera_dep,exe);exe.root_module.addImport("libcamera",libcamera_mod);

Compiling your project

Once configured, you can build your project with the standard Zig command:

zig build

If you implemented a build option to toggle libcamera support (e.g., -Dlibcamera=true), use:

zig build -Dlibcamera=true

Camera controls example

constlc=@import("libcamera");varsrc=lc.LibCameraSource.init(0);varvs=src.videoSource();tryvs.open(.{.width=1920,.height=1080,.fps=30});// Set brightness and lock AE_=src.setControls(.{.brightness=0.2,.ae_locked=1,});

Raw Bayer capture example

tryvs.open(.{.width=4056,.height=3040,.fps=10,.pixel_format=.sgrbg10,.stream_role=.raw,});

Camera properties example

if(src.getProperties())|props|{std.debug.print("Sensor: {s} ({d}x{d})\n",.{props.model,props.pixel_array_width,props.pixel_array_height,});}

Per-frame metadata example

constframe=(tryvs.nextFrame())orelsereturn;std.debug.print("exp={}μs gain={d:.2} lux={d:.1}\n",.{frame.actual_exposure_time_us,frame.actual_gain,frame.lux,});

Hotplug example

constlc=@import("libcamera");fncameraAdded(id:[*:0]constu8,_:?*anyopaque)callconv(.C)void{std.debug.print("Camera added: {s}\n",.{id});}fncameraRemoved(id:[*:0]constu8,_:?*anyopaque)callconv(.C)void{std.debug.print("Camera removed: {s}\n",.{id});}// ..._=lc.setHotplugCallbacks(cameraAdded,cameraRemoved,null);// ... application runs ...lc.stopHotplug();

Format enumeration example

varsrc=lc.LibCameraSource.init(0);trysrc.open(.{});defersrc.close();constformats=trysrc.listFormats(allocator);defer{for(formats)|f|allocator.free(f.fps);allocator.free(formats);}for(formats)|f|{std.debug.print("{s} {d}x{d}\n",.{@tagName(f.pixel_format),f.width,f.height});}

Digital zoom example

// 2x digital zoom (centered crop)_=src.setControls(.{.zoom_factor=2.0});// Raw ScalerCrop rectangle override (overrides zoom_factor)_=src.setControls(.{.crop=.{.x=100,.y=100,.w=1920,.h=1080}});

Multi-stream example

tryvs.open(.{.width=1920,.height=1080,.stream_count=2,.extra_streams=.{.{.width=640,.height=480,.pixel_format=.nv12,.stream_role=.viewfinder},.{},.{},},});// Primary stream (stream 0)constframe0=trysrc.nextFrameFromStream(0);// Secondary stream (stream 1)constframe1=trysrc.nextFrameFromStream(1);