Files
Claude Opus 7f45c36aa2 init
2026-05-26 23:23:25 +01:00

48 lines
3.5 KiB
Markdown

---
title: Python bindings
sidebar_position: 3
---
# Python bindings
**Status: planned for v0.5+. Not shipped yet.**
This page is a placeholder so the integration story is honest about what exists and what does not. If you need Python access to cuframes today, read [Workaround for v0.4](#workaround-for-v04) below.
## What v0.5+ will ship
A small `cuframes` Python package, distributed as a wheel, providing:
- **`ctypes`-based bindings** around the existing C API (`cuframes_publisher_create`, `cuframes_subscriber_create`, `cuframes_acquire`, `cuframes_release`, etc.). No new ABI, no SWIG, no C++ wrapper.
- **Zero-copy NumPy / PyTorch access** to the decoded NV12 surface via the [CUDA Array Interface](https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html). A subscribed frame is exposed as a CuPy / PyTorch tensor that points at the same GPU memory the publisher wrote — no `cudaMemcpy` to host, no copy on the device either.
- **Context-manager API** for acquire / release so frame slots cannot leak across exceptions.
Target use cases:
- **PyTorch inference on shared frames** — a detector / classifier subscribes to `cuframes://camN`, gets a tensor, runs `model(tensor)` directly. Today this requires either re-decoding the RTSP stream or copying frames over a Unix pipe.
- **OpenCV CUDA processing** — `cv2.cuda_GpuMat` constructed from the cuframes pointer, then any cv2.cuda op (resize, color convert, optical flow) runs in place.
- **Quick prototyping** — a Jupyter notebook that subscribes to a live camera, slices out a region of interest, and visualises it without spinning up a full FFmpeg pipeline.
There is no plan to add CPU-side NumPy fallback. Frames are GPU surfaces; if you want them on the CPU you do an explicit `tensor.cpu()` and accept the copy.
## Workaround for v0.4
Until the bindings ship, the supported path is to call `libcuframes.so` directly from Python using `ctypes` or `cffi`. The C API is small (≈ 10 functions) and stable within a v0.x release.
Realistically though, most v0.4 deployments do **not** call cuframes from Python at all. They use the existing C/FFmpeg path:
- For inference: subscribe to the **packet** ring with `ffmpeg -f cuframes_packets -i cuframes_packets://camN` and pipe decoded frames into your Python process. You lose zero-copy but gain a working pipeline today.
- For prototyping: use the C examples in [`examples/`](https://git.goldix.org/gx/cuframes) as your starting point.
If you need a Python-side zero-copy path *right now*, you are going to write the `ctypes` wrappers yourself. Mirror the prototypes from [`include/cuframes/cuframes.h`](/docs/reference/protocol), keep handles opaque (`void *`), and use `cuMemAlloc` / CuPy `UnownedMemory` to view the imported VMM allocation. Expect rough edges — the v0.5 bindings exist precisely because this is not fun to do by hand.
## Track progress
Roadmap and milestone notes for the Python package live in [`ROADMAP.md`](https://git.goldix.org/gx/cuframes) in the cuframes repo. v0.5 also gates on the HEVC packet-ring path and a small ABI cleanup, so the bindings are not the only thing on that release.
## See also
- [Install](/docs/getting-started/install) — get `libcuframes.so` onto your system so the bindings will have something to load.
- [Protocol reference](/docs/reference/protocol) — the C API surface the bindings will mirror.
- [FFmpeg `cuframes://` demuxer](/docs/integration/ffmpeg-demuxer) — today's practical path for getting cuframes data into any non-C consumer.