#![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"
)]
#![allow(
clippy::cast_possible_truncation,
reason = "AV1 StdVideo* fields are narrower (u8/u16) than this crate's own u32 pixel \
dimensions/enum-repr values, but every one here is driver-validated small \
(this crate's own coded extent, or a fixed spec-level constant like \
STD_VIDEO_AV1_PRIMARY_REF_NONE == 7) — mirrors session_encode.rs's/ \
session_command.rs's identical crate-wide allow for small driver-facing counts."
)]
use vulkanalia::vk::video as native;
pub(crate) const FIXED_Q_INDEX: u8 = 128;
const fn bits_needed(value: u32) -> u32 {
if value == 0 {
1
} else {
32 - value.leading_zeros()
}
}
pub(crate) fn build_color_config() -> native::StdVideoAV1ColorConfig {
let mut flags = native::StdVideoAV1ColorConfigFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_mono_chrome(0);
flags.set_color_range(0);
flags.set_separate_uv_delta_q(0);
flags.set_color_description_present_flag(0);
native::StdVideoAV1ColorConfig {
flags,
BitDepth: 8,
subsampling_x: 1,
subsampling_y: 1,
reserved1: 0,
color_primaries: native::STD_VIDEO_AV1_COLOR_PRIMARIES_UNSPECIFIED,
transfer_characteristics: native::STD_VIDEO_AV1_TRANSFER_CHARACTERISTICS_UNSPECIFIED,
matrix_coefficients: native::STD_VIDEO_AV1_MATRIX_COEFFICIENTS_UNSPECIFIED,
chroma_sample_position: native::STD_VIDEO_AV1_CHROMA_SAMPLE_POSITION_UNKNOWN,
}
}
pub(crate) const fn build_timing_info() -> native::StdVideoAV1TimingInfo {
native::StdVideoAV1TimingInfo {
flags: native::StdVideoAV1TimingInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
},
num_units_in_display_tick: 0,
time_scale: 0,
num_ticks_per_picture_minus_1: 0,
}
}
pub(crate) fn build_sequence_header(
width: u32,
height: u32,
color_config: &native::StdVideoAV1ColorConfig,
timing_info: &native::StdVideoAV1TimingInfo,
) -> native::StdVideoAV1SequenceHeader {
let mut flags = native::StdVideoAV1SequenceHeaderFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_still_picture(0);
flags.set_reduced_still_picture_header(0);
flags.set_use_128x128_superblock(0);
flags.set_enable_filter_intra(0);
flags.set_enable_intra_edge_filter(0);
flags.set_enable_interintra_compound(0);
flags.set_enable_masked_compound(0);
flags.set_enable_warped_motion(0);
flags.set_enable_dual_filter(0);
flags.set_enable_order_hint(1);
flags.set_enable_jnt_comp(0);
flags.set_enable_ref_frame_mvs(0);
flags.set_frame_id_numbers_present_flag(0);
flags.set_enable_superres(0);
flags.set_enable_cdef(0);
flags.set_enable_restoration(0);
flags.set_film_grain_params_present(0);
flags.set_timing_info_present_flag(0);
flags.set_initial_display_delay_present_flag(0);
let max_frame_width_minus_1 = width - 1;
let max_frame_height_minus_1 = height - 1;
native::StdVideoAV1SequenceHeader {
flags,
seq_profile: native::STD_VIDEO_AV1_PROFILE_MAIN,
frame_width_bits_minus_1: (bits_needed(max_frame_width_minus_1) - 1) as u8,
frame_height_bits_minus_1: (bits_needed(max_frame_height_minus_1) - 1) as u8,
max_frame_width_minus_1: max_frame_width_minus_1 as u16,
max_frame_height_minus_1: max_frame_height_minus_1 as u16,
delta_frame_id_length_minus_2: 0,
additional_frame_id_length_minus_1: 0,
order_hint_bits_minus_1: 6,
seq_force_screen_content_tools: 2,
seq_force_integer_mv: 2,
reserved1: [0; 5],
pColorConfig: color_config,
pTimingInfo: timing_info,
}
}
pub(crate) fn build_operating_point() -> native::StdVideoEncodeAV1OperatingPointInfo {
let mut flags = native::StdVideoEncodeAV1OperatingPointInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_decoder_model_present_for_this_op(0);
flags.set_low_delay_mode_flag(0);
flags.set_initial_display_delay_present_for_this_op(0);
native::StdVideoEncodeAV1OperatingPointInfo {
flags,
operating_point_idc: 0,
seq_level_idx: native::STD_VIDEO_AV1_LEVEL_2_0.0 as u8,
seq_tier: 0,
decoder_buffer_delay: 0,
encoder_buffer_delay: 0,
initial_display_delay_minus_1: 0,
}
}
#[allow(
clippy::trivially_copy_pass_by_ref,
reason = "the returned struct embeds a pointer to `extension_header` itself, so it must \
borrow caller-owned memory rather than take (and drop) an owned copy"
)]
pub(crate) fn build_reference_info(
extension_header: &native::StdVideoEncodeAV1ExtensionHeader,
) -> native::StdVideoEncodeAV1ReferenceInfo {
let mut flags = native::StdVideoEncodeAV1ReferenceInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_disable_frame_end_update_cdf(0);
flags.set_segmentation_enabled(0);
native::StdVideoEncodeAV1ReferenceInfo {
flags,
RefFrameId: 0,
frame_type: native::STD_VIDEO_AV1_FRAME_TYPE_KEY,
OrderHint: 0,
reserved1: [0; 3],
pExtensionHeader: extension_header,
}
}
pub(crate) fn build_loop_filter() -> native::StdVideoAV1LoopFilter {
let mut flags = native::StdVideoAV1LoopFilterFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_loop_filter_delta_enabled(0);
flags.set_loop_filter_delta_update(0);
native::StdVideoAV1LoopFilter {
flags,
loop_filter_level: [0; 4],
loop_filter_sharpness: 0,
update_ref_delta: 0,
loop_filter_ref_deltas: [1, 0, 0, 0, -1, 0, -1, -1],
update_mode_delta: 1,
loop_filter_mode_deltas: [0; 2],
}
}
pub(crate) const fn build_cdef() -> native::StdVideoAV1CDEF {
native::StdVideoAV1CDEF {
cdef_damping_minus_3: 0,
cdef_bits: 0,
cdef_y_pri_strength: [0; 8],
cdef_y_sec_strength: [0; 8],
cdef_uv_pri_strength: [0; 8],
cdef_uv_sec_strength: [0; 8],
}
}
pub(crate) const fn build_loop_restoration() -> native::StdVideoAV1LoopRestoration {
native::StdVideoAV1LoopRestoration {
FrameRestorationType: [
native::STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
native::STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
native::STD_VIDEO_AV1_FRAME_RESTORATION_TYPE_NONE,
],
LoopRestorationSize: [1, 1, 1],
}
}
pub(crate) const fn build_global_motion() -> native::StdVideoAV1GlobalMotion {
native::StdVideoAV1GlobalMotion {
GmType: [0; 8],
gm_params: [[0; 6]; 8],
}
}
pub(crate) const fn build_segmentation() -> native::StdVideoAV1Segmentation {
native::StdVideoAV1Segmentation {
FeatureEnabled: [0; 8],
FeatureData: [[0; 8]; 8],
}
}
pub(crate) const fn build_extension_header() -> native::StdVideoEncodeAV1ExtensionHeader {
native::StdVideoEncodeAV1ExtensionHeader {
temporal_id: 0,
spatial_id: 0,
}
}
pub(crate) fn build_quantization() -> native::StdVideoAV1Quantization {
let mut flags = native::StdVideoAV1QuantizationFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_using_qmatrix(0);
flags.set_diff_uv_delta(0);
native::StdVideoAV1Quantization {
flags,
base_q_idx: FIXED_Q_INDEX,
DeltaQYDc: 0,
DeltaQUDc: 0,
DeltaQUAc: 0,
DeltaQVDc: 0,
DeltaQVAc: 0,
qm_y: 0,
qm_u: 0,
qm_v: 0,
}
}
pub(crate) struct PictureInfoOptionals {
pub(crate) quantization: native::StdVideoAV1Quantization,
pub(crate) segmentation: native::StdVideoAV1Segmentation,
pub(crate) loop_filter: native::StdVideoAV1LoopFilter,
pub(crate) cdef: native::StdVideoAV1CDEF,
pub(crate) loop_restoration: native::StdVideoAV1LoopRestoration,
pub(crate) global_motion: native::StdVideoAV1GlobalMotion,
pub(crate) extension_header: native::StdVideoEncodeAV1ExtensionHeader,
}
impl PictureInfoOptionals {
pub(crate) fn new() -> Self {
Self {
quantization: build_quantization(),
segmentation: build_segmentation(),
loop_filter: build_loop_filter(),
cdef: build_cdef(),
loop_restoration: build_loop_restoration(),
global_motion: build_global_motion(),
extension_header: build_extension_header(),
}
}
}
pub(crate) fn build_key_frame_picture_info(
width: u32,
height: u32,
optionals: &PictureInfoOptionals,
) -> native::StdVideoEncodeAV1PictureInfo {
let mut flags = native::StdVideoEncodeAV1PictureInfoFlags {
_bitfield_align_1: [],
_bitfield_1: native::__BindgenBitfieldUnit::new([0u8; 4]),
};
flags.set_error_resilient_mode(1);
flags.set_disable_cdf_update(0);
flags.set_use_superres(0);
flags.set_render_and_frame_size_different(0);
flags.set_allow_screen_content_tools(0);
flags.set_is_filter_switchable(0);
flags.set_force_integer_mv(0);
flags.set_frame_size_override_flag(0);
flags.set_buffer_removal_time_present_flag(0);
flags.set_allow_intrabc(0);
flags.set_frame_refs_short_signaling(0);
flags.set_allow_high_precision_mv(0);
flags.set_is_motion_mode_switchable(0);
flags.set_use_ref_frame_mvs(0);
flags.set_disable_frame_end_update_cdf(0);
flags.set_allow_warped_motion(0);
flags.set_reduced_tx_set(0);
flags.set_skip_mode_present(0);
flags.set_delta_q_present(0);
flags.set_delta_lf_present(0);
flags.set_delta_lf_multi(0);
flags.set_segmentation_enabled(0);
flags.set_segmentation_update_map(0);
flags.set_segmentation_temporal_update(0);
flags.set_segmentation_update_data(0);
flags.set_UsesLr(0);
flags.set_usesChromaLr(0);
flags.set_show_frame(1);
flags.set_showable_frame(0);
native::StdVideoEncodeAV1PictureInfo {
flags,
frame_type: native::STD_VIDEO_AV1_FRAME_TYPE_KEY,
frame_presentation_time: 0,
current_frame_id: 0,
order_hint: 0,
primary_ref_frame: native::STD_VIDEO_AV1_PRIMARY_REF_NONE as u8,
refresh_frame_flags: 0xFF,
coded_denom: 0,
render_width_minus_1: (width - 1) as u16,
render_height_minus_1: (height - 1) as u16,
interpolation_filter: native::STD_VIDEO_AV1_INTERPOLATION_FILTER_EIGHTTAP,
TxMode: native::STD_VIDEO_AV1_TX_MODE_SELECT,
delta_q_res: 0,
delta_lf_res: 0,
ref_order_hint: [0; 8],
ref_frame_idx: [-1; 7],
reserved1: [0; 3],
delta_frame_id_minus_1: [0; 7],
pTileInfo: std::ptr::null(),
pQuantization: &raw const optionals.quantization,
pSegmentation: &raw const optionals.segmentation,
pLoopFilter: &raw const optionals.loop_filter,
pCDEF: &raw const optionals.cdef,
pLoopRestoration: &raw const optionals.loop_restoration,
pGlobalMotion: &raw const optionals.global_motion,
pExtensionHeader: &raw const optionals.extension_header,
pBufferRemovalTimes: std::ptr::null(),
}
}