#![cfg(feature = "ts")]
use std::fs;
use std::path::{Path, PathBuf};
use dvb_si::demux::SiDemux;
use mpeg_ts::ts::TS_PACKET_SIZE;
fn streams_dir() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join(".test-streams")
}
fn ts_files(dir: &Path) -> Vec<PathBuf> {
let mut v = Vec::new();
if let Ok(rd) = fs::read_dir(dir) {
for entry in rd.flatten() {
let p = entry.path();
if p.extension().is_some_and(|x| x == "ts") {
v.push(p);
}
}
}
v.sort();
v
}
#[test]
fn downloaded_streams_parse_without_panic() {
let files = ts_files(&streams_dir());
if files.is_empty() {
eprintln!(
"downloaded_streams: SKIPPED — no captures in .test-streams/. \
Run `tools/fetch-test-streams.sh` to enable the extended-corpus tests."
);
return;
}
for f in files {
let data = fs::read(&f).expect("read capture");
let name = f
.file_name()
.unwrap_or_default()
.to_string_lossy()
.into_owned();
let mut demux = SiDemux::builder().build();
let (mut sections, mut errors) = (0usize, 0usize);
for chunk in data.chunks(TS_PACKET_SIZE) {
if chunk.len() != TS_PACKET_SIZE || chunk[0] != 0x47 {
continue;
}
for ev in demux.feed(chunk) {
match ev.table_section() {
Ok(_) => sections += 1,
Err(_) => errors += 1,
}
}
}
eprintln!(
"downloaded_streams: {name} — {sections} SI sections parsed, \
{errors} parse errors, {} bytes",
data.len()
);
assert!(
sections > 0,
"{name}: expected at least one SI section from a real broadcast mux"
);
}
}