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
//! Shared primitives for the dvb_si / dvb_t2mi / dvb_bbframe family.
//!
//! See individual modules for documentation: the [`Parse`] / [`Serialize`]
//! traits every wire type implements, the MPEG-2 [`crc32_mpeg2`] CRC, the
//! [`bcd`] / [`time`] / [`hex`] codecs, the [`mux`] container-mux traits, and
//! the [`cenc`] Common Encryption scheme identity those traits protect with.
//!
//! # Container-mux traits ([`mux`])
//!
//! The [`mux`] module defines the codec-agnostic vocabulary for the any-to-any
//! muxing hub, mirroring the [`Parse`] / [`Serialize`] symmetry:
//!
//! - [`Unpackage`] — demux a packaged container into an in-memory media IR.
//! - [`Package`] — mux a media IR back into a packaged container.
//! - [`Decrypt`] / [`Encrypt`] — in-place sample (un)protection.
//!
//! Each is generic over its input/output/media/config/key associated types plus
//! `type Error`; no concrete media or codec types appear here. `Unpackage` ⇄
//! `Package` and `Decrypt` ⇄ `Encrypt` are inverse pairs. Concrete
//! implementations live in the container crates (e.g. `transmux`).
//!
//! These are the *batch* container-mux contract, operating on a whole packaged
//! container at once. For the complementary *incremental* contract — feed
//! bytes in, poll typed output out, drive on a clock — see [`stage`].
//!
//! # Incremental staging ([`stage`])
//!
//! The [`stage`] module defines [`Stage`](stage::Stage), the drive shape every
//! streaming stage in the workspace (TS/FLV demuxers, HLS/LL-HLS segmenters,
//! conformance monitors, …) is converging on: `feed`/`poll`/`finish` plus a
//! [`Timestamp`](stage::Timestamp) clock parameter and deadline hooks for
//! purely time-driven work, and a [`Demand`](stage::Demand) backpressure hint.
//!
//! # Quick start
//! ```
//! use broadcast_common::{bcd, crc32_mpeg2};
//!
//! // Binary-coded decimal (as used in MJD/BCD time fields):
//! assert_eq!(bcd::from_bcd_byte(0x42), Some(42));
//! assert_eq!(bcd::to_bcd_byte(42), Some(0x42));
//!
//! // MPEG-2 CRC-32 over a section body (deterministic):
//! let crc = crc32_mpeg2::compute(&[0xDE, 0xAD, 0xBE, 0xEF]);
//! assert_eq!(crc, crc32_mpeg2::compute(&[0xDE, 0xAD, 0xBE, 0xEF]));
//! ```
// The crate's runnable examples, embedded so they render on docs.rs and stay in
// sync with the actual `examples/*.rs` files (shown, not compiled).
extern crate alloc;
pub use CencScheme;
pub use ;
pub use ;
pub use ;
/// Generate a [`core::fmt::Display`] impl for a spec/field enum that delegates
/// to an inherent `fn name(&self) -> &'static str`.
///
/// This is the project-wide convention for every public spec/field enum across
/// the `dvb-*` crates (see issue #204): `name()` is the hand-written,
/// zero-alloc static spec token (lossy on the reserved/unknown arm, which
/// returns `"reserved"`), and `Display` is the lossless, composable view that
/// delegates to it. The labels themselves live in `name()` in source — never in
/// this macro — so they sit next to the variant docs and stay greppable. This
/// macro carries no labels; it only removes the otherwise-identical `Display`
/// boilerplate and keeps the two in lockstep.
///
/// # Forms
/// - `impl_spec_display!(Ty)` — every variant's `Display` is exactly `name()`.
/// Use when there is no byte-bearing catch-all (or its byte need not be
/// shown), e.g. a unit `Reserved` variant.
/// - `impl_spec_display!(Ty, Var1, Var2, …)` — each named variant is a
/// single-field tuple binding a byte; `Display` renders it as
/// `"{name}(0x{:02X})"` so the value is preserved (e.g. `Reserved(0x1A)` →
/// `reserved(0x1A)`, `UserDefined(0x1A)` → `user defined(0x1A)`). All other
/// variants delegate to `name()`.
///
/// ```
/// pub enum Mode { Normal, HighEfficiency, Reserved(u8) }
/// impl Mode {
/// pub fn name(&self) -> &'static str {
/// match self {
/// Self::Normal => "normal",
/// Self::HighEfficiency => "high efficiency",
/// Self::Reserved(_) => "reserved",
/// }
/// }
/// }
/// broadcast_common::impl_spec_display!(Mode, Reserved);
/// assert_eq!(Mode::Normal.to_string(), "normal");
/// assert_eq!(Mode::Reserved(0x1A).to_string(), "reserved(0x1A)");
/// ```