Skip to content

Decode frame pictures of streams that permit field coding (#16) - #26

Merged
Ttimmahlax merged 3 commits into
mainfrom
fix/16-fake-interlaced
Oct 28, 2026
Merged

Ttimmahlax merged 3 commits into
mainfrom
fix/16-fake-interlaced

Conversation

@Ttimmahlax

Copy link
Copy Markdown
Collaborator

Carries @rickeyski's fix from #22 unchanged (commit 7da3ea0, authorship kept), plus one commit adding a field-picture refusal vector. Opened from this repo's branch because CI for fork PRs needs approval and the extra test had to ride along; #22 will be closed in favour of this with thanks. (#23, the High 10 work that stacks on #22, is untouched.)

Fixes #16.

The fix (from #22)

frame_mbs_only_flag == 0 only permits field coding. The SPS now reads mb_adaptive_frame_field_flag and refuses only MBAFF. Height is counted in map units (FrameHeightInMbs = 2 × PicHeightInMapUnits), and CropUnitY becomes 4. Both slice-header parsers (lib.rs and the frame-MT POC peek in frame_mt.rs; I grepped, there are no others) read field_pic_flag and refuse field pictures. Frame pictures decode as before.

Added here

field_pic.264 is the PR's fake_interlaced.264 with field_pic_flag set in the first IDR slice (one bit). field_picture_is_refused requires Unsupported("… (field picture)") from decode_stream and from per-AU decode, and that no later AU produces a frame.

Evidence: CLI decode vs ffmpeg -f rawvideo

stream main this PR
issue cmd: 720p24 fake-interlaced=1:pic-struct=1 veryfast (B-frames) refused at SPS 0/48 differ
control (same, no fake-interlaced) 0/48 0/48
1080p25 fake-interlaced, medium (coded 1088, crop via CropUnitY=4) refused 0/50
x264 interlaced=1 (MBAFF) refused refused: … (MBAFF)
JVT CAMA1_Sony_C, CVMA1_TOSHIBA_B, CAPAMA3_Sand_F (MBAFF) refused refused: … (MBAFF)
JVT CVFI1_Sony_D (all field pictures) refused refused: … (field picture)
JVT CVPA1_TOSHIBA_B (PAFF: field + frame pictures) refused decode_stream: refused … (field picture)

No panics on any of them, serial or RS_H264_FRAME_THREADS=4. Per-AU Decoder::decode on CVPA1: every field AU errors, and the P/B frame pictures that depend on them error too ("inter without reference" / "B without references" / "bitstream truncated"). The only frame produced is AU 46, a non-IDR I frame picture, which has no dependencies. No garbage frames are emitted.

A fake-interlaced stream with no-deblock=1 still shows the #15 bottom-row bug on this branch alone (49/50 frames differ). That is fixed by #25 and is re-checked after both merge.

🤖 Generated with Claude Code

Rickey Visinski and others added 3 commits October 18, 2026 10:34
frame_mbs_only_flag == 0 only permits field coding. x264's fake-interlaced (needed for
Blu-ray 1080p25/30) sets it while coding every picture as a progressive frame, and
those streams were refused at the SPS.

Now the SPS reads mb_adaptive_frame_field_flag and refuses only MBAFF; the height is
counted in field map units (FrameHeightInMbs = 2 * PicHeightInMapUnits) and the
vertical crop unit is 4. Slice headers read field_pic_flag and refuse only field
pictures. Everything else about a frame picture decodes as before.

Fixes #16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fake_interlaced.rs covered the decode path and the MBAFF refusal at the
SPS; the other half of the change, the per-slice field_pic_flag refusal,
had no vector. field_pic.264 is fake_interlaced.264 with field_pic_flag
set in the first IDR slice header (one bit, NAL bit 21). The test requires
Unsupported("... (field picture)") from decode_stream and from per-AU
decode, and that no later AU then yields a frame.

Real field-coded streams were also checked by hand against this branch
(JVT conformance CVFI1_Sony_D, all field pictures; CVPA1_TOSHIBA_B, PAFF;
CAMA1_Sony_C / CVMA1_TOSHIBA_B / CAPAMA3_Sand_F and x264 interlaced=1,
MBAFF): every one is refused with an Unsupported error, no panic, serial
and RS_H264_FRAME_THREADS=4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Ttimmahlax
Ttimmahlax merged commit db44f70 into main Oct 28, 2026
21 checks passed
@Ttimmahlax
Ttimmahlax deleted the fix/16-fake-interlaced branch October 28, 2026 22:38
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.

rusty_h264 rejects progressive streams that set frame_mbs_only_flag = 0 (x264 fake-interlaced)

2 participants