Skip to content

2.0.0 — typed demux, trait-driven dispatch, decoded JSON

Choose a tag to compare

@fishloa fishloa released this 05 Jun 14:20
· 35 commits to main since this release
316e348

2.0.0 — typed demux, trait-driven dispatch, decoded JSON

Feed 188-byte TS packets in; get typed, decoded SI out. That's the whole story.
SiDemux filters by PID, validates CRCs, follows the PAT to PMT PIDs, and
version-gates so a steady carousel emits each table only once — one SectionEvent
per changed section. Every event carries owning Bytes (cheap clone, no lifetime
fight) and a lazy event.table() that dispatches to the right typed AnyTable
variant via declare_tables!, the single source of truth that also generates the
AnyDescriptor dispatcher and declare_payloads! in dvb-t2mi. For
tvheadend-class workloads the demux hot path is version-gated and allocation-free
per packet; for one-off parsing, parse_loop(descriptor_bytes) gives a lazy
iterator that never panics and surfaces Unknown for unrecognised tags. All four
crates released in lockstep at 2.0.0.

Highlights

Demux in 10 lines

use dvb_si::demux::SiDemux;
use dvb_si::tables::AnyTable;

let mut demux = SiDemux::builder().build();
for packet in ts_packets {                      // each aligned 188-byte packet
    for event in demux.feed(&packet) {          // changed sections only
        if let Ok(AnyTable::Pat(pat)) = event.table() {
            println!("PAT v{} on {}", event.version().unwrap_or(0), event.pid());
            let _ = pat;
        }
    }
}

See examples/si_dump.rs
for a complete file-reading CLI (cargo run -p dvb-si --example si_dump -- file.ts [--json]).

parse_loop → decoded JSON

use dvb_si::descriptors::{parse_loop, AnyDescriptor};

for item in parse_loop(eit_event.descriptors) {
    if let Ok(AnyDescriptor::ShortEvent(se)) = item {
        // se.event_name is DvbText — decoded on demand, never in the hot path
        println!("{}", se.event_name.decode());
    }
}

With the serde feature:

let items: Vec<_> = parse_loop(eit_event.descriptors)
    .collect::<Result<_, _>>()?;
println!("{}", serde_json::to_string_pretty(&items)?);
[
  {
    "shortEvent": {
      "language_code": "fre",
      "event_name": "Journal",
      "text": ""
    }
  }
]

Note: camelCase variant key (shortEvent), snake_case field names (event_name,
language_code) — only the enum wrapper is renamed.

T2-MI → BBFrame → SI chain

use dvb_t2mi::pump::T2miPump;
use dvb_t2mi::payload::AnyPayload;
use dvb_bbframe::{header::Bbheader, packet::up_iter};
use dvb_si::demux::SiDemux;

let mut pump = T2miPump::new(0x0006);   // T2-MI PID in the outer TS
let mut si = SiDemux::builder().build();

for ts_packet in ts_packets {
    for t2mi_event in pump.feed_ts(&ts_packet) {
        if let Ok(AnyPayload::Bbframe(bb)) = t2mi_event.payload() {
            // bb.bbframe = BBHEADER + data field; extract the inner TS packets
            let header = Bbheader::parse(bb.bbframe)?;
            for up in up_iter(&bb.bbframe[10..], &header) {
                for section_event in si.feed(&up) {
                    println!("{:?}", section_event.table());
                }
            }
        }
    }
}

(Working end-to-end version: dvb-t2mi/tests/chain.rs.)

Breaking changes

Change Migration
Text fields (event_name, service_name, …) are DvbText<'a> instead of &'a [u8] Call .raw() for wire bytes, .decode() for Cow<str>; Deref<[u8]> still works
Language/country codes are LangCode instead of [u8; 3] Access raw bytes via .0; call .as_str() for Cow<str>; Deref<[u8;3]> still works
Deserialize removed on text-bearing structs Re-parse from wire bytes instead of deserializing from JSON
Old descriptors::Descriptor subset enum removed Use parse_loop + AnyDescriptor; see §4 of the migration guide
serde JSON shape changed: decoded strings, camelCase variant keys Update JSON expectations; see §5 of the migration guide
pid::well_known constants are Pid (not u16) Call .value() or u16::from(pid) for the raw integer

Full details and before/after code for every break:
MIGRATION-2.0.md

Links


All four crates released in lockstep at 2.0.0.