#![allow(unsafe_op_in_unsafe_fn)]
#![allow(clippy::ptr_as_ptr)]
#![allow(clippy::cast_possible_wrap)]
use super::{
AVPacket, AVPacketSideDataType_AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
AVPacketSideDataType_AV_PKT_DATA_MASTERING_DISPLAY_METADATA, VideoEncoderInner,
av_packet_new_side_data,
};
#[repr(C)]
pub(super) struct AvContentLightMetadata {
pub(super) max_cll: u32,
pub(super) max_fall: u32,
}
#[repr(C)]
pub(super) struct AvMasteringDisplayMetadata {
pub(super) display_primaries: [[ff_sys::AVRational; 2]; 3],
pub(super) white_point: [ff_sys::AVRational; 2],
pub(super) min_luminance: ff_sys::AVRational,
pub(super) max_luminance: ff_sys::AVRational,
pub(super) has_primaries: std::os::raw::c_int,
pub(super) has_luminance: std::os::raw::c_int,
}
impl VideoEncoderInner {
pub(super) unsafe fn attach_hdr10_side_data(
&self,
pkt: *mut AVPacket,
meta: &ff_format::Hdr10Metadata,
) {
let cll_ptr = av_packet_new_side_data(
pkt,
AVPacketSideDataType_AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
std::mem::size_of::<AvContentLightMetadata>(),
);
if cll_ptr.is_null() {
log::warn!(
"hdr10 side_data allocation failed, skipping MaxCLL/MaxFALL type=content_light_level"
);
} else {
let cll_value = AvContentLightMetadata {
max_cll: u32::from(meta.max_cll),
max_fall: u32::from(meta.max_fall),
};
std::ptr::write_unaligned(cll_ptr.cast::<AvContentLightMetadata>(), cll_value);
}
let md_ptr = av_packet_new_side_data(
pkt,
AVPacketSideDataType_AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
std::mem::size_of::<AvMasteringDisplayMetadata>(),
);
if md_ptr.is_null() {
log::warn!(
"hdr10 side_data allocation failed, skipping mastering display type=mastering_display_metadata"
);
} else {
let d = &meta.mastering_display;
let r = |n: u16| ff_sys::AVRational {
num: i32::from(n),
den: 50000,
};
let lum = |n: u32| ff_sys::AVRational {
num: i32::try_from(n).unwrap_or(i32::MAX),
den: 10000,
};
let md_value = AvMasteringDisplayMetadata {
display_primaries: [
[r(d.red_x), r(d.red_y)],
[r(d.green_x), r(d.green_y)],
[r(d.blue_x), r(d.blue_y)],
],
white_point: [r(d.white_x), r(d.white_y)],
min_luminance: lum(d.min_luminance),
max_luminance: lum(d.max_luminance),
has_primaries: 1,
has_luminance: 1,
};
std::ptr::write_unaligned(md_ptr.cast::<AvMasteringDisplayMetadata>(), md_value);
}
}
}