use container_probe::{
Confidence, Detail::Ebml, Detail::Isobmff, DocType, Format, IsobmffLayout, Probe,
};
use std::fs;
fn fixture(rel: &str) -> Vec<u8> {
fs::read(format!("{}/../{}", env!("CARGO_MANIFEST_DIR"), rel))
.unwrap_or_else(|e| panic!("failed to read fixture {rel}: {e}"))
}
fn assert_isobmff(rel: &str, brand: &[u8; 4]) {
let p = container_probe::probe(&fixture(rel));
assert!(
matches!(
p,
Probe::Identified {
format: Format::Isobmff,
confidence: Confidence::STRUCTURAL,
detail: Isobmff {
major_brand: Some(b),
..
},
..
} if &b == brand
),
"{rel}: expected Isobmff STRUCTURAL brand={:?}, got {p:?}",
String::from_utf8_lossy(brand)
);
}
fn assert_matroska(rel: &str) {
let p = container_probe::probe(&fixture(rel));
assert!(
matches!(
p,
Probe::Identified {
format: Format::Matroska,
confidence: Confidence::CERTAIN,
detail: Ebml {
doc_type: DocType::Matroska,
..
},
..
}
),
"{rel}: expected Matroska CERTAIN DocType::Matroska, got {p:?}"
);
}
fn assert_webm(rel: &str) {
let p = container_probe::probe(&fixture(rel));
assert!(
matches!(
p,
Probe::Identified {
format: Format::WebM,
confidence: Confidence::CERTAIN,
detail: Ebml {
doc_type: DocType::Webm,
..
},
..
}
),
"{rel}: expected WebM CERTAIN DocType::Webm, got {p:?}"
);
}
fn assert_mxf(rel: &str) {
let p = container_probe::probe(&fixture(rel));
assert!(
matches!(
p,
Probe::Identified {
format: Format::Mxf,
confidence: Confidence::CERTAIN,
..
}
),
"{rel}: expected Mxf CERTAIN, got {p:?}"
);
}
#[test]
fn isobmff_brand_isom() {
for f in [
"fixtures/mp4/h264_high.mp4",
"fixtures/mp4/hevc_main.mp4",
"fixtures/mp4/av1.mp4",
"fixtures/mp4/vp9.mp4",
"fixtures/mp4/opus.mp4",
"fixtures/mp4/flac.mp4",
"fixtures/mp4/cenc.mp4",
"fixtures/mp4/stpp.mp4",
"fixtures/mp4/prft.mp4",
"fixtures/mp4/colr_hdr.mp4",
"fixtures/mp4/aac_sgpd.mp4",
"fixtures/mp4/cmaf/av_frag.mp4",
"fixtures/mp4/progressive/av_prog.mp4",
] {
assert_isobmff(f, b"isom");
}
}
#[test]
fn isobmff_brand_iso5_fragmented() {
for f in [
"fixtures/mp4/frag/av1.frag.mp4",
"fixtures/mp4/frag/vvc.frag.mp4",
] {
assert_isobmff(f, b"iso5");
}
}
#[test]
fn matroska_mkv() {
for f in [
"fixtures/mkv/h264_aac.mkv",
"fixtures/mkv/hevc_aac.mkv",
"fixtures/mkv/vp9_opus.mkv",
] {
assert_matroska(f);
}
}
#[test]
fn webm() {
for f in [
"fixtures/webm/vorbis.webm",
"fixtures/webm/vp8_opus.webm",
"fixtures/webm/vp9_opus.webm",
] {
assert_webm(f);
}
}
#[test]
fn mxf() {
assert_mxf("fixtures/mxf/op1a_mpeg2_pcm.mxf");
assert_mxf("st377-1/tests/fixtures/synthetic_minimal.mxf");
}
#[test]
fn mpeg_ps() {
let p = container_probe::probe(&fixture("fixtures/ps/h264_ac3.ps"));
assert!(
matches!(
p,
Probe::Identified {
format: Format::MpegPs,
confidence: Confidence::STRUCTURAL,
..
}
),
"fixtures/ps/h264_ac3.ps: expected MpegPs STRUCTURAL, got {p:?}"
);
}
fn assert_layout(rel: &str, expect: IsobmffLayout) {
let data = fixture(rel);
match container_probe::probe(&data) {
Probe::Identified {
format: Format::Isobmff,
detail: Isobmff { layout, .. },
..
} => assert_eq!(layout, expect, "{rel}"),
other => panic!("{rel} must be Isobmff, got {other:?}"),
}
}
#[test]
fn progressive_mp4s_report_progressive_layout() {
for rel in [
"fixtures/mp4/h264_high.mp4",
"fixtures/mp4/cenc.mp4",
"fixtures/mp4/av1.mp4",
"fixtures/mp4/progressive/av_prog.mp4",
"fixtures/mp4/progressive/av_faststart.mp4",
] {
assert_layout(rel, IsobmffLayout::Progressive);
}
}
#[test]
fn fragmented_mp4s_report_fragmented_layout() {
for rel in [
"fixtures/mp4/frag/av1.frag.mp4",
"fixtures/mp4/frag/vvc.frag.mp4",
"fixtures/mp4/cmaf/av_frag.mp4",
"fixtures/mp4/llcmaf/ll_chunked.mp4",
] {
assert_layout(rel, IsobmffLayout::Fragmented);
}
}
#[test]
fn major_brand_alone_cannot_discriminate_layout() {
let brand_of = |rel: &str| -> Option<[u8; 4]> {
match container_probe::probe(&fixture(rel)) {
Probe::Identified {
detail: Isobmff { major_brand, .. },
..
} => major_brand,
other => panic!("{rel}: {other:?}"),
}
};
let progressive = brand_of("fixtures/mp4/h264_high.mp4");
let fragmented = brand_of("fixtures/mp4/cmaf/av_frag.mp4");
assert_eq!(
progressive, fragmented,
"these two fixtures must share a brand for this test to mean anything"
);
assert_eq!(progressive, Some(*b"isom"));
}
#[test]
fn a_prefix_without_moof_or_moov_reports_unknown_layout() {
let data = fixture("fixtures/mp4/cmaf/av_frag.mp4");
match container_probe::probe(&data[..64]) {
Probe::Identified {
format: Format::Isobmff,
detail: Isobmff { layout, .. },
..
} => assert_eq!(layout, IsobmffLayout::Unknown),
other => panic!("a 64-byte ISOBMFF prefix should still identify, got {other:?}"),
}
}