Vellum/internal
mithral 549b503fdf Detect transcode hardware, and prove it can actually encode
First step of ADR-008. internal/transcode answers one question: can this host
hardware-transcode, and with which encoder.

The rule the package exists to enforce is that a device node is not proof. A
node can exist while the driver cannot encode, and that produces the worst
outcome ADR-008 describes: a transcode that starts, looks like it works, and
then cannot keep up. So every candidate runs a real two-frame probe encode and
is dropped unless that encode exits cleanly.

This host is a perfect illustration and the reason the rule is not theoretical:
it has /dev/dri/renderD128 AND Nvidia nodes. The render node exists, but VAAPI
fails to initialise against it ("Failed to initialise VAAPI connection"). A
detection that trusted the node would have picked VAAPI and been wrong. The
probe rejected it and selected NVENC, which was verified independently with
ffmpeg outside this code.

The probe is injected, so every branch is testable with no hardware present,
including the important one: device present, probe fails. Verified red-green -
ignoring the probe result fails TestDetectProbeFails with "got vaapi, want no
capability".

One real bug found while proving it: the probe used testsrc=size=64x48, below
NVENC's minimum frame size, so a host with working NVENC would have reported no
capability at all. Raised to 320x240, still two frames.

Also added internal/transcode to the arch layer map as a layer-1 primitive
beside probe and engine, which the arch rule caught immediately.

Not wired into the engine registry or playback yet - that is the next step.
2026-10-12 11:49:05 -04:00
..
apitoken Waves 9-10: Jellyfin and Subsonic clients can browse and play 2026-10-11 15:05:43 -04:00
arch Detect transcode hardware, and prove it can actually encode 2026-10-12 11:49:05 -04:00
auth Rate limit every surface that checks a password 2026-10-12 00:57:56 -04:00
catalog Expose the television tree: catalog reads, API routes, Jellyfin shapes 2026-10-12 01:41:05 -04:00
cli Documentation, and make a fresh clone actually work 2026-10-12 00:18:11 -04:00
core Add a ThePornDB provider for the adult kind 2026-10-12 11:30:58 -04:00
discovery Advertise Vellum over mDNS so clients find it without a typed URL 2026-10-12 01:04:33 -04:00
engine Waves 7-8: playback engine selection, and missing files you can see 2026-10-11 14:36:55 -04:00
home Phase 2: split the fat packages along real boundaries 2026-10-11 16:03:10 -04:00
httpapi Documentation, and make a fresh clone actually work 2026-10-12 00:18:11 -04:00
httpx Phase 1: accounts, sessions, per-library grants 2026-10-09 16:31:24 -04:00
jellyfin Expose the television tree: catalog reads, API routes, Jellyfin shapes 2026-10-12 01:41:05 -04:00
jobs Wave 1: survive a real library 2026-10-11 13:10:34 -04:00
library Separate video libraries by kind: movies, TV, adult, hentai 2026-10-12 11:20:51 -04:00
media Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00
metadata Separate video libraries by kind: movies, TV, adult, hentai 2026-10-12 11:20:51 -04:00
modules Phase 1: one item-access seam, and architecture rules that fail the build 2026-10-11 15:47:18 -04:00
natsort Phase 6a: directory grouping, audiobooks and music playback 2026-10-09 21:20:47 -04:00
playback Phase 3: a storage seam behind catalog, and one consumer threaded onto it 2026-10-11 16:16:07 -04:00
probe Waves 4-6: audio depth, ffprobe facts, and direct-play video 2026-10-11 14:14:32 -04:00
progress Wave 1: survive a real library 2026-10-11 13:10:34 -04:00
providers Add a ThePornDB provider for the adult kind 2026-10-12 11:30:58 -04:00
scanner Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00
search Wave 3: search depth, transfer size, and the Home screen's tests 2026-10-11 13:46:18 -04:00
stream Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00
subsonic Rate limit every surface that checks a password 2026-10-12 00:57:56 -04:00
transcode Detect transcode hardware, and prove it can actually encode 2026-10-12 11:49:05 -04:00