picam2hdmi
A Raspberry Pi camera as a raw-Bayer HDMI source.
FPGA boards rarely have a camera connector, but nearly all of them have HDMI-in. A Raspberry Pi has the opposite: a first-class camera stack — every sensor libcamera supports, drivers, modes, controls — and an HDMI output. picam2hdmi turns the Pi into a sensor module with an HDMI plug: raw 12-bit Bayer frames, straight from the sensor's CSI-2 output with the ISP bypassed, carried over the display link as bytes and self-described by a header line.
sensor ──CSI-2──▶ Pi (libcamera raw, zero-copy) ──HDMI──▶ any receiver with HDMI-in
No transcoding, no compression, no per-sensor code in this tool: the Bayer order and bit depth travel in the stream itself, so a receiver built once works with every camera the Pi supports.
The protocol: bayerlink
The wire format is bayerlink — the display's active area as a byte container, one header line making the stream self-describing. The spec, the reference codec and the conformance vectors live in the protocol's own repository, because this tool is one encoder among several and should not own the contract receivers implement.
The codec runs on both ends: this tool encodes with it on the Pi, and a receiver's host software decodes captured frames with the same package —
import bayerlink
header, raw = bayerlink.decode_frame(captured) # (H, W, 3) uint8 in
print(header.bayer_order, header.width, header.height, header.frame_seq)
# raw: (lines, samples) uint16, exactly what the sensor produced
Status
| Piece | State |
|---|---|
| bayerlink v2 protocol, patterns, vectors | done — in bayerlink |
| CLI: pattern → container file | done |
| KMS scanout (double-buffered, full-range RGB forced) | implemented — pure ctypes DRM, off-target tests green; first on-Pi run is the phase-0 session |
| Appliance mode | contrib/picam2hdmi-pattern.service: power on, it streams |
| Picamera2 raw capture (zero-copy dmabuf path) | next — design in capture.py |
Usage today
pip install picam2hdmi # numpy only; add [pi] on the Pi itself
picam2hdmi pattern --mode counting --width 2028 --height 1078 --out frame.npy
That file is bit-for-bit what the HDMI link will carry — receivers can be built and tested against it before any cable exists.
The one integration rule
The link must deliver bytes unmodified: full-range RGB, no scaling, no
overscan, RGB 4:4:4. The most common failure is a limited-range clamp
(16–235) quietly destroying sample values; the checker and corners
patterns exist to catch exactly that on day one. Details and the receiver
rate rule are in PROTOCOL.md.
Why this exists
Built as the sensor front-end for FPGA image pipelines — for example, as the input to hardware generated with np2hw — but useful to anyone who wants real sensor data into a board without MIPI hardware, deserialisers, or per-sensor bring-up.
Licence
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file picam2hdmi-0.3.0.tar.gz.
File metadata
- Download URL: picam2hdmi-0.3.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f206925462c343a76a335b996b679e662128f1ba74d4ae43e064ff81b1d2c9d6
|
|
| MD5 |
028fac1e90aa3d6dfce4a0ebecf5d7c1
|
|
| BLAKE2b-256 |
8e250c09051e213c8414c01c8cc0886963c6a818f13f4efef6f11906d99232f0
|
Provenance
The following attestation bundles were made for picam2hdmi-0.3.0.tar.gz:
Publisher:
publish.yml on bayerlink/picam2hdmi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picam2hdmi-0.3.0.tar.gz -
Subject digest:
f206925462c343a76a335b996b679e662128f1ba74d4ae43e064ff81b1d2c9d6 - Sigstore transparency entry: 2398118307
- Sigstore integration time:
-
Permalink:
bayerlink/picam2hdmi@b2aadc6ab486ee912e6999771303df3bc36ed3b6 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/bayerlink
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b2aadc6ab486ee912e6999771303df3bc36ed3b6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file picam2hdmi-0.3.0-py3-none-any.whl.
File metadata
- Download URL: picam2hdmi-0.3.0-py3-none-any.whl
- Upload date:
- Size: 15.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06f89de170928febc9e367c5fc1df2709f1dbbee0bbd478d3de6a3f76f67ddc0
|
|
| MD5 |
8b550de980674db9a07864a4a3fdae28
|
|
| BLAKE2b-256 |
71f3eb063b87106065d01c048a62d8b985d85cfc0b8e7bfc98b4ec65b8960573
|
Provenance
The following attestation bundles were made for picam2hdmi-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on bayerlink/picam2hdmi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picam2hdmi-0.3.0-py3-none-any.whl -
Subject digest:
06f89de170928febc9e367c5fc1df2709f1dbbee0bbd478d3de6a3f76f67ddc0 - Sigstore transparency entry: 2398118800
- Sigstore integration time:
-
Permalink:
bayerlink/picam2hdmi@b2aadc6ab486ee912e6999771303df3bc36ed3b6 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/bayerlink
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b2aadc6ab486ee912e6999771303df3bc36ed3b6 -
Trigger Event:
release
-
Statement type: