Metadata-Version: 2.4
Name: bayerlink
Version: 0.5.0
Summary: Raw sensor data over an HDMI/DVI link: the bayerlink protocol and its reference implementation
Author: Serge Rabyking
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/bayerlink/bayerlink
Project-URL: Source, https://github.com/bayerlink/bayerlink
Project-URL: Issues, https://github.com/bayerlink/bayerlink/issues
Keywords: bayer,raw,hdmi,dvi,fpga,camera,protocol,video
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Scientific/Engineering :: Image Processing
Classifier: Topic :: Software Development :: Embedded Systems
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

<img src="bayerlink.svg" alt="bayerlink: a Bayer mosaic of chain links" width="96" align="right">

# 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](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](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](TRADEMARK.md) for the one thing the name asks of you.

## The package

```python
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](PROTOCOL.md). Reference
encoder: [picam2hdmi](https://github.com/bayerlink/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_in`](https://github.com/lanserge/np2hw) decodes the link on
  an FPGA and aligns sample depth on the way in.
- [revela](https://github.com/lanserge/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](https://github.com/bayerlink/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](https://github.com/sponsors/lanserge), or write
first: **s.rabykin@gmail.com**. Sponsorable capability targets carry the
[`sponsorable` label on the issue tracker](https://github.com/bayerlink/bayerlink/issues?q=label%3Asponsorable)
— 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](https://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.
