use std::process::ExitCode;
use dvb_si::demux::SiDemux;
use dvb_si::tables::AnyTableSection;
use crate::util::{for_each_packet, read_file};
fn table_name(table: &AnyTableSection<'_>) -> String {
match table {
AnyTableSection::Unknown { table_id, .. } => format!("UNKNOWN(0x{table_id:02X})"),
t => t.name().to_string(),
}
}
pub fn run(args: &[String]) -> ExitCode {
let mut path: Option<String> = None;
let mut json = false;
for arg in args {
match arg.as_str() {
"--json" => json = true,
"-h" | "--help" => {
eprintln!("usage: dvb-tools dump <file.ts> [--json]");
return ExitCode::SUCCESS;
}
other if other.starts_with('-') => {
eprintln!("dvb-tools dump: unknown option {other}");
return ExitCode::FAILURE;
}
other => path = Some(other.to_string()),
}
}
let Some(path) = path else {
eprintln!("usage: dvb-tools dump <file.ts> [--json]");
return ExitCode::FAILURE;
};
let data = match read_file(&path, "dvb-tools dump") {
Ok(d) => d,
Err(code) => return code,
};
let mut demux = SiDemux::builder().build();
for packet in for_each_packet(&data) {
for event in demux.feed(&packet) {
match event.table_section() {
Ok(table) => {
if json {
match serde_json::to_string_pretty(&table) {
Ok(s) => println!("{s}"),
Err(e) => {
eprintln!("dvb-tools dump: serialize {}: {e}", event.pid());
}
}
} else {
let name = table_name(&table);
match event.version() {
Some(v) => println!(
"pid={} {name} v{v} sn={}",
event.pid(),
event.section_number().unwrap_or(0)
),
None => println!("pid={} {name}", event.pid()),
}
match &table {
AnyTableSection::PmtSection(pmt) => {
for st in &pmt.streams {
println!(
" es pid=0x{:04X} stream_type={}",
st.elementary_pid,
st.stream_type.name()
);
}
}
AnyTableSection::SdtSection(sdt) => {
for s in &sdt.services {
println!(
" service 0x{:04X} running_status={}",
s.service_id,
s.running_status.name()
);
}
}
_ => {}
}
}
}
Err(e) => eprintln!("pid={} parse error: {e}", event.pid()),
}
}
}
let s = demux.stats();
eprintln!(
"-- packets={} sections={} emitted={} suppressed={} crc_failures={} malformed={}",
s.packets,
s.sections_completed,
s.emitted,
s.suppressed,
s.crc_failures,
s.malformed_packets
);
ExitCode::SUCCESS
}