Skip to content

Commit

Permalink
WIP Add support for variable length extension metadata blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
quietvoid committed Jan 6, 2022
1 parent af5ff23 commit 5236e3a
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 11 deletions.
14 changes: 11 additions & 3 deletions assets/tests/cmv4_0_2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,16 @@
<Level5 level="5">
<AspectRatios>1.77778 1.55556</AspectRatios>
</Level5>
<Level8 level="8">
<TID>1</TID>
<L8Trim>0 0 0 0 0 0</L8Trim>
<MidContrastBias>0</MidContrastBias>
<HighlightClipping>-0.0180664</HighlightClipping>
<SaturationVectorField>0 0 0 0 0 0</SaturationVectorField>
<HueVectorField>0 0 0 0 0 0</HueVectorField>
</Level8>
<Level9 level="9">
<SourceColorModel>255</SourceColorModel>
<SourceColorModel>0</SourceColorModel>
<SourceColorPrimary>0.68 0.32 0.265 0.69 0.15 0.06 0.3127 0.329</SourceColorPrimary>
</Level9>
</DVDynamicData>
Expand Down Expand Up @@ -169,7 +177,7 @@
<HueVectorField>0 0 0 0 0 0</HueVectorField>
</Level8>
<Level9 level="9">
<SourceColorModel>255</SourceColorModel>
<SourceColorModel>0</SourceColorModel>
<SourceColorPrimary>0.68 0.32 0.265 0.69 0.15 0.06 0.3127 0.329</SourceColorPrimary>
</Level9>
</DVDynamicData>
Expand All @@ -190,7 +198,7 @@
<L1Offset>0 -0.0863522 0</L1Offset>
</Level3>
<Level9 level="9">
<SourceColorModel>255</SourceColorModel>
<SourceColorModel>0</SourceColorModel>
<SourceColorPrimary>0.68 0.32 0.265 0.69 0.15 0.06 0.3127 0.329</SourceColorPrimary>
</Level9>
</DVDynamicData>
Expand Down
44 changes: 39 additions & 5 deletions dolby_vision/src/rpu/extension_metadata/blocks/level8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,41 @@ use super::{ExtMetadataBlock, ExtMetadataBlockInfo, MAX_12_BIT_VALUE};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_feature", derive(Deserialize, Serialize))]
pub struct ExtMetadataBlockLevel8 {
pub length: u64,
pub target_display_index: u8,
pub trim_slope: u16,
pub trim_offset: u16,
pub trim_power: u16,
pub trim_chroma_weight: u16,
pub trim_saturation_gain: u16,
pub ms_weight: u16,
pub target_mid_contrast: u16,
pub clip_trim: u16,
}

impl ExtMetadataBlockLevel8 {
pub fn parse(reader: &mut BitVecReader) -> ExtMetadataBlock {
ExtMetadataBlock::Level8(Self {
pub fn parse(reader: &mut BitVecReader, length: u64) -> ExtMetadataBlock {
let mut level8 = Self {
length,
target_display_index: reader.get_n(8),
trim_slope: reader.get_n(12),
trim_offset: reader.get_n(12),
trim_power: reader.get_n(12),
trim_chroma_weight: reader.get_n(12),
trim_saturation_gain: reader.get_n(12),
ms_weight: reader.get_n(12),
})
..Default::default()
};

if length >= 11 {
level8.target_mid_contrast = reader.get_n(12);

if length >= 13 {
level8.clip_trim = reader.get_n(12);
}
}

ExtMetadataBlock::Level8(level8)
}

pub fn write(&self, writer: &mut BitVecWriter) -> Result<()> {
Expand All @@ -45,6 +60,14 @@ impl ExtMetadataBlockLevel8 {
writer.write_n(&self.trim_saturation_gain.to_be_bytes(), 12);
writer.write_n(&self.ms_weight.to_be_bytes(), 12);

if self.length >= 11 {
writer.write_n(&self.target_mid_contrast.to_be_bytes(), 12);

if self.length >= 13 {
writer.write_n(&self.clip_trim.to_be_bytes(), 12);
}
}

Ok(())
}

Expand All @@ -55,6 +78,8 @@ impl ExtMetadataBlockLevel8 {
ensure!(self.trim_chroma_weight <= MAX_12_BIT_VALUE);
ensure!(self.trim_saturation_gain <= MAX_12_BIT_VALUE);
ensure!(self.ms_weight <= MAX_12_BIT_VALUE);
ensure!(self.target_mid_contrast <= MAX_12_BIT_VALUE);
ensure!(self.clip_trim <= MAX_12_BIT_VALUE);

Ok(())
}
Expand All @@ -66,11 +91,17 @@ impl ExtMetadataBlockInfo for ExtMetadataBlockLevel8 {
}

fn bytes_size(&self) -> u64 {
10
self.length
}

fn required_bits(&self) -> u64 {
80
if self.length == 13 {
104
} else if self.length == 12 {
92
} else {
80
}
}

fn sort_key(&self) -> (u8, u16) {
Expand All @@ -82,13 +113,16 @@ impl ExtMetadataBlockInfo for ExtMetadataBlockLevel8 {
impl Default for ExtMetadataBlockLevel8 {
fn default() -> Self {
Self {
length: 10,
target_display_index: 48,
trim_slope: 2048,
trim_offset: 2048,
trim_power: 2048,
trim_chroma_weight: 2048,
trim_saturation_gain: 2048,
ms_weight: 2048,
target_mid_contrast: 0,
clip_trim: 0,
}
}
}
4 changes: 2 additions & 2 deletions dolby_vision/src/rpu/extension_metadata/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ impl ExtMetadataBlock {
pub fn validate_and_read_remaining<T: WithExtMetadataBlocks>(
&self,
reader: &mut BitVecReader,
expected_length: u64,
block_length: u64,
) -> Result<()> {
let level = self.level();

ensure!(
expected_length == self.length_bytes(),
block_length == self.length_bytes(),
format!(
"{}: Invalid metadata block. Block level {} should have length {}",
T::VERSION,
Expand Down
2 changes: 1 addition & 1 deletion dolby_vision/src/rpu/extension_metadata/cmv40.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl WithExtMetadataBlocks for CmV40DmData {

let ext_metadata_block = match ext_block_level {
3 => level3::ExtMetadataBlockLevel3::parse(reader),
8 => level8::ExtMetadataBlockLevel8::parse(reader),
8 => level8::ExtMetadataBlockLevel8::parse(reader, ext_block_length),
9 => level9::ExtMetadataBlockLevel9::parse(reader),
10 => level10::ExtMetadataBlockLevel10::parse(reader),
11 => level11::ExtMetadataBlockLevel11::parse(reader),
Expand Down
3 changes: 3 additions & 0 deletions dolby_vision/src/rpu/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,16 @@ mod tests {
let mut shot2_level8_iter = shot2_vdr_dm_data.level_blocks_iter(8);

if let ExtMetadataBlock::Level8(shot2_l8) = shot2_level8_iter.next().unwrap() {
assert_eq!(shot2_l8.length, 13);
assert_eq!(shot2_l8.target_display_index, 1);
assert_eq!(shot2_l8.trim_slope, 2048);
assert_eq!(shot2_l8.trim_offset, 2048);
assert_eq!(shot2_l8.trim_power, 2048);
assert_eq!(shot2_l8.trim_chroma_weight, 2048);
assert_eq!(shot2_l8.trim_saturation_gain, 2048);
assert_eq!(shot2_l8.ms_weight, 2048);
assert_eq!(shot2_l8.target_mid_contrast, 2048);
assert_eq!(shot2_l8.clip_trim, 2011);
}
if let ExtMetadataBlock::Level8(shot2_l8) = shot2_level8_iter.next().unwrap() {
assert_eq!(shot2_l8.target_display_index, 48);
Expand Down
38 changes: 38 additions & 0 deletions dolby_vision/src/xml/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,14 +558,52 @@ impl CmXmlParser {
((trim[5].parse::<f32>().unwrap() * 2048.0) + 2048.0).round() as u16,
);

let mid_contrast_bias_text = node
.children()
.find(|e| e.has_tag_name("MidContrastBias"))
.unwrap()
.text()
.unwrap();

let highlight_clipping_text = node
.children()
.find(|e| e.has_tag_name("HighlightClipping"))
.unwrap()
.text()
.unwrap();

let target_mid_contrast = min(
4095,
((mid_contrast_bias_text.parse::<f32>().unwrap() * 2048.0) + 2048.0).round() as u16,
);

let clip_trim = min(
4095,
((highlight_clipping_text.parse::<f32>().unwrap() * 2048.0) + 2048.0).round() as u16,
);

// Write order:
// target_mid_contrast <-- 12
// clip_trim <-- 13
let length = if clip_trim != 2048 {
13
} else if target_mid_contrast != 2048 {
12
} else {
10
};

Ok(ExtMetadataBlockLevel8 {
length,
target_display_index: target_display.id.parse::<u8>()?,
trim_slope,
trim_offset,
trim_power,
trim_chroma_weight,
trim_saturation_gain,
ms_weight,
target_mid_contrast,
clip_trim,
})
}

Expand Down

0 comments on commit 5236e3a

Please sign in to comment.