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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Raw-sample observer hook for the RTMP / WHIP / RTSP / SRT bridges.
//!
//! Session 60 completed the Tier 2.1 consumer-side switchover: every
//! downstream fragment consumer (archive, LL-HLS, DASH) now subscribes
//! to a `lvqr_fragment::FragmentBroadcaster` owned by a shared
//! `FragmentBroadcasterRegistry`, so the `FragmentObserver` trait and
//! its transitive callback wiring are gone.
//!
//! The raw-sample surface remains: consumers that need unmuxed NAL /
//! AAC / Opus bytes (notably the WHEP egress, which packetizes per-NAL
//! into RTP) subscribe here instead of reparsing `CmafChunk` `mdat`
//! bodies. Raw samples are a read-only tap on the ingest side; they
//! never replace the fragment path.
//!
//! Implementations must be cheap and non-blocking. The observer is
//! invoked from inside the `rml_rtmp` callback chain / WHIP str0m
//! runloop / SRT reader loop, which all run on the ingest task;
//! long work there stalls ingest. Spawn a tokio task per notification
//! if downstream work is expensive.
use RawSample;
use Arc;
/// Which audio or video codec a [`RawSample`] carries.
///
/// Stamped on every [`RawSampleObserver::on_raw_sample`] call by
/// the producing bridge so the downstream consumer (notably the
/// WHEP egress and the LL-HLS audio rendition router) can pick
/// the matching output path without sniffing payload bytes. The
/// track name distinguishes kinds (`0.mp4` = video, `1.mp4` =
/// audio) and this enum distinguishes codec within the kind.
///
/// Session-level guarantees from each producer:
///
/// * `lvqr_ingest::RtmpMoqBridge` emits `H264` for video and
/// `Aac` for audio (FLV-over-RTMP is AVC + AAC only in LVQR
/// today; enhanced-RTMP HEVC is deferred).
/// * `lvqr_whip::WhipMoqBridge` emits whichever codec the
/// `str0m` answerer negotiated: `H264` / `H265` for video,
/// `Opus` for audio.
///
/// The default is `H264` so code paths that existed before
/// session 28 and never passed an explicit codec still behave
/// as they did.
/// Shared, dynamically-dispatched raw-sample observer handle.
pub type SharedRawSampleObserver = ;
/// Observer hook called by [`crate::RtmpMoqBridge`] (and every
/// other ingest bridge) for every per-sample unit it sees, *before*
/// the sample is muxed into an fMP4 fragment.
///
/// Consumers that need the raw NAL / AAC / Opus access-unit bytes
/// subscribe here instead of re-parsing `CmafChunk` mdat bodies
/// downstream. The bridge still produces fragments in parallel for
/// the broadcaster path; raw-sample observers are a read-only tap.
///
/// Implementations must be cheap and non-blocking: the observer is
/// fired from inside the ingest crate's receive loop, which runs on
/// the ingest task. Long work or blocking I/O will stall ingest;
/// spawn a tokio task per notification if downstream work is
/// expensive.
/// Drop-in raw-sample observer that does nothing.
;