Skip to content

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

Closed

Description

@rickeyski

Summary

The SPS parser refuses every stream whose frame_mbs_only_flag is 0
(params.rs#L249-L251).
That flag only says field coding is permitted. x264's --fake-interlaced (required for
Blu-ray-compliant 1080p25/1080p30) sets it while coding every picture as a progressive frame
(field_pic_flag = 0, mb_adaptive_frame_field_flag = 0). Those streams need no interlace
tools at all, but are rejected at the first SPS.

Steps to reproduce

ffmpeg -f lavfi -i testsrc2=size=1280x720:rate=24 -t 2 -c:v libx264 -preset veryfast -pix_fmt yuv420p \
       -x264-params fake-interlaced=1:pic-struct=1 -f h264 fake_interlaced.h264
ffprobe -v error -show_entries stream=profile,pix_fmt,field_order -of csv=p=0 fake_interlaced.h264
# High,yuv420p,progressive

Feed the stream to rusty_h264::Decoder::decode one access unit at a time.

Expected

Decodes like the same content without fake-interlaced.

Actual

access unit 0: unsupported coding tool: interlace / field coding  (0 frames decoded before it)

(A control encode without fake-interlaced decodes all 30 frames.)

Suggested fix

When frame_mbs_only_flag == 0:

  1. In the SPS, read mb_adaptive_frame_field_flag instead of refusing.
  2. In each slice header, read field_pic_flag (and bottom_field_flag when set), keeping the
    header parse in sync.
  3. Refuse only when a picture actually uses field tools: field_pic_flag == 1, or
    mb_adaptive_frame_field_flag == 1 (MBAFF; needs full support, tracked separately).
  4. Frame-picture POC derivation is unchanged (delta_pic_order_cnt_bottom is already read
    when bottom_field_pic_order_in_frame_present_flag is set).

Activity

  1. added a commit that references this issue on Oct 28, 2026
  2. Ttimmahlax commented on Oct 28, 2026

    @Ttimmahlax
    Collaborator

    Fixed in rusty_h264 0.17.0 (with rusty_h264-decoder 0.17.0 etc.), now on crates.io.

    Following your suggested fix: when frame_mbs_only_flag == 0, the SPS now reads mb_adaptive_frame_field_flag and refuses only MBAFF. Height is counted in field map units, and CropUnitY is 4. Each slice header reads field_pic_flag and refuses only actual field pictures. Frame pictures (x264 fake-interlaced) decode normally. Credit to @rickeyski (#22, landed via #26).

    Verified against ffmpeg -f rawvideo, on the published 0.17.0 crate:

    Real interlace tools are still refused cleanly with Unsupported, with no panic:

    • MBAFF (x264 interlaced=1; JVT CAMA1_Sony_C, CVMA1_TOSHIBA_B, CAPAMA3_Sand_F): refused with … (MBAFF)
    • Field pictures (JVT CVFI1_Sony_D) and PAFF (CVPA1_TOSHIBA_B): refused with … (field picture)

    Full MBAFF / field decoding is still out of scope.

    🤖 Generated with Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions