Expand description
Server-side transcoding for LVQR (Tier 4 item 4.6).
Generates an ABR ladder (720p / 480p / 240p by default) from a
single high-resolution source broadcast, with the output
renditions re-injected into the caller-supplied
lvqr_fragment::FragmentBroadcasterRegistry under
<source>/<rendition> broadcast names. Every egress surface
(LL-HLS, DASH, MoQ relay, archive) picks them up without
per-protocol wiring; the LL-HLS master playlist composer emits
one #EXT-X-STREAM-INF per rendition automatically.
§What this crate ships
Always available (default features):
Transcodertrait +TranscoderFactory+TranscoderContext– the “subscribe / drain / panic-isolate” shape generalised fromlvqr_agent::Agent. Each factory carries its ownRenditionSpec.TranscodeRunner+TranscodeRunnerHandle– registry-side installer + cheaply-cloneable handle, mirroringlvqr_agent::AgentRunner.RenditionSpecwith width / height / bitrate fields,RenditionSpec::preset_720p/preset_480p/preset_240pconstructors, andRenditionSpec::default_ladder.PassthroughTranscoder– in-memory observer that proves the registry-callback / drain / panic-isolation wiring; useful for tests and as a metrics tap.AudioPassthroughTranscoder– copies<source>/1.mp4audio fragments verbatim into every rendition’s audio track so each rendition broadcaster is a self-contained mp4 the LL-HLS bridge drains without special-casing the missing audio.
Behind the transcode feature (pulls gstreamer-rs 0.23 +
base/good/bad/ugly + gst-libav from the host):
- [
SoftwareTranscoder] / [SoftwareTranscoderFactory] – theappsrc -> qtdemux -> h264parse -> avdec_h264 -> videoscale -> x264enc -> ... -> mp4mux -> appsinkladder, one worker thread per(source, rendition)pair, bounded mpsc. - [
AacToOpusEncoder] / [AacToOpusEncoderFactory] – AAC -> Opus transcoder used bylvqr-whep(under itsaac-opusfeature) so AAC publishers reach Opus-negotiated WHEP subscribers.
Behind one of the hw-* features (each implies transcode):
hw-videotoolbox– [VideoToolboxTranscoder] / [VideoToolboxTranscoderFactory] for macOS via Apple’svtenc_h264_hw(theapplemediaplugin from gst-plugins-bad).hw-nvenc– [NvencTranscoder] / [NvencTranscoderFactory] for Linux + Nvidia GPUs vianvh264enc(thenvcodecplugin from gst-plugins-bad, driven by the CUDA runtime).hw-vaapi– [VaapiTranscoder] / [VaapiTranscoderFactory] for Linux + Intel iGPU / AMD viavah264enc(the modernvaplugin from gst-plugins-bad, superseding the deprecatedvaapih264encfromgstreamer-vaapi).hw-qsv– [QsvTranscoder] / [QsvTranscoderFactory] for Linux + Intel Quick Sync viaqsvh264enc(theqsvplugin from gst-plugins-bad, driving Intel Media SDK / oneVPL).
All four HW backends mirror SoftwareTranscoderFactory shape
verbatim – same Transcoder trait, same lifecycle, same
<source>/<rendition> output broadcast naming, same bounded
mpsc + dedicated worker thread per (source, rendition) pair –
and only swap the GStreamer encoder element + property mapping.
HW-only path is intentional across all four: a factory that
silently falls back to CPU encoding under load defeats the point
of an operator-pickable hardware tier. Each factory’s
is_available() probes the required encoder element at
construction and build() opts out cleanly with a warn log when
missing.
Future sessions may extract the shared scaffolding into a
dedicated pipeline.rs module (per the “three is the threshold
for an abstraction” rule). The current shape is intentional code
duplication: each backend stays readable on its own and the cost
of cross-backend changes is small enough that the mechanical-
sharing tradeoff is not yet a win.
§Where this crate fits in the consumer family
Pattern-matches the existing
lvqr_fragment::FragmentBroadcasterRegistry consumers:
| Crate | Wires | Purpose |
|---|---|---|
lvqr_cli::hls::BroadcasterHlsBridge | on_entry_created | LL-HLS playlist composition |
lvqr_cli::archive::BroadcasterArchiveIndexer | on_entry_created | DVR archive index + on-disk segments |
lvqr_wasm::install_wasm_filter_bridge | on_entry_created | Per-fragment WASM filter tap |
lvqr_cli::cluster_claim::install_cluster_claim_bridge | on_entry_created | Renew cluster broadcast claim |
lvqr_agent::AgentRunner | on_entry_created | Per-broadcast user-defined agents |
lvqr_transcode::TranscodeRunner | on_entry_created | Per-broadcast ABR-ladder transcoders |
§Operator wiring
lvqr-cli exposes --transcode-rendition 720p,480p,240p (or a
.toml RenditionSpec path) and, on hw-videotoolbox builds,
--transcode-encoder software|videotoolbox. End-to-end shape:
ingest one source RTMP stream, the LL-HLS master playlist
advertises one variant per rendition + the source.
Structs§
- Audio
Passthrough Transcoder - Per-
(source, rendition)audio passthrough. Forwards every sourceFragmentverbatim to the rendition broadcaster. - Audio
Passthrough Transcoder Factory - Factory that builds one
AudioPassthroughTranscoderper source audio track, republishing fragments onto<source>/<rendition>/1.mp4. - Passthrough
Transcoder - Pass-through transcoder: logs each fragment and counts calls but does NOT encode or republish. The real encoder lives in session 105 B.
- Passthrough
Transcoder Factory - Factory that builds a
PassthroughTranscoderfor each video-track source stream acrate::TranscodeRunnersees. - Rendition
Spec - One rendition in an ABR ladder. Carries the target geometry + bitrates a downstream encoder uses to produce output fragments.
- Transcode
Runner - Builder that collects
TranscoderFactoryregistrations and installs them onto aFragmentBroadcasterRegistry. Typical usage – three rungs of the default ladder: - Transcode
Runner Handle - Cheaply-cloneable handle returned by
TranscodeRunner::install. - Transcoder
Context - Snapshot of the
(broadcast, track, FragmentMeta, rendition)tuple a freshTranscodersees at construction time. - Transcoder
Stats - Per-
(transcoder, rendition, broadcast, track)outcome counters.
Traits§
- Transcoder
- In-process consumer of source
Fragmentvalues for one(broadcast, track, rendition)tuple. The 104 A trait is observe-only; 105 B extends the concrete implementations with an output-publish side without changing the trait surface. - Transcoder
Factory - Factory that builds a
Transcoderfor one specific rendition of one specific(broadcast, track)stream.