Skip to content

Fix #13: use picture frame rate for field-coded interlaced sources#44

Merged
StuartCameronCode merged 1 commit into
mainfrom
fix/issue-13-field-coded-framerate
Jun 30, 2026
Merged

Fix #13: use picture frame rate for field-coded interlaced sources#44
StuartCameronCode merged 1 commit into
mainfrom
fix/issue-13-field-coded-framerate

Conversation

@StuartCameronCode

Copy link
Copy Markdown
Owner

Problem

Issue #13: a DVB-T2 PAL rip deinterlaces to 100fps instead of 50fps.

The source is 25fps interlaced H.264 stored as "separated fields" (field-coded). ffprobe reports its r_frame_rate as the field rate (50/1), while avg_frame_rate carries the true picture rate (25/1) — a well-known ffprobe quirk for field-coded streams. VapourBox read r_frame_rate everywhere, so it treated the source as 50p:

  • the deinterlace panel showed the source as 50i, and
  • because the pipe-source template forces the VapourSynth clip to the detected fps (fps_num={{INPUT_FPS_NUM}}), QTGMC double-rate targeted 100fps, with a doubled, desynced frame count.

The owner's own files aren't affected because they're frame-coded (r_frame_rate = avg_frame_rate = 25).

Fix

Add FieldOrderDetector.selectFrameRate(r, avg): when r is ~2× avg (the field-coded signature, ratio 1.8–2.2) trust avg; otherwise keep r so true 50p progressive and frame-coded 25i are untouched — no regression to working workflows. Wired into getVideoInfo (fixes display, inputFrameRate→clip fps, and frameCount) and the preview generator's probe (seek accuracy).

Tests

  • 6 unit tests for selectFrameRate (PAL/NTSC field-coded, true 50p, frame-coded 25i, null fallbacks).
  • A real-clip test on the issue's DVB-T2 sample — added as Tests/TestResources/pal-dvbt-fieldcoded-25i.ts, trimmed with stream copy to preserve the field-coded bitstream — asserting getVideoInfo resolves to 25fps, interlaced, TFF.

🤖 Generated with Claude Code

DVB-T PAL rips stored as "separated fields" (field-coded H.264) report
ffprobe r_frame_rate as the *field* rate (50 for 25fps PAL, 59.94 for
29.97fps NTSC), while avg_frame_rate carries the true picture rate.
VapourBox read r_frame_rate everywhere, so it treated the source as 50p:
the deinterlace panel showed 50i and — because the pipe-source template
forces the clip to the detected fps — QTGMC double-rate targeted 100fps
with a doubled, desynced frame count.

Add FieldOrderDetector.selectFrameRate(r, avg): when r is ~2x avg (the
field-coded signature, ratio 1.8-2.2) trust avg, otherwise keep r so CFR
progressive and frame-coded interlaced are unaffected. Wire it into
getVideoInfo and the preview generator's probe.

Tests:
- 6 unit tests for selectFrameRate (PAL/NTSC field-coded, 50p, 25i, null).
- A real-clip test on the issue's DVB-T2 sample (trimmed, stream-copied
  to preserve the field-coded bitstream) asserting 25fps, interlaced, TFF.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@StuartCameronCode StuartCameronCode merged commit 0ec03e1 into main Jun 30, 2026
4 checks passed
@StuartCameronCode StuartCameronCode deleted the fix/issue-13-field-coded-framerate branch June 30, 2026 14:21
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