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
//! Smooth Streaming live origin engine (issue #2453): the client Manifest and
//! fragment *decision* logic, driven from a shared `media_plane::Trunk` — the
//! same shape as `hls-runtime`'s `server` module.
//!
//! Nothing here ever `.await`s or opens a socket. [`SmoothOrigin::manifest`]
//! renders the current live Manifest and the `ServedEgress` implementation
//! answers one parsed [`SmoothRequest`] with an
//! [`EgressResponse`](media_plane::egress::EgressResponse) (`Ready`, `Await`,
//! `BadRequest`, `NotFound`) — never blocking the caller. The manifest is
//! built as a `broadcast-smooth` model and rendered by its own `to_xml`; no
//! XML is written here. Each track's codec parameters come from `transmux`'s
//! [`resolve_codec`](transmux::resolve_codec), the same resolver the packager
//! uses, so the manifest advertises exactly what the fragments carry.
//!
//! # The host's bookkeeping, not the origin's
//!
//! Which segments and tracks a program presents is the host's own
//! bookkeeping (the set its DASH window and HLS origin already render from),
//! so the origin asks for both through [`SegmentProvider`] and
//! [`TrackProvider`] rather than caching the media itself. The `Trunk` stays
//! the single copy.
//!
//! # The caller-driven wait loop
//!
//! A Manifest cannot be rendered before the trunk has an init segment, a
//! track set and at least one published segment. The origin answers
//! `EgressResponse::Await` until then; an adapter registers `Trunk::listen`
//! *before* retrying so no publish is missed:
//!
//! ```text
//! loop {
//! let listener = trunk.listen();
//! match origin.resolve(request, now, await_policy) {
//! EgressResponse::Await { .. } => { /* bounded wait on `listener` */ }
//! answer => return answer,
//! }
//! }
//! ```
//!
//! # `std`-only
//!
//! Like `media_plane::Trunk` itself, this module needs `std::sync::Mutex`, so
//! it is compiled only when this crate's `std` feature is enabled (the
//! default). A `--no-default-features` build gets [`crate::client`] alone.
pub use ;