Expand description
§oxideav-h265
Pure-Rust H.265 / HEVC (ITU-T H.265 | ISO/IEC 23008-2) parser and decoder, for the oxideav framework.
Status: the decoder is end-to-end. decode_annexb_sequence /
SequenceDecoder decode whole Annex B byte streams to
output-order pictures, and make_decoder exposes the same driver
through the oxideav_core::Decoder registry contract (registered
by register under "h265" / "hevc", accepting Annex B and
hvcC / length-prefixed transport). Every Annex B bitstream in the
staged 16-fixture conformance corpus decodes byte-exact, plus
self-built pins for explicit weighted prediction, PCM, dependent
slice segments and per-slice loop-filter flags. make_encoder is
the PCM-only IDR encoder bootstrap (lossless, conformant, every
packet a random access point) over the write-side stack in
encoder (bit writer, NAL encapsulation, the §9.3.5 CABAC
encoding engine, parameter-set / slice writers). See README.md
for coverage and the remaining gaps (true multi-tile fixtures,
encoder beyond the PCM bootstrap).
The sections below record the per-round rebuild history of the subsystems the driver composes.
History: clean-room rebuild (post 2026-05-18 audit).
The latest round adds the §8.6.2 / §8.6.3 / §8.6.4 scaling,
transformation and residual-array construction step — the new
[transform] module. [transform::scale_coefficients] implements
the §8.6.3 dequantization (the levelScale / m[x][y] /
1 << (qP/6) product, bdShift offset-round and
[coeffMin, coeffMax] clip of equations 8-300..8-309);
[transform::inverse_transform] implements the §8.6.4 separable
inverse transform (the equation-8-316 4x4 DST-VII for MODE_INTRA
4x4 luma and the equations-8-318..8-321 32x32 DCT-II with the
equation-8-317 column subsampling for every other block, plus the
equation-8-314 intermediate offset-round); and
[transform::residual_block] orchestrates the §8.6.2 dispatch over
cu_transquant_bypass_flag (the equation-8-297 rotateCoeffs
pass-through), transform_skip_flag (the equation-8-298 tsShift
left-shift), and the full scale-then-transform path, applying the
equation-8-299 final bdShift offset-round.
Round 12 finishes the §7.3.2.1 VPS tail through the optional VPS
timing-info block ([vps::HevcVps] now carries max_layer_id,
num_layer_sets_minus1, the layer_id_included_flag[][]
inclusion matrix as [vps::LayerIdInclusionRow] rows, the
vps_timing_info_present_flag block as [vps::VpsTimingInfo] —
u(32) num_units_in_tick / time_scale,
poc_proportional_to_timing_flag +
num_ticks_poc_diff_one_minus1, and num_hrd_parameters — plus
vps_extension_flag); per-HRD hrd_parameters() bodies and the
extension-data payload are surfaced as
[vps::HevcVps::opaque_tail].
Round 11 landed the §9.3 CABAC arithmetic decoding engine
([cabac::CabacEngine] / [cabac::ContextModel] / [cabac::init_type]):
the §9.3.2.6 engine-register init, the §9.3.2.2 context-variable init
(equations 9-4..9-7), the §9.3.4.3.2 DecodeDecision primitive (with
the Table 9-52 / Table 9-53 LPS-range / state-transition tables), the
§9.3.4.3.3 RenormD loop, the §9.3.4.3.4 DecodeBypass primitive (with
an MSB-first decode_bypass_bits(n) helper), the §9.3.4.3.5
DecodeTerminate primitive, and the §9.3.4.3.6 aligned-bypass
alignment hook. The engine ships standalone — independent of the
§9.3.4.2 per-syntax-element binarization / context-index derivation
that the slice-data parser still needs.
Rounds 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 land the Annex B NAL-unit
byte-stream walker, the §7.3.1.2 NAL header parse, the §7.3.2.1
VPS structural parse (with a §7.3.3 profile_tier_level walk), the
full §7.3.2.2 SPS parse (through the vui_parameters_present_flag
/ sps_extension_present_flag gates, with the VUI body and any
extension payload surfaced as an opaque-bytes tail), the
§7.3.2.3.1 PPS parse (full general body through
pps_extension_present_flag, including the tiles and
deblocking-control blocks; the PPS extension bodies are surfaced as
an opaque tail), the §7.3.6.1 slice-segment-header parse —
independent I-slice IDR segments end to end (round 6), and
independent non-IDR I-slice segments through the §7.3.6.1 POC +
short-term-RPS + long-term-RPS block end to end (round 7) — and
now (round 8) the §7.3.4 scaling_list_data() parse with the
§7.4.5 ScalingList[sizeId][matrixId][i] derivation, wired into
both the SPS (sps_scaling_list_data_present_flag) and PPS
(pps_scaling_list_data_present_flag) paths. The P/B
reference-list / weighted-prediction sub-structures are still
surfaced as an opaque tail.
§What works today
- Annex B byte-stream splitting (3- and 4-byte start codes, trailing-zero padding tolerance).
- §7.3.1.2 NAL header parse:
forbidden_zero_bit,nal_unit_type,nuh_layer_id, andTemporalId(derived fromnuh_temporal_id_plus1). - §7.4.1.1 emulation-prevention byte strip (
0x00 0x00 0x03→0x00 0x00). - MSB-first bit reader with
u(n)and 0-th-order unsigned-Exp-Golombue(v)(§9.2) descriptors. - §7.3.2.1 [
vps::HevcVps] — vps_id, base-layer / max-layers / sub-layers / temporal-nesting flags, reserved-0xFFFF validation, the §7.3.3 profile_tier_level walk (general profile + level + per-sub-layer present-flag gates andsub_layer_level_idc), and the per-sub-layer DPB / reorder / latency triple loop. - §7.3.2.2 [
sps::SeqParameterSet] — vps-id back-reference, max-sub-layers / nesting flag, the §7.3.3 PTL re-walk,chroma_format_idc/separate_colour_plane_flag,pic_width_in_luma_samples/pic_height_in_luma_samples, conformance-window quad,bit_depth_{luma,chroma}_minus8,log2_max_pic_order_cnt_lsb_minus4, the per-sub-layer DPB / reorder / latency triple loop, the fourlog2_*_block_size{_minus_2,_minus_3,_diff_max_min}fields,max_transform_hierarchy_depth_{inter,intra},scaling_list_enabled_flag(with the nestedsps_scaling_list_data_present_flag/ [scaling_list::ScalingListData] §7.3.4 block),amp_enabled_flag,sample_adaptive_offset_enabled_flag, the [sps::PcmInfo] block gated bypcm_enabled_flag, thenum_short_term_ref_pic_setsue(v) + per-set [sps::ShortTermRefPicSet] (§7.3.7, both explicit and inter-RPS-prediction forms), thelong_term_ref_pics_present_flagblock plus [sps::LongTermRefPicEntry] table, thesps_temporal_mvp_enabled_flag/strong_intra_smoothing_enabled_flagpair, thevui_parameters_present_flaggate whose §E.2.1vui_parameters()body is decoded into [vui::VuiParameters] (aspect-ratio / EXTENDED_SAR, overscan, video-signal-type + colour-description, chroma-loc, default-display-window, thevui_timing_infoblock —u(32)num_units_in_tick / time_scale plus the nested §E.2.3hrd_parameters()call — and bitstream-restriction), and thesps_extension_present_flaggate whose extension body is surfaced as [sps::OpaqueTail]. The §7.3.4scaling_list_data()block — whensps_scaling_list_data_present_flag == 1— is parsed and the §7.4.5ScalingList[sizeId][matrixId][i]coefficient arrays are derived (default tables + prediction inference); see [scaling_list::ScalingListData]. - §6.5 [
scan] — all four scan-order initialization processes plus the §7.4.2 [scan::scan_order]ScanOrder[log2BlockSize][scanIdx]accessor: [scan::up_right_diagonal] (§6.5.3, equation 6-11), [scan::horizontal] (§6.5.4, equation 6-12), [scan::vertical] (§6.5.5, equation 6-13), and [scan::traverse] (§6.5.6, equation 6-14, the boustrophedon raster). [scan::scan_order] enforces §7.4.2’s populated ranges (log2BlockSize0..=3 for diagonal / horizontal / vertical, 2..=5 for traverse). §7.4.5 [scaling_list::ScalingListData::scaling_factors] expands the flat scaling lists into the two-dimensionalScalingFactor[sizeId][matrixId][x][y]quantization matrices (equations 7-44..7-51: the diagonal scatter, the 2x / 4x block replication, the DC[0][0]override, and theChromaArrayType == 332x32-chroma derivation). - §7.3.2.3.1 [
pps::PicParameterSet] — the full generalpic_parameter_set_rbsp()body: thepps_*_idpair, the slice-header gates,init_qp_minus26(se(v)), the chroma QP offsets, the tiles block ([pps::TileInfo] — column/row counts plus the explicitcolumn_width_minus1[]/row_height_minus1[]arrays whenuniform_spacing_flag == 0), the deblocking-filter-control block ([pps::DeblockingFilterControl]),lists_modification_present_flag,log2_parallel_merge_level_minus2, and thepps_extension_present_flaggate. Whenpps_extension_present_flag == 1the eight bits of typed extension flags are decoded into [pps::PpsExtensionFlags] (pps_range_extension_flag,pps_multilayer_extension_flag,pps_3d_extension_flag,pps_scc_extension_flag, and the reservedpps_extension_4bits); any extension body whose flag is set is surfaced as a shared [sps::OpaqueTail] starting at the first body’s bit position. Whenpps_scaling_list_data_present_flag == 1the §7.3.4scaling_list_data()block is parsed into [scaling_list::ScalingListData]. The §7.4.3.3.1 inference rules are applied so absent conditional fields carry their effective value. - §7.3.6.1 [
slice::SliceSegmentHeader] — theslice_segment_header()parse for an independent slice segment, taking the activated SPS + PPS as context (theslice_segment_addressandslice_pic_order_cnt_lsbwidths plus the SAO / MVP / tiles gates are SPS/PPS-derived). Independent I-slice segments — both IDR and non-IDR — parse end to end throughbyte_alignment(), including the §7.3.6.1 non-IDR POC (slice_pic_order_cnt_lsb) + short-term-RPS (short_term_ref_pic_set_sps_flag/ in-linest_ref_pic_set(num_short_term_ref_pic_sets)via [sps::ShortTermRefPicSet::parse_slice_inline] /short_term_ref_pic_set_idx) + long-term-RPS block (per-entry SPS-indexed vs in-slice +delta_poc_msb_present_flag/delta_poc_msb_cycle_lt, surfaced as [slice::SliceLongTermRefPic]). The P/B reference-list / weighted-prediction sub-structures are still surfaced as an [sps::OpaqueTail]. The §7.4.7.1 inference rules are applied to absent fields. - §7.3.6.2 [
slice::RefPicListsModification] — theref_pic_lists_modification()syntax structure as a standalone parser. The parser walks theref_pic_list_modification_flag_lXu(1)gates and thelist_entry_lX[]u(v)loops (each entryCeil( Log2( NumPicTotalCurr ) )bits wide and range-checked per §7.4.7.2); the implicitRefPicListTempXderivation of §8.3.4 stays the consumer’s responsibility. - §7.4.7.2 [
slice::NumPicTotalCurrInputs] — theNumPicTotalCurrderivation (equation 7-57) as a small typed builder taking the per-positionUsedByCurrPicS0/UsedByCurrPicS1/UsedByCurrPicLtflags from the active short-term RPS + the slice’s long-term ref list and thepps_curr_pic_ref_enabled_flagclosing-clause flag, returning the typedNumPicTotalCurr: u32. A [slice::NumPicTotalCurrInputs::from_explicit_short_term_rps] convenience constructor sourcesS0/S1straight off an explicit-form [sps::ShortTermRefPicSet]; the inter-RPS-prediction form needs the §7.4.8 derivation to run first. [slice::SliceLongTermRefPic::used_by_curr_pic_lt] resolves each long-term entry’sUsedByCurrPicLt[i]per §7.4.7.1 (SPS-table lookup for SPS-resident entries, direct flag for in-slice entries). The F.7.4.7.2 multilayer-extension form (equation F-56) is reachable through [slice::NumPicTotalCurrInputs::with_multilayer_extension]. - §7.3.6.3 [
slice::PredWeightTable] — thepred_weight_table()syntax structure as a standalone parser. The parser walks theluma_log2_weight_denom/delta_chroma_log2_weight_denomdenominators, the two flag passes (luma_weight_lX_flag[i]+chroma_weight_lX_flag[i]), and the per-reference delta block (delta_luma_weight_lX[i]/luma_offset_lX[i]/delta_chroma_weight_lX[i][j]/delta_chroma_offset_lX[i][j]), applying the §7.4.7.3 range bounds + the per-i §7.3.6.3 outer-gate (pic_layer_id != nuh_layer_id || PicOrderCnt(RefPicListX[i]) != PicOrderCnt(CurrPic)) decision supplied by the caller, theChromaLog2WeightDenom ∈ 0..=7derived range, and thesumWeightLXFlags ≤ 24conformance cap. [slice::PredWeightTable::luma_weight_l0] / [slice::PredWeightTable::chroma_weight_l0] (mirrored for L1) resolve each derivedLumaWeightLX[i]/ChromaWeightLX[i][j]; [slice::PredWeightTable::chroma_offset_l0] (mirrored) applies equation 7-58 forChromaOffsetLX[i][j].
See nal for the byte-stream walker entry points, [vps] for
the parsed VPS structure, [sps] for the parsed SPS, [pps]
for the parsed PPS, and [crate::slice] for the parsed slice
header.
Re-exports§
pub use decoder::make_decoder;pub use decoder::H265Decoder;pub use encoder::make_encoder;pub use encoder::H265Encoder;pub use encoder::H265PcmEncoder;pub use hvcc::extradata_is_hvcc;pub use hvcc::nal_unit_from_coded;pub use hvcc::parse_hvcc;pub use hvcc::split_length_prefixed;pub use hvcc::HvccError;pub use hvcc::HvccRecord;pub use nal::collect_nal_units;pub use nal::NalError;pub use nal::NalHeader;pub use nal::NalIter;pub use nal::NalUnit;pub use picture::clip1;pub use picture::sub_wh_c;pub use picture::Picture;pub use picture::Plane;pub use sequence::decode_annexb_sequence;pub use sequence::DecodedFrame;pub use sequence::SequenceDecoder;pub use sequence::SequenceError;
Modules§
- decoder
- Registry decoder — the
oxideav_core::Decodercontract over the whole-bitstreamcrate::sequencedriver. - encoder
- H.265 / HEVC encoder — write-side building blocks.
- hvcc
HEVCDecoderConfigurationRecord(hvcC) extradata parse.- nal
- H.265 / HEVC NAL-unit byte-stream walker.
- picture
- Decoded-picture sample storage — the §8 reconstruction target.
- sequence
- Whole-bitstream decode driver — Annex B byte stream to output pictures.
Enums§
- Error
- Crate-local error type for the structural utilities (the NAL
walker and parameter-set parsers surface their own
NalError/VpsErrortypes directly; the decode drivers usesequence::SequenceErrorand the registry decoder maps intooxideav_core::Error). - HrdError
- Errors that can arise while parsing an
hrd_parameters()body. - PpsError
- Errors that can arise while parsing a PPS RBSP.
- Recon
Error - Errors raised while reconstructing samples from a decoded CTU.
- Short
Term RefPic SetMaterialize Error - Errors that can arise while running the §7.4.8 inter-RPS-prediction
derivation via [
ShortTermRefPicSet::materialize]. - Slice
Error - Errors that can arise while parsing a slice segment header.
- SpsError
- Errors that can arise while parsing an SPS RBSP.
- VpsError
- Errors that can arise while parsing a VPS RBSP.
- VuiError
- Errors that can arise while parsing a
vui_parameters()body.
Functions§
- register
- Codec registration: the software H.265 / HEVC decoder under the
"h265"id (aliased"hevc"), claiming the common container tags (hvc1/hev1sample entries, the MP4 ObjectTypeIndication for HEVC, and theHEVCFourCC).