Skip to main content

Crate container_probe

Crate container_probe 

Source
Expand description

Robust media container-format detection over a caller-owned byte slice.

container-probe identifies whether a byte prefix (a file’s leading bytes, a network read) is an MPEG-2 Transport Stream, an ISOBMFF file, a Matroska/WebM file, MXF, MPEG—PS, FLV, WAV, Ogg, ASF, or a raw ADTS AAC / MP3 / Annex B elementary stream. One-shot over a slice: the crate holds no buffer, owns no IO, and keeps no state.

§Detected formats

FormatHow it is detectedBest confidence tier
MPEG-2 TSsync lattice over 188/192/204/208-byte stridesLATTICE_STRONG
ISOBMFFbox-chain walk (ISO/IEC 14496-12 §4.2)STRUCTURAL
Matroska/WebMEBML magic + DocTypeCERTAIN
MXFpartition-pack key + BER lengthCERTAIN
MPEG-PSpack start code + marker bitsSTRUCTURAL
FLV"FLV" signature + header fieldsSTRONG
WAV"RIFF".."WAVE"STRONG
Ogg"OggS"STRONG
ASF16-byte header GUIDSTRONG
ADTS AACframe-length chainLATTICE_STRONG
MP3frame-length chainLATTICE_STRONG
Annex B (H.264)start-code NAL chainLATTICE_STRONG

§Known gaps

  • Annex B detection is H.264 only. HEVC (H.265) NAL units use a 2-byte header with nal_unit_type at bits [6:1], which this prober does not parse — it validates the H.264 1-byte header, so an HEVC stream fails the range check at the first NAL. HEVC is deliberately not implemented: this workspace does not implement a format without a real fixture to test it against, and no HEVC Annex B fixture exists in the repository.

§The scored confidence model

Every registered prober runs over the same bytes and returns a scored candidate (an Evidence): a Confidence tier and a Detail. All probers always run, so the answer does not depend on declaration order. The highest score wins:

TierValueMeaning
CERTAIN240Magic plus a structural confirmation
STRONG192Unambiguous magic at a defined offset
STRUCTURAL160A validated structure chain
LATTICE_STRONG128>= 8 lattice/frame confirmations
LATTICE_WEAK963-7 lattice/frame confirmations
HEURISTIC64A signature with real false-positive risk

If the top two candidates are within TIE_THRESHOLD (16), the result is Probe::Ambiguous with every candidate listed — never an arbitrary pick. A container matched at LATTICE_STRONG or above zeroes every elementary-stream candidate (ADTS/MP3/Annex B), on the principle that ES frames inside a container payload are expected data, not evidence the file is a raw stream.

§Insufficient vs Unknown

These are deliberately distinct, and a caller must not conflate them:

  • Probe::Insufficient { need_at_least } means read more bytes — nothing conclusive matched yet, but a longer buffer could change that. Use need_at_least to decide how much more to buffer.
  • Probe::Unknown means stop — nothing matched and more bytes will not help.

§The loop that terminates

need_at_least is guaranteed to exceed the number of bytes the probe actually examined, which is min(len, budget) — not len. So a caller that only grows the buffer, while leaving probe’s fixed DEFAULT_BUDGET in place, can stall once the budget caps the read. Feed need_at_least back as the budget too:

let mut buf = read_at_least(DEFAULT_BUDGET);
let verdict = loop {
    match probe_with_budget(&buf, buf.len()) {
        Probe::Insufficient { need_at_least, .. } if need_at_least > buf.len() => {
            let grown = read_at_least(need_at_least);
            // EOF with nothing conclusive: stop. The probe cannot answer
            // from this file, and no further read will change that.
            if grown.len() <= buf.len() {
                break Probe::Unknown;
            }
            buf = grown;
        }
        other => break other,
    }
};

Passing buf.len() as the budget is what makes each turn examine ground the last one did not. The grown.len() <= buf.len() arm is the caller’s own termination guarantee at EOF, and is not optional: the crate cannot know whether more bytes exist.

§no_std + alloc

The crate is #![no_std] and links only alloc. Its single runtime dependency is broadcast-common. The only allocation is the candidate Vec of a genuine Ambiguous result. Build it without the default features for a pure-alloc target.

§Example

use container_probe::{probe, Probe};

// An empty slice is `Insufficient`: reading more bytes could make it any
// registered format, so a caller must not stop — it must read more. This is
// the honest contract for a buffer that has not yet ruled anything out.
let p = probe(&[]);
match p {
    Probe::Insufficient { need_at_least, .. } => assert!(need_at_least >= 1),
    _ => unreachable!("an empty slice cannot be concluded from"),
}

§Non-goals

  • No demuxing — the probe identifies a format; parsing its content is a demuxer’s job.
  • No codec identification — “this is TS” is the answer, not “this TS carries H.264”.
  • No file IOno_std; the caller supplies bytes.
  • No format conversion or repair — identification only.
  • No incremental/streaming API — the probe is one-shot over a slice; a streaming caller reads more and re-probes, guided by Insufficient’s need_at_least.

no_std + alloc; runtime dependency is broadcast-common only.

Structs§

Candidate
One scored candidate: a format, the evidence strength behind it, and what the prober learned on the way.
Confidence
Evidence strength behind a match, in named tiers (see the TIER_* constants and the crate-root confidence model).

Enums§

Detail
What a prober learned on the way to its conclusion — the difference between “it is TS” and “it is TS, 192-byte stride, first sync at offset 4”.
DocType
The EBML DocType string ("webm" or "matroska") decoded from an EBML header’s EBMLDocType element.
Format
The identified container/stream format.
IsobmffLayout
How an ISOBMFF file carries its sample metadata — the discriminator a consumer needs to choose a demuxer.
PartitionKind
MXF Partition Pack kind — the PartitionKind byte, byte 14 of the Partition Pack Key UL (SMPTE ST 377-1 §7.2-7.4).
Probe
What the probe concluded.

Constants§

DEFAULT_BUDGET
Default byte budget for probe — comfortably above the worst case (a 208-byte-stride TS lattice needing 8 confirmations plus a full phase search). Design §Performance.

Functions§

probe
Probe with the default budget (DEFAULT_BUDGET).
probe_with_budget
Probe reading at most budget bytes of data.