Skip to content

fix(demux): repair variable-cadence H264 heads and hierarchical partial offsets - #761

Open
orut34iop wants to merge 1 commit into
superuser404notfound:mainfrom
orut34iop:codex/fix-h264-missing-head-cadence
Open

orut34iop wants to merge 1 commit into
superuser404notfound:mainfrom
orut34iop:codex/fix-h264-missing-head-cadence

Conversation

@orut34iop

Copy link
Copy Markdown
Contributor

Summary

Fix persistent judder in two H.264 MP4 shapes still refused by the existing composition-offset repair: a missing-offset head whose DTS cadence changes, and a healthy head followed by zero-offset regions with a hierarchical anchor three pictures ahead despite video_delay == 2. Reuse the existing original-slot ladder and bounded prefix evidence; do not synthesize an average-FPS clock.

Related: #409, #513, #700, #707. The #513 streaming repair is already present; #700 establishes complete-prefix evidence in the whole-file classifier, but the partial-region ladder still uses a symmetric forward/backward delay. #707 addresses a separate open-GOP seek boundary. This change extends those mechanisms rather than replacing them.

What changed

  • A nonuniform H.264 head can enter the existing slot session only after progressive IDR, equal PTS/DTS, exact container start/index lead, unique complete-prefix and slot/lead checks succeed. The uniform H.264/HEVC classifier and HEVC open-GOP seek behavior remain intact.
  • In a later zero-offset IDR sequence, an anchor beyond the old forward allowance waits for bounded numeric evidence. A complete prefix proves the measured forward distance; backward displacement must still fit the declared delay. This proof resets at each candidate IDR. The ordinary mini-GOP path is unchanged.
  • Preserve original DTS, audio, payload, side data, container order and the published index. Keep the existing 64-picture evidence, 16-picture forward, 1024-packet and 32-MiB hold bounds; unsupported/incomplete sequences hand back pending packets unchanged. Numeric refusal/proof logs are limited to the first eight occurrences per session.
  • Extend the existing CI control script with generated malformed/healthy twins, an exact healthy-PTS oracle for partial regions, policy rejection tests and the existing seek/EOF/packet-balance lifecycle checks. Update format documentation and changelog. No public API or dependency change.

Test plan

Reproduce with FFmpeg/libx264, Python 3 and Ruby:

bash Scripts/test-h264-partial-composition-controls.sh

The script compiles the real timestamp sessions and parser against the revision pinned in Package.resolved, then compares independent raw/repaired software decoder output. All fixtures are generated patterns and tones; no private media, URLs, logs or screenshots are included.

  • Public fixture format: MP4, H.264 High, 96×64, 8-bit yuv420p, AAC-LC mono 48 kHz; SDR, no Dolby Vision. Missing-head twin changes from 25-fps spacing to 30000/1001 spacing. Hierarchical twins use 25 fps, B3 and closed 49-picture GOPs, with only ctts offsets removed at IDR boundaries.
  • Missing head, seeks 0 / 1.5 / 0 / 20 / 40: original decoded-time regressions 400 / 400 / 400 / 320 / 120 become all zero, with zero abandoned sequences.
  • Hierarchical missing tail, seeks 0 / 12 / 0 / 6 / 22: 198 / 149 / 198 / 198 / 29 become all zero. Every output video PTS equals the healthy twin's PTS at that DTS. The missing-middle twin also matches exactly and resumes unchanged healthy delivery.
  • Existing partial-tail, middle and long-GOP controls, both new healthy twins, insufficient/ambiguous lead, duplicate/gapped/out-of-range ranks, missing/nonincreasing DTS, overflow, seek cleanup, fail-open delivery and interleaved packet ceiling pass. Audio and packet data stay identical; packet balance is zero.
  • Downstream physical acceptance: the same repair logic was installed on an Apple TV running tvOS 27.2. The reporter confirmed both affected H.264 MP4s and a previously healthy control play normally, including A/V sync and seeking. Numeric device evidence for the second case was rank=4, decode_index=1, samples=12, reorder_depth=2, forward_depth=3. Private source files are not redistributed. This acceptance applies to the downstream candidate; this upstream port is separately checked by the local tests above and CI.
  • Local Swift 6.4 package build (including test targets) passes. On this exact port: 42 Swift Testing cases covering H.264, HEVC and first-seek/open-GOP repair, plus 21 XCTest documentation/API/constant checks, pass. The standalone controls pass 32 playback/seek comparisons and six lifecycle groups. Local host executables were linked without implicit ad-hoc signing and signed with the existing Apple Development identity before execution. No full unrelated suite or fresh upstream-port device installation is claimed.
  • Relative documentation links and patch whitespace checks pass. GitHub CI will run after submission; its result is separate from the physical acceptance above.

Limit: these fixtures demonstrate timestamp order and, for partial regions, exact recovery from a healthy twin. They do not establish recovery of arbitrary lost timestamps, unsupported non-IDR damage, interlaced/open-GOP shapes, or physical synchronization for every source.

Checklist

  • CHANGELOG.md updated
  • Commit messages follow Conventional Commits
  • The fix lives in the engine, not in a host-side workaround
  • Public API unchanged; behavior and limits documented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant