mux: StreamSelection primitive + apply sites for per-title stream selection

The demux pipeline is declaration-driven off DiscTitle.streams (build_demux_state,
DiscStream::new, and the MKV writer all key off that list), so 'which streams to
keep' is already a pipeline capability with no public knob. This adds the knob:

- mux/select.rs: StreamSelection { audio, subtitle: PidFilter::All | Only(Vec<u16>) }
  + apply(&mut DiscTitle): keep Video always, keep Audio/Subtitle whose PID the
  filter lists, prune the rest (and the parallel codec_privates in lockstep);
  error SelectionPidUnknown on a listed PID absent from the title (fail loud, not
  a silently-missing track). Pure; 6 unit tests. Re-exported at crate root.
- Error::SelectionPidUnknown (E6014).
- MuxOptions gains  (+ derives Default now) applied in mux_stream's
  Iso/Session arms before the highway/DiscStream builds demux state (and before
  probe_and_remap's DVD AC-3 PID rewrite). InputOptions gains  applied
  in input()'s iso arm right after the title-index bounds check.

PIDs not languages -- language->PID is caller/engine policy. Default All/All is a
no-op (apply gated on !is_all()), so the no-selection path is byte-identical:
nothing below the title-finalization line changes (ts/ps/demux_thread/
pipelined_stream/mkv/disc untouched). All 2488 lib tests pass on 1.86.
This commit is contained in:
MattJackson
2026-07-28 13:14:40 -07:00
parent d22d09c898
commit 0ee8341aea
7 changed files with 367 additions and 5 deletions
+11
View File
@@ -59,6 +59,7 @@ pub const E_MKV_INVALID: u16 = 6008;
pub const E_NO_STREAMS: u16 = 6009;
pub const E_HALTED: u16 = 6010;
pub const E_MAPFILE_INVALID: u16 = 6011;
pub const E_SELECTION_PID_UNKNOWN: u16 = 6014;
pub const E_UDF_BUFFER_TOO_SMALL: u16 = 6012;
pub const E_UDF_NOT_FILESYSTEM: u16 = 6013;
@@ -292,6 +293,12 @@ pub enum Error {
IfoParse,
MkvInvalid,
NoStreams,
/// A [`crate::StreamSelection`] listed a PID that does not exist in the
/// title's declared streams — a caller bug (e.g. a stale scan), reported
/// loudly rather than silently producing an MKV missing a requested track.
SelectionPidUnknown {
pid: u16,
},
/// ddrescue mapfile parse failed. `kind` is a stable, language-neutral
/// identifier (e.g. `"status_char"`, `"hex"`); not a translatable
/// English message.
@@ -579,6 +586,7 @@ impl Error {
Error::IfoParse => E_IFO_PARSE,
Error::MkvInvalid => E_MKV_INVALID,
Error::NoStreams => E_NO_STREAMS,
Error::SelectionPidUnknown { .. } => E_SELECTION_PID_UNKNOWN,
Error::MapfileInvalid { .. } => E_MAPFILE_INVALID,
Error::AacsNoKeys => E_AACS_NO_KEYS,
Error::AacsCertShort => E_AACS_CERT_SHORT,
@@ -786,6 +794,9 @@ impl std::fmt::Display for Error {
Error::InvalidCdbLength { len, max } => {
write!(f, "E{}: {}/{}", self.code(), len, max)
}
Error::SelectionPidUnknown { pid } => {
write!(f, "E{}: 0x{:04x}", self.code(), pid)
}
_ => write!(f, "E{}", self.code()),
}
}