Expand description
ETSI TR 101 290 v1.4.1 transport-stream conformance monitor.
Implements the first-priority (Table 5.0a, indicators 1.1–1.6),
second-priority (Table 5.0b, indicators 2.1–2.3b, 2.5–2.6), and
third-priority (Table 5.0c, indicators 3.1–3.10) indicator sets —
see docs/tr_101_290.md for the full spec transcription and the
crate-coverage mapping.
§T-STD buffer model (indicators 3.3, 3.9, 3.10)
A partial ISO/IEC 13818-1 T-STD buffer model (see src/tstd.rs) drives
the buffer-model indicators:
- 3.3
BufferError: TBsys overflow detection (512-byte buffer at 1 Mbit/s drain, fed at PSI section completion). TBn overflow is deferred — it requires the coded bitrateRxnfrom descriptors. - 3.9
EmptyBufferError: TBn (per-PID) and TBsys (global) empty at least once per second. MBn empty check is deferred. - 3.10
Data_delay_error: Data delay > 1 s through TBn and TBsys. Still-picture 60 s threshold is tracked but not yet differentiated. - 2.4
PcrAccuracyError: not implemented — requires hardware arrival timestamps with ±500 ns resolution. The variant exists for documentation completeness only.
MBn/EBn/Bn/Bsys buffer modelling is deferred — it requires codec-level buffer sizes from descriptors (multiplex_buffer_descriptor, smoothing_buffer_descriptor) not yet parsed by the monitor.
Feasible but deferred: the 25 ms minimum-gap dimension shared by 3.1.a /
3.2 / 3.5.a / 3.6.a / 3.7 / 3.8 (needs per-(table_id, section_number)
tracking to avoid false positives on dense multi-section tables); the
_other repetition sub-clauses 3.1.b / 3.5.b / 3.6.b (need TR 101 211
interval rules); the EIT P/F pairing check 3.6.c.
§Caller-supplied time
ConformanceMonitor::feed takes a core::time::Duration timestamp
alongside each TS packet. All presence/absence timeout checks (1.3.a, 1.5.a,
1.6, 2.3a, 2.3b, 2.5, 3.2) are evaluated against this clock. The caller
must ensure that timestamps are monotonic non-decreasing across calls;
the monitor does not enforce this but non-monotonic timestamps will produce
spurious events.
§References
- ETSI TR 101 290 v1.4.1 (2020-06), §5.2.1, Table 5.0a
- ETSI TR 101 290 v1.4.1 (2020-06), §5.2.2, Table 5.0b
- ETSI TR 101 290 v1.4.1 (2020-06), §5.2.3, Table 5.0c
- ISO/IEC 13818-1 (MPEG-2 Systems)
§Examples
Two runnable examples ship with this crate (cargo run -p dvb-conformance --example <name>).
§monitor_stream
//! Basic: run the TR 101 290 conformance monitor over a capture and print the
//! headline stats.
//!
//! Run with: `cargo run -p dvb-conformance --example monitor_stream`
//!
//! Reads the committed `m6-single.ts` fixture from the sibling `dvb-si` crate
//! at runtime, so the example compiles even when the fixture is absent.
use core::time::Duration;
use dvb_conformance::ConformanceMonitor;
const PKT: usize = 188;
const INTER_PACKET_US: u64 = 40; // ~nominal spacing for the timing checks
fn main() {
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/../dvb-si/tests/fixtures/m6-single.ts"
);
let data = match std::fs::read(path) {
Ok(b) => b,
Err(e) => {
eprintln!("fixture not available ({e}); nothing to do");
return;
}
};
let mut monitor = ConformanceMonitor::new();
let mut total_events = 0usize;
for (i, pkt) in data.chunks(PKT).enumerate() {
if pkt.len() < PKT {
break;
}
let t = Duration::from_micros(i as u64 * INTER_PACKET_US);
total_events += monitor.feed(pkt, t).len();
}
let stats = monitor.stats();
println!("packets analysed : {}", stats.packets);
println!("in sync : {}", stats.in_sync);
println!("events raised : {total_events}");
}§priority_breakdown
//! Advanced: run the TR 101 290 monitor and break the findings down by
//! measurement priority and indicator — the shape of a real QoS report.
//!
//! Run with: `cargo run -p dvb-conformance --example priority_breakdown`
use core::time::Duration;
use dvb_conformance::{ConformanceEvent, ConformanceMonitor, Priority};
use std::collections::BTreeMap;
const PKT: usize = 188;
const INTER_PACKET_US: u64 = 40;
fn main() {
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/../dvb-si/tests/fixtures/m6-single.ts"
);
let data = match std::fs::read(path) {
Ok(b) => b,
Err(e) => {
eprintln!("fixture not available ({e}); nothing to do");
return;
}
};
let mut monitor = ConformanceMonitor::new();
let mut events: Vec<ConformanceEvent> = Vec::new();
for (i, pkt) in data.chunks(PKT).enumerate() {
if pkt.len() < PKT {
break;
}
let t = Duration::from_micros(i as u64 * INTER_PACKET_US);
events.extend_from_slice(monitor.feed(pkt, t));
}
let (mut p1, mut p2, mut p3) = (0u32, 0u32, 0u32);
let mut by_indicator: BTreeMap<String, u32> = BTreeMap::new();
for ev in &events {
match ev.priority {
Priority::First => p1 += 1,
Priority::Second => p2 += 1,
Priority::Third => p3 += 1,
_ => {}
}
*by_indicator.entry(ev.indicator.to_string()).or_default() += 1;
}
let stats = monitor.stats();
println!("== TR 101 290 report ({} packets) ==", stats.packets);
println!("Priority 1 (must decode) : {p1}");
println!("Priority 2 (recommended) : {p2}");
println!("Priority 3 (application) : {p3}");
if by_indicator.is_empty() {
println!("\nno conformance events — stream is clean ✔");
} else {
println!("\nby indicator:");
for (name, n) in &by_indicator {
println!(" {name:<24} {n}");
}
}
}Structs§
- Config
- Configurable hysteresis and timeout parameters.
- Conformance
Event - One raised conformance error.
- Conformance
Monitor - ETSI TR 101 290 transport-stream conformance monitor.
- Stats
- Diagnostic counters.