Harden 3D MVC mux: robustness + tests (audit round 1)

Triage of a 10-lens code audit of the 3D branch. Fixes for real defects;
rejected three spec false-positives that matched the ISO/IEC 14496-15
§7.6.2 record verbatim.

Robustness / correctness:
- Never panic when a title's only video is the MVC dependent view: the
  base is now the first NON-dependent video, so a dependent-only title
  sets up no merge (muxed as an ordinary track) instead of hitting an
  `expect` on the skipped track slot.
- Drop a per-frame BlockAdditional (BlockAddID=2) when the track declared
  no mvcC mapping (dependent params not captured before the header) — a
  plain block keeps the file conforming instead of an orphaned add.
- A non-keyframe MVC base frame always carries a ReferenceBlock (fall back
  to a 0 offset in the pre-first-keyframe corner) so it is never mistaken
  for a seek point.
- Reference the last keyframe on the PRIMARY video track only, so a
  secondary video track's keyframe can't become a cross-track reference.
- dep_by_pts overflow: bound BEFORE inserting so the just-arrived
  dependent survives the drift-clear; count a displaced duplicate-PTS
  dependent as an orphan instead of losing it silently.

API / docs:
- Fold write_frame_with_additional into write_frame(..., Option<&[u8]>)
  per the "no foo_with_X" convention.
- Fix mvc_params doc (StereoMode is intentionally not emitted); remove a
  stale PAT/PMT comment describing an approach that was never taken.

Tests: MVCDecoderConfigurationRecord over-length guards; write_int minimal
two's-complement widths; BlockGroup/BlockAdditions/BlockAdditional +
ReferenceBlock emission; additional dropped without a mapping; h264 MVC
passthrough keeps param sets in-band; extract_mvc_params no-panic on
truncated/empty input; pairing window + dep-overflow edges; no-panic on a
dependent-only title.
This commit is contained in:
Matthew Jackson
2026-07-13 11:24:23 -07:00
parent fd6dfbe5b0
commit d4021114cd
5 changed files with 356 additions and 108 deletions
-7
View File
@@ -250,13 +250,6 @@ impl Disc {
})
.collect();
// 3D: the base STN table lists only the left-eye video. The right-eye
// MVC substream is a SECOND video PID (stream_type 0x20) in the SSIF.
// Read the SSIF head — the PAT/PMT sit in the clear, so no key is needed
// — and add any video PID the STN table didn't already list. This reuses
// the same PAT/PMT scanner the m2ts:// path uses; 0x20 now resolves to
// H.264 video (see `Codec::from_coding_type`), so the dependent view is
// enumerated instead of dropped.
// 3D: add the MVC dependent (right-eye) video stream. The base STN table
// lists only the left-eye video; the dependent view is a second video
// PID (stream_type 0x20) carried in the SSIF. The on-disc PAT/PMT are