Expand description
ETSI TS 102 773 v1.4.1 DVB-T2 Modulator Interface (T2-MI) parser + builder.
Entry points:
Parse/Serialize— the two symmetric contracts every payload type implements.packet— T2-MI packet header and type parsing.payload— BBFrame, L1, FEF, timestamp, and addressing payload types.payload::PayloadRegistry/pump::T2miEvent::payload_with— register private packet types and dispatch through the registry.payload::AnyPayload::dispatch_with— registry-aware dispatch for custom types.crc— CRC-32 per Annex A.
§RFU policy
Payload parsers REJECT non-zero reserved (rfu) bits with
ReservedBitsViolation and serialize them as 0 — with one deliberate
exception: individual addressing (0x21) PRESERVES its leading rfu byte
verbatim so gateway streams round-trip byte-exact (see
payload::individual_addressing).
§Quickstart: pump a TS, get typed payloads
pump::T2miPump filters a TS by PID, reassembles + CRC-validates T2-MI
packets, and hands back events whose payload
dispatches to a typed payload::AnyPayload:
use dvb_t2mi::pump::T2miPump;
use dvb_t2mi::payload::AnyPayload;
let mut pump = T2miPump::new(0x0006); // T2-MI PID from the PMT
for packet in &ts_packets { // each aligned 188-byte TS packet
for event in pump.feed_ts(packet) {
if let Ok(AnyPayload::Bbframe(bb)) = event.payload() {
println!("BBFrame plp_id={}", bb.plp_id);
}
}
}§The full signal chain
T2-MI carries DVB-T2 BBFrames, which carry the inner MPEG-TS, which carries
SI. The crates compose end to end — T2-MI here, BBFrame extraction in
dvb-bbframe, SI demux in
dvb-si:
TS (T2-MI PID) ─▶ T2miPump ─▶ AnyPayload::Bbframe
│ bb.bbframe
▼
dvb_bbframe::Bbheader::parse + up_iter
│ inner TS packets
▼
dvb_si::demux::SiDemux ─▶ AnyTableSectionA complete, working version of this chain (synthetic fixture, every layer
built and asserted) lives in dvb-t2mi/tests/chain.rs.
§Features
| Feature | Default | Enables |
|---|---|---|
ts | on | pump::T2miPump — PID-filtered TS reassembly + CRC validation. Off → bring your own complete T2-MI packet bytes. |
serde | on | Serialize-only — for display/export (JSON via serde_json); parsing FROM JSON is deliberately unsupported, re-parse from wire bytes. Serialize on every packet/payload type. |
yoke | off | yoke::Yokeable on the zero-copy payload view types — own a parsed T2-MI payload past the input buffer’s borrow without re-parsing. |
§Header-only example
use dvb_t2mi::packet::Header;
use dvb_common::Parse;
let buf = [0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
let hdr = Header::parse(&buf[..]).unwrap();
assert_eq!(hdr.payload_len_bits, 0);§Examples
Two runnable examples ship with this crate (cargo run -p dvb-t2mi --example <name>).
§parse_header
//! Basic: parse a T2-MI packet header from raw bytes.
//!
//! Run with: `cargo run -p dvb-t2mi --example parse_header`
use dvb_common::Parse;
use dvb_t2mi::packet::Header;
fn main() {
// A 6-byte T2-MI packet header: packet_type, packet_count, superframe_idx,
// reserved, and a 16-bit payload length in bits (here: 0).
let bytes = [0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00];
let hdr = Header::parse(&bytes).expect("valid T2-MI header");
println!("packet_type : {:?}", hdr.packet_type);
println!("packet_count : {}", hdr.packet_count);
println!("superframe_idx : {}", hdr.superframe_idx);
println!("payload_len_bits: {}", hdr.payload_len_bits);
}§pump_capture
//! Advanced: pump a real T2-MI stream out of an MPEG-TS capture and tally the
//! payload types (BBFrames, L1 signalling, timestamps).
//!
//! Run with: `cargo run -p dvb-t2mi --example pump_capture` (needs the default
//! `ts` feature). Reads the committed `colombia-capital-t2mi.ts` fixture at
//! runtime.
use dvb_t2mi::payload::AnyPayload;
use dvb_t2mi::pump::T2miPump;
const T2MI_PID: u16 = 0x0040;
const PKT: usize = 188;
fn main() {
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/fixtures/colombia-capital-t2mi.ts"
);
let data = match std::fs::read(path) {
Ok(b) => b,
Err(e) => {
eprintln!("fixture not available ({e}); nothing to do");
return;
}
};
let mut pump = T2miPump::new(T2MI_PID);
let (mut bbframes, mut l1, mut timestamps, mut other) = (0u32, 0u32, 0u32, 0u32);
for pkt in data.chunks(PKT) {
if pkt.len() < PKT {
break;
}
for event in pump.feed_ts(pkt) {
match event.payload() {
Ok(AnyPayload::Bbframe(_)) => bbframes += 1,
Ok(AnyPayload::L1Current(_)) => l1 += 1,
Ok(AnyPayload::Timestamp(_)) => timestamps += 1,
Ok(_) => other += 1,
Err(_) => {}
}
}
}
println!("T2-MI on PID {T2MI_PID:#06X}:");
println!(" BBFrame payloads : {bbframes}");
println!(" L1-current packets : {l1}");
println!(" timestamp packets : {timestamps}");
println!(" other payloads : {other}");
println!(" CRC-32 failures : {}", pump.stats().crc_failures);
}Re-exports§
Modules§
- crc
- T2-MI CRC helpers.
- error
- Error type returned by every parser in this crate.
- inner_
ts ts - Inner-TS recovery — the single driver from a T2-MI PID to the inner MPEG-TS.
- packet
- T2-MI packet header and type parsing.
- payload
- T2-MI payload types (§5.2.1 - §5.2.12).
- pump
ts T2miPump— owning-Bytesfeed-and-iterate T2-MI pump.- traits
- T2-MI–specific traits.
Parse/Serializeare provided bydvb_commonand imported directly at call sites. - ts
ts - TS packet reassembly utilities.