rslibcamlite 0.2.0

Rust wrapper for libcamlite - h264/rgb stream access to rpi cameras
# libcamlite-rs
This crate brings libcamlite (https://github.com/carsonfenimore/libcamlite) support to rust!

It gives you the Raspberry Pi camera's hardware-encoded H.264 stream and a low-res RGB
stream (e.g. for inference) at the same time, at very low CPU cost. See
[examples/framerate.rs](examples/framerate.rs) for a complete program. The core of it is:

```rust
struct Callback;

impl ExternalCallback for Callback {
    unsafe fn callbackH264(&self, bytes: *mut u8, count: usize, timestamp_us: i64, keyframe: bool) { /* ... */ }
    unsafe fn callbackLowres(&self, bytes: *mut u8, count: usize) { /* ... */ }
}

let libcam = LibCamClient::new();
let h264 = StreamParams { width: 1920, height: 1080, format: StreamFormat::STREAM_FORMAT_H264, framerate: 30 };
libcam.client.setupH264(&h264, 30, &"main".to_owned(), &"4mbps".to_owned());
let lowres = StreamParams { width: 300, height: 300, format: StreamFormat::STREAM_FORMAT_RGB, framerate: 30 };
libcam.client.setupLowres(&lowres);
libcam.setCallbacks(Box::new(Callback));
libcam.start(true);
```

This produces a steady 30 fps of both H.264 and RGB:

    h264:  30 fps   1984 kbit/s (2 keyframes total)   rgb 300x300:  30 fps
    h264:  30 fps   1947 kbit/s (3 keyframes total)   rgb 300x300:  30 fps

On a Pi Zero 2 W this costs about 70MB of RAM and a load average of about 0.5.

Versions:
  - 0.2.0: callbacks take `&self` and must be `Send + Sync` (breaking); libcamlite is
    compiled into the crate against the system libcamera / rpicam-apps packages (no
    CMake step, no `LD_LIBRARY_PATH`); cross-compilation support; lowres frames use a
    single worker thread; shutdown fixes. Requires rpicam-apps >= 1.9.1.
  - 0.1.9: support latest libcamlite, which supports latest libcamera/rpicam-apps
  - 0.1.2: fixes the crate so that it builds the libcamlite dependency automatically.

## Building
The crate only builds for 64-bit Raspberry Pi OS (trixie or newer) targets. On the Pi:

```
sudo apt install -y build-essential pkg-config libclang-dev \
    libcamera-dev librpicam-app-dev libboost-program-options-dev \
    libavformat-dev libavcodec-dev libavutil-dev libavfilter-dev \
    libavdevice-dev libswscale-dev libswresample-dev
git submodule update --init
cargo build
```

rpicam-apps changes its C++ API between releases, so the build checks for rpicam-apps
>= 1.9.1 (tested with 1.13.0) and rebuilds are needed after rpicam-apps updates.

### Cross-compiling (recommended for the Pi Zero 2 W)
Building on a Pi Zero 2 W is slow. On any x86_64 Linux machine with podman or docker:

```
cross/build.sh             # builds the crate and examples/framerate
cross/build.sh --publish   # cargo publish --dry-run, verified for arm64
```

The first run creates a Debian trixie container with the arm64 libcamera / rpicam-apps /
ffmpeg packages from the Raspberry Pi archive; after that builds are incremental. Run
`cross/build.sh --pull` after updating your Pis so it builds against the same package
versions. To try the example on a Pi:

```
scp target/aarch64-unknown-linux-gnu/release/examples/framerate pi:
ssh pi ./framerate
```

To publish: commit, run `cross/build.sh --publish` to verify the packaged crate builds
for arm64, then from any machine where you've run `cargo login`:

```
cargo publish --no-verify
```

(`--no-verify` skips cargo's own test build, which can't work on a non-Pi host; the
dry run above already did it.)