#![allow(
clippy::redundant_pub_crate,
reason = "workspace `unreachable_pub` policy (Cargo.toml) wants `pub(crate)` here; \
clippy::pedantic's redundant_pub_crate disagrees for private modules — the \
two lints are mutually exclusive for this shape, workspace policy wins"
)]
use vulkanalia::vk::video as native;
#[derive(Debug, Clone, Copy)]
pub(crate) struct CtuAlignedExtent {
pub(crate) width: u32,
pub(crate) height: u32,
}
impl CtuAlignedExtent {
pub(crate) const fn from_pixels(width: u32, height: u32) -> Option<Self> {
if width == 0 || height == 0 || width % 8 != 0 || height % 8 != 0 {
return None;
}
Some(Self { width, height })
}
}
const PROFILE_IDC_MAIN: native::StdVideoH265ProfileIdc = native::STD_VIDEO_H265_PROFILE_IDC_MAIN;
const LEVEL_IDC_1_0: native::StdVideoH265LevelIdc = native::STD_VIDEO_H265_LEVEL_IDC_1_0;
const CB_MIN_LOG2_MINUS3: u8 = 0; const CB_DIFF_LOG2: u8 = 2; const TB_MIN_LOG2_MINUS2: u8 = 0; const TB_DIFF_LOG2: u8 = 3; const TRANSFORM_HIERARCHY_DEPTH: u8 = 3;
pub(crate) fn profile_tier_level_main() -> native::StdVideoH265ProfileTierLevel {
let mut flags = native::StdVideoH265ProfileTierLevelFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 1]),
__bindgen_padding_0: [0; 3],
};
flags.set_general_progressive_source_flag(1);
flags.set_general_frame_only_constraint_flag(1);
native::StdVideoH265ProfileTierLevel {
flags,
general_profile_idc: PROFILE_IDC_MAIN,
general_level_idc: LEVEL_IDC_1_0,
}
}
pub(crate) const fn dec_pic_buf_mgr_no_refs() -> native::StdVideoH265DecPicBufMgr {
native::StdVideoH265DecPicBufMgr {
max_latency_increase_plus1: [0; 7],
max_dec_pic_buffering_minus1: [0; 7],
max_num_reorder_pics: [0; 7],
}
}
pub(crate) fn build_vps(
profile_tier_level: &native::StdVideoH265ProfileTierLevel,
dec_pic_buf_mgr: &native::StdVideoH265DecPicBufMgr,
) -> native::StdVideoH265VideoParameterSet {
let mut flags = native::StdVideoH265VpsFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 1]),
__bindgen_padding_0: [0; 3],
};
flags.set_vps_temporal_id_nesting_flag(1);
native::StdVideoH265VideoParameterSet {
flags,
vps_video_parameter_set_id: 0,
vps_max_sub_layers_minus1: 0,
reserved1: 0,
reserved2: 0,
vps_num_units_in_tick: 0,
vps_time_scale: 0,
vps_num_ticks_poc_diff_one_minus1: 0,
reserved3: 0,
pDecPicBufMgr: dec_pic_buf_mgr,
pHrdParameters: std::ptr::null(),
pProfileTierLevel: profile_tier_level,
}
}
pub(crate) const fn build_sps(
extent: CtuAlignedExtent,
profile_tier_level: &native::StdVideoH265ProfileTierLevel,
dec_pic_buf_mgr: &native::StdVideoH265DecPicBufMgr,
) -> native::StdVideoH265SequenceParameterSet {
native::StdVideoH265SequenceParameterSet {
flags: native::StdVideoH265SpsFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
},
chroma_format_idc: native::STD_VIDEO_H265_CHROMA_FORMAT_IDC_420,
pic_width_in_luma_samples: extent.width,
pic_height_in_luma_samples: extent.height,
sps_video_parameter_set_id: 0,
sps_max_sub_layers_minus1: 0,
sps_seq_parameter_set_id: 0,
bit_depth_luma_minus8: 0,
bit_depth_chroma_minus8: 0,
log2_max_pic_order_cnt_lsb_minus4: 0,
log2_min_luma_coding_block_size_minus3: CB_MIN_LOG2_MINUS3,
log2_diff_max_min_luma_coding_block_size: CB_DIFF_LOG2,
log2_min_luma_transform_block_size_minus2: TB_MIN_LOG2_MINUS2,
log2_diff_max_min_luma_transform_block_size: TB_DIFF_LOG2,
max_transform_hierarchy_depth_inter: TRANSFORM_HIERARCHY_DEPTH,
max_transform_hierarchy_depth_intra: TRANSFORM_HIERARCHY_DEPTH,
num_short_term_ref_pic_sets: 0,
num_long_term_ref_pics_sps: 0,
pcm_sample_bit_depth_luma_minus1: 0,
pcm_sample_bit_depth_chroma_minus1: 0,
log2_min_pcm_luma_coding_block_size_minus3: 0,
log2_diff_max_min_pcm_luma_coding_block_size: 0,
reserved1: 0,
reserved2: 0,
palette_max_size: 0,
delta_palette_max_predictor_size: 0,
motion_vector_resolution_control_idc: 0,
sps_num_palette_predictor_initializers_minus1: 0,
conf_win_left_offset: 0,
conf_win_right_offset: 0,
conf_win_top_offset: 0,
conf_win_bottom_offset: 0,
pProfileTierLevel: profile_tier_level,
pDecPicBufMgr: dec_pic_buf_mgr,
pScalingLists: std::ptr::null(),
pShortTermRefPicSet: std::ptr::null(),
pLongTermRefPicsSps: std::ptr::null(),
pSequenceParameterSetVui: std::ptr::null(),
pPredictorPaletteEntries: std::ptr::null(),
}
}
pub(crate) fn build_pps() -> native::StdVideoH265PictureParameterSet {
let mut flags = native::StdVideoH265PpsFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_pps_loop_filter_across_slices_enabled_flag(1);
native::StdVideoH265PictureParameterSet {
flags,
pps_pic_parameter_set_id: 0,
pps_seq_parameter_set_id: 0,
sps_video_parameter_set_id: 0,
num_extra_slice_header_bits: 0,
num_ref_idx_l0_default_active_minus1: 0,
num_ref_idx_l1_default_active_minus1: 0,
init_qp_minus26: 0,
diff_cu_qp_delta_depth: 0,
pps_cb_qp_offset: 0,
pps_cr_qp_offset: 0,
pps_beta_offset_div2: 0,
pps_tc_offset_div2: 0,
log2_parallel_merge_level_minus2: 0,
log2_max_transform_skip_block_size_minus2: 0,
diff_cu_chroma_qp_offset_depth: 0,
chroma_qp_offset_list_len_minus1: 0,
cb_qp_offset_list: [0; 6],
cr_qp_offset_list: [0; 6],
log2_sao_offset_scale_luma: 0,
log2_sao_offset_scale_chroma: 0,
pps_act_y_qp_offset_plus5: 0,
pps_act_cb_qp_offset_plus5: 0,
pps_act_cr_qp_offset_plus3: 0,
pps_num_palette_predictor_initializers: 0,
luma_bit_depth_entry_minus8: 0,
chroma_bit_depth_entry_minus8: 0,
num_tile_columns_minus1: 0,
num_tile_rows_minus1: 0,
reserved1: 0,
reserved2: 0,
column_width_minus1: [0; 19],
row_height_minus1: [0; 21],
reserved3: 0,
pScalingLists: std::ptr::null(),
pPredictorPaletteEntries: std::ptr::null(),
}
}
pub(crate) const fn build_empty_reference_lists() -> native::StdVideoEncodeH265ReferenceListsInfo {
native::StdVideoEncodeH265ReferenceListsInfo {
flags: native::StdVideoEncodeH265ReferenceListsInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
},
num_ref_idx_l0_active_minus1: 0,
num_ref_idx_l1_active_minus1: 0,
RefPicList0: [0xFF; 15],
RefPicList1: [0xFF; 15],
list_entry_l0: [0xFF; 15],
list_entry_l1: [0xFF; 15],
}
}
pub(crate) fn build_idr_picture_info() -> native::StdVideoEncodeH265PictureInfo {
let mut flags = native::StdVideoEncodeH265PictureInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_is_reference(1);
flags.set_IrapPicFlag(1);
flags.set_pic_output_flag(1);
native::StdVideoEncodeH265PictureInfo {
flags,
pic_type: native::STD_VIDEO_H265_PICTURE_TYPE_IDR,
sps_video_parameter_set_id: 0,
pps_seq_parameter_set_id: 0,
pps_pic_parameter_set_id: 0,
short_term_ref_pic_set_idx: 0,
PicOrderCntVal: 0,
TemporalId: 0,
reserved1: [0; 7],
pRefLists: std::ptr::null(),
pShortTermRefPicSet: std::ptr::null(),
pLongTermRefPics: std::ptr::null(),
}
}
pub(crate) fn build_idr_slice_segment_header() -> native::StdVideoEncodeH265SliceSegmentHeader {
let mut flags = native::StdVideoEncodeH265SliceSegmentHeaderFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_first_slice_segment_in_pic_flag(1);
flags.set_slice_loop_filter_across_slices_enabled_flag(1);
native::StdVideoEncodeH265SliceSegmentHeader {
flags,
slice_type: native::STD_VIDEO_H265_SLICE_TYPE_I,
slice_segment_address: 0,
collocated_ref_idx: 0,
MaxNumMergeCand: 5,
slice_cb_qp_offset: 0,
slice_cr_qp_offset: 0,
slice_beta_offset_div2: 0,
slice_tc_offset_div2: 0,
slice_act_y_qp_offset: 0,
slice_act_cb_qp_offset: 0,
slice_act_cr_qp_offset: 0,
slice_qp_delta: 0,
reserved1: 0,
pWeightTable: std::ptr::null(),
}
}