Skip to content

Decode High 10 (and other bit depths up to 14) with a 16-bit pipeline - #23

Open
rickeyski wants to merge 2 commits into
Remade-With-Rust:mainfrom
rickeyski:rwr/RWR-009-high10
Open

rickeyski wants to merge 2 commits into
Remade-With-Rust:mainfrom
rickeyski:rwr/RWR-009-high10

Conversation

@rickeyski

Copy link
Copy Markdown

This stacks on #22.

A separate decoder, hbd::HbdDecoder, next to the optimized 8-bit one so the 8-bit
byte-identity gates are untouched. It follows FFmpeg's h264 decoder (neighbour caches,
motion vector prediction, direct modes, reference lists, POC) and is bit-exact with it.

Scope: progressive 4:2:0, bit depths 8-14, CAVLC and CABAC, I/P/B, 8x8 transform,
scaling matrices, explicit and implicit weighted prediction, spatial and temporal direct,
long-term references and MMCO. Interlace, 4:2:2/4:4:4, lossless and SP/SI are refused;
like the 8-bit decoder, it decodes the frame pictures of a stream that permits field
coding and refuses field pictures. A broken internal invariant is
DecodeError::Internal, not a panic.

The SPS now keeps the bit depths and the POC type 1 cycle; the 8-bit Decoder refuses
bit depths other than 8 at the slice instead of the SPS. The crop window is computed
with checked u64 arithmetic (Sps::crop_window), since offsets near u32::MAX used to
wrap past the bounds check with overflow checks off.

Tests: three x264 High 10 streams (64x48, 8 frames, ffmpeg 8.1's decodes as the
yuv420p10le references) covering CABAC B-pyramid with explicit and implicit
weighted prediction, CAVLC with spatial and temporal direct and PPS scaling matrices,
and two slices per picture; every picture is byte-identical.

Rickey Visinski and others added 2 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 Remade-With-Rust#16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A separate decoder, `hbd::HbdDecoder`, next to the optimized 8-bit one so the 8-bit
byte-identity gates are untouched. It follows FFmpeg's h264 decoder (neighbour caches,
motion vector prediction, direct modes, reference lists, POC) and is bit-exact with it.

Scope: progressive 4:2:0, bit depths 8-14, CAVLC and CABAC, I/P/B, 8x8 transform,
scaling matrices, explicit and implicit weighted prediction, spatial and temporal direct,
long-term references and MMCO. Interlace, 4:2:2/4:4:4, lossless and SP/SI are refused;
like the 8-bit decoder, it decodes the frame pictures of a stream that permits field
coding and refuses field pictures. A broken internal invariant is
`DecodeError::Internal`, not a panic.

The SPS now keeps the bit depths and the POC type 1 cycle; the 8-bit Decoder refuses
bit depths other than 8 at the slice instead of the SPS. The crop window is computed
with checked u64 arithmetic (`Sps::crop_window`), since offsets near u32::MAX used to
wrap past the bounds check with overflow checks off.

Tests: three x264 High 10 streams (64x48, 8 frames, ffmpeg 8.1's decodes as the
`yuv420p10le` references) covering CABAC B-pyramid with explicit and implicit
weighted prediction, CAVLC with spatial and temporal direct and PPS scaling matrices,
and two slices per picture; every picture is byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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