1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! 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):
//!
//! * [`Transcoder`] trait + [`TranscoderFactory`] +
//! [`TranscoderContext`] -- the "subscribe / drain / panic-isolate"
//! shape generalised from `lvqr_agent::Agent`. Each factory
//! carries its own [`RenditionSpec`].
//! * [`TranscodeRunner`] + [`TranscodeRunnerHandle`] -- registry-side
//! installer + cheaply-cloneable handle, mirroring
//! `lvqr_agent::AgentRunner`.
//! * [`RenditionSpec`] with width / height / bitrate fields,
//! [`RenditionSpec::preset_720p`] / `preset_480p` / `preset_240p`
//! constructors, and [`RenditionSpec::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.mp4` audio
//! 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`] -- the
//! `appsrc -> qtdemux -> h264parse -> avdec_h264 -> videoscale ->
//! x264enc -> ... -> mp4mux -> appsink` ladder, one worker thread
//! per `(source, rendition)` pair, bounded mpsc.
//! * [`AacToOpusEncoder`] / [`AacToOpusEncoderFactory`] -- AAC -> Opus
//! transcoder used by `lvqr-whep` (under its `aac-opus` feature)
//! so AAC publishers reach Opus-negotiated WHEP subscribers.
//!
//! Behind the `hw-videotoolbox` feature (implies `transcode`;
//! requires the `applemedia` plugin from gst-plugins-bad):
//!
//! * [`VideoToolboxTranscoder`] / [`VideoToolboxTranscoderFactory`]
//! -- mirrors `SoftwareTranscoderFactory` but swaps the
//! `x264enc bitrate=... tune=zerolatency speed-preset=superfast`
//! pipeline element for Apple's HW-only `vtenc_h264_hw bitrate=...
//! realtime=true allow-frame-reordering=false
//! max-keyframe-interval=60`. HW-only path is intentional: a
//! factory that silently falls back to CPU encoding under load
//! defeats the point of an operator-pickable hardware tier.
//! `is_available()` probes for the encoder element at construction
//! and `build()` opts out cleanly with a warn log when missing.
//!
//! NVENC, VAAPI, and QSV stay deferred to v1.2 per the README's
//! existing language. When a third HW backend lands, that session
//! is also the right moment to extract a shared `pipeline.rs`
//! scaffolding module from `software.rs` + `videotoolbox.rs`.
//!
//! ## 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.
pub use ;
pub use ;
pub use RenditionSpec;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;