Emergency video
For reasons that made sense at the time, I built a small emergency video system.
The question behind it was pretty simple: if a connection gets bad enough, how little video can you still send before it stops being useful?
Repo is here: github.com/tgergo1/emergency-video.
The core of it is a custom C++ codec hooked up to a live webcam feed. Frames are shrunk to a tiny internal resolution, converted to grayscale, quantized to 4-bit luma, and encoded as periodic keyframes plus sparse interframes. If a block has not changed, it gets skipped, because bandwidth is what we are trying to save in the first place. If it has changed, it can be sent as coarse 4x4 cells, residuals against the previous reconstructed frame, or full raw 8x8 samples when the block is too messy for anything cheaper.
So yes, the result looks rough. Typical modes are 128x96 or 96x72 at only a few frames per second. That is on purpose. I was not trying to make nice-looking video. I was trying to keep enough scene information to answer basic questions: is somebody there, did something move, is that smoke, did the person just wave, is the situation getting worse?
What started as a codec experiment turned into a slightly larger communication prototype. There is a browser dashboard with live raw, sent, and received views, plus controls for the link, text messages, relay import/export, and general status. Underneath that is a simple packet layer with fragmentation, CRCs, ACK and retry handling, presence messages, queue management, and config beacons. Video is only one payload type. The same system can also send text, snapshots, and low-rate fallback traffic.
The transport side also got a bit out of hand. The app can move data over acoustic bursts through a speaker and microphone, serial, optical patterns, and a file-relay mode. When the link gets worse, a fallback controller steps down through lower FPS, lower resolution, snapshot-only mode, and finally text-only mode. There is also a low-rate text path with plain text, Morse, and DTMF-style encoding.
There are clear weak spots. This is not a standard video codec, and it is not trying to compete with one. The acoustic path depends a lot on the room, the hardware, and how noisy the environment is. The FEC is still fairly simple. Fast motion can still turn into stale or blocky output. The upside is that the whole thing is small enough to read, test, and package without it turning into a giant black box.
A few practical extras made it in: face-aware ROI prioritization, live bitrate and PSNR metrics, config hash checks before decode, browser-accessible HTTP endpoints, and tests for deterministic encoding, corruption handling, queue deduplication, communicator envelopes, and fallback logic. Somewhere along the way it stopped feeling like a codec toy and started feeling more like a small field tool.
If I had to describe it in one line, it is a video system that gives up slowly.
You can build and run it locally with:
cmake -S . -B build
cmake --build build -j
./build/emergency_video
Then open:
http://localhost:8080
// comments