bayerlink
Raw sensor data over an HDMI/DVI link.
FPGA boards rarely have camera connectors; nearly everything has HDMI. The bayerlink protocol treats a display link's active area as a byte container: packed raw Bayer samples, one camera line per display line, self-described by a 48-byte header (magic, version, V4L2 fourcc, geometry, frame counter, stripe and source identity for multi-link use, CRC). Real sensor data into any board with HDMI-in — no MIPI hardware, no deserialisers, no per-sensor bring-up on the receiver.
New here? GUIDE.md routes by what is on your desk — a Pi, an FPGA board, a $10 capture stick, a sensor that is not 12-bit.
PROTOCOL.md is the specification. This package is its
reference implementation, and vectors/ pins the exact bytes, so a
conforming implementation in any language never has to run this one.
Independent implementations are unrestricted and encouraged; say "speaks bayerlink v2" and you are conforming, not licensing. See TRADEMARK.md for the one thing the name asks of you.
The package
import bayerlink
frame = bayerlink.encode_frame(raw, "RGGB", frame_seq=7) # (H, W, 3) uint8 out
header, raw = bayerlink.decode_frame(captured) # and back
header.bayer_order, header.width, header.frame_seq
It runs on both ends: encoders build containers with it, and a receiver's host software decodes captured frames with the same module — one implementation to disagree with the spec, which is the fewest possible.
bayerlink.pattern carries the link-proving test patterns (counting,
gradient, checker, corners) every encoder and receiver bring-up uses;
checker and corners pin 0 and full scale, the first casualties of a
limited-range link.
Implementations
The registry lives at the end of PROTOCOL.md. Reference encoder: picam2hdmi (Raspberry Pi, every libcamera sensor). To be listed: implement the spec, pass the vectors, open an issue.
After the decoder
This library is the wire and nothing beyond it: it says what a frame looks like, not what to do with one. A decoder hands you raw Bayer plus the header's geometry, CFA phase and depth — and those are exactly what an ISP needs to be told, which is why they travel with the frame rather than being configured at both ends.
One path is built end to end, if you want the frames processed rather than merely received:
np2hw.video_indecodes the link on an FPGA and aligns sample depth on the way in.- revela generates the ISP that consumes it, taking geometry and phase as stream context — the header's facts, wired straight through rather than copied into registers.
- bayerlink-fpga is all of it on a PYNQ-Z2, and the reason the two rows below it in the registry say "working on silicon".
None of that is required by the protocol. A decoder that hands frames to something else entirely is just as conformant — the vectors are the test.
Funding
Developed independently; recurring support via
github.com/sponsors/lanserge, or write
first: s.rabykin@gmail.com. Sponsorable capability targets carry the
sponsorable label on the issue tracker
— currently the PiSP compressed payload family and the laptop replay
player. Scope is agreed in writing before work
starts; sponsored work lands in the open tree immediately, licensed like
everything else — sponsorship buys ordering and named credit, not
exclusivity. The person behind it:
serge.rabyking.com.
Licence
Apache-2.0 — chosen over MIT for two of its clauses, not for anything this project owns. Section 3 means every contributor grants implementers a licence to any patent claims their contribution would infringe: no such patents are known or claimed, and the clause is insurance FOR implementers, not an assertion by this project. Section 6 makes explicit that the licence covers the text and code, never the name (see TRADEMARK.md). A protocol meant for many independent implementers benefits from both being written down.
Metadata
Release files for bayerlink 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bayerlink-0.5.0.tar.gz | 28.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bayerlink-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.9 kB
Release files / bayerlink-0.5.0.tar.gz
| Download URL | bayerlink-0.5.0.tar.gz |
|---|---|
| Size | 28.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6af8b2fa75068c3edc0bf6a19e044ac68ff5e4e94aa21a1b707bc4e0a21f688a
|
|
BLAKE2b-256 checksum How to use checksums |
96a333e6e4c7b00e46005da05bd164eaa83f0619118c507410e44cb55482eaad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency logRelease files / bayerlink-0.5.0-py3-none-any.whl
| Download URL | bayerlink-0.5.0-py3-none-any.whl |
|---|---|
| Size | 21.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d195facc88289c7b693a90f1b06bc1428d22708e90c7a972dd47c0889dbdf26d
|
|
BLAKE2b-256 checksum How to use checksums |
fe84758d21ec85b4002001697de5ccae5e0de9b9fed1390410e466aa7a0949f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency log