Skip to content

Progressive H.264 MP4 without CTTS judders on the native path #409

Description

@orut34iop

What happened?

On a progressive H.264 MP4 VOD with reordered pictures but no composition-time table, the native stream-copy path produces continuous forward/backward judder from the first frame. Seeking is not required to trigger it. The same source plays smoothly in another FFmpeg-based player.

The container presents every sampled video packet with PTS == DTS even though codecpar.video_delay == 1. A bounded libavcodec decode of the same head sample shows the contradiction directly: raw decoded AVFrame.pts regresses 16 times while best_effort_timestamp advances 58 times with zero regressions. Because the PTS values are present rather than AV_NOPTS_VALUE, the existing +genpts open flag and the #407 fallback do not repair them. Stream-copying those packet timestamps into fMP4 preserves decode order as presentation order, so AVPlayer displays future reference pictures before the B pictures that precede them.

Routing only this confirmed shape through the software decoder and scheduling decoded frames on best_effort_timestamp removes the judder.

Steps to reproduce

  1. Open a seekable MP4 containing progressive H.264 with B-frame reordering, but whose sample table has no ctts composition offsets.
  2. Play through the normal native VOD path.
  3. Observe continuous small forward/backward motion from playback start.
  4. Inspect the first 64 video packets and decoded frames. The reporting source produced: valid_pairs=64, PTS==DTS for all pairs, nonkey=62, decoded=59, best_effort_advances=58, best_effort_regressions=0, raw_pts_regressions=16.

A tiny 96x64 H.264 Main, 30000/1001 fps, 3-B-frame synthetic fixture and its healthy ctts twin are ready for a regression test in the accompanying PR.

AetherEngine version or commit SHA

6.39.0 / f70d4aee595f0947ef2354fbae01c76b41a7857b

Host app

Custom integration

Platform

tvOS

OS version

tvOS 26.6 beta (23L773)

Device / chip

Apple TV 4K (3rd generation)

Playback path

Native AVPlayer

Source media (for playback bugs)

MP4 / progressive H.264 with B-frame reordering / SDR. The source has no usable composition offsets: sampled packet PTS and DTS are equal despite video_delay=1. Audio is not involved in the failure. The synthetic regression fixture is MP4 / H.264 Main / 96x64 / 30000/1001 fps / no audio / SDR.

Error codes / log lines

No AVPlayer or VideoToolbox error is emitted. The diagnostic signature is:

video_packets=64 valid_pairs=64 nonkey=62 decoded_frames=59
best_advances=58 best_regressions=0 raw_regressions=16
raw_best_differences=16

Anything else

This is adjacent to #407 but not the same case. #407 repairs only AVFrame.pts == AV_NOPTS_VALUE; here the raw PTS is always present, but it is the wrong decode-order axis. A focused engine patch with bounded fail-closed detection, automatic per-session software routing, and good/bad MP4 fixtures is being prepared.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions