Skip to content

Commit

Permalink
Support blocks with variable length (L8 L9 L10)
Browse files Browse the repository at this point in the history
Support parsing L8/L9 from metadata XML
  A predefined list of primaries is added for parsing primary_index of L9/L10.

Co-authored-by: Rainbaby <rainbaby@outlook.jp>
Co-authored-by: quietvoid <39477805+quietvoid@users.noreply.github.com>
  • Loading branch information
saindriches and quietvoid committed Jan 6, 2022
1 parent 5908b27 commit 73a6f45
Show file tree
Hide file tree
Showing 10 changed files with 877 additions and 123 deletions.
136 changes: 128 additions & 8 deletions dolby_vision/src/rpu/extension_metadata/blocks/level10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,77 @@ use anyhow::{ensure, Result};
use bitvec_helpers::{bitvec_reader::BitVecReader, bitvec_writer::BitVecWriter};

#[cfg(feature = "serde_feature")]
use serde::{Deserialize, Serialize};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};

use super::{level6::MAX_PQ_LUMINANCE, ExtMetadataBlock, ExtMetadataBlockInfo};

pub const PRESET_TARGET_DISPLAYS: &[u8] = &[1, 16, 18, 21, 27, 28, 37, 38, 42, 48, 49];

pub const PREDEFINED_REALDEVICE_PRIMARIES: &[[f64; 8]] = &[
[0.693, 0.304, 0.208, 0.761, 0.1467, 0.0527, 0.3127, 0.329],
[0.6867, 0.3085, 0.231, 0.69, 0.1489, 0.0638, 0.3127, 0.329],
[0.6781, 0.3189, 0.2365, 0.7048, 0.141, 0.0489, 0.3127, 0.329],
[0.68, 0.32, 0.265, 0.69, 0.15, 0.06, 0.3127, 0.329],
[0.7042, 0.294, 0.2271, 0.725, 0.1416, 0.0516, 0.3127, 0.329],
[0.6745, 0.310, 0.2212, 0.7109, 0.152, 0.0619, 0.3127, 0.329],
[
0.6805, 0.3191, 0.2522, 0.6702, 0.1397, 0.0554, 0.3127, 0.329,
],
[
0.6838, 0.3085, 0.2709, 0.6378, 0.1478, 0.0589, 0.3127, 0.329,
],
[
0.6753, 0.3193, 0.2636, 0.6835, 0.1521, 0.0627, 0.3127, 0.329,
],
[
0.6981, 0.2898, 0.1814, 0.7189, 0.1517, 0.0567, 0.3127, 0.329,
],
];

/// Custom target display information
#[repr(C)]
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde_feature", derive(Deserialize, Serialize))]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_feature", derive(Deserialize))]
pub struct ExtMetadataBlockLevel10 {
pub length: u64,
pub target_display_index: u8,
pub target_max_pq: u16,
pub target_min_pq: u16,
pub target_primary_index: u8,

pub target_primary_red_x: u16,
pub target_primary_red_y: u16,
pub target_primary_green_x: u16,
pub target_primary_green_y: u16,
pub target_primary_blue_x: u16,
pub target_primary_blue_y: u16,
pub target_primary_white_x: u16,
pub target_primary_white_y: u16,
}

impl ExtMetadataBlockLevel10 {
pub fn parse(reader: &mut BitVecReader) -> ExtMetadataBlock {
ExtMetadataBlock::Level10(Self {
pub fn parse(reader: &mut BitVecReader, length: u64) -> ExtMetadataBlock {
let mut block = Self {
length,
target_display_index: reader.get_n(8),
target_max_pq: reader.get_n(12),
target_min_pq: reader.get_n(12),
target_primary_index: reader.get_n(8),
})
..Default::default()
};

if length > 5 {
block.target_primary_red_x = reader.get_n(16);
block.target_primary_red_y = reader.get_n(16);
block.target_primary_green_x = reader.get_n(16);
block.target_primary_green_y = reader.get_n(16);
block.target_primary_blue_x = reader.get_n(16);
block.target_primary_blue_y = reader.get_n(16);
block.target_primary_white_x = reader.get_n(16);
block.target_primary_white_y = reader.get_n(16);
}

ExtMetadataBlock::Level10(block)
}

pub fn write(&self, writer: &mut BitVecWriter) -> Result<()> {
Expand All @@ -37,6 +83,17 @@ impl ExtMetadataBlockLevel10 {
writer.write_n(&self.target_min_pq.to_be_bytes(), 12);
writer.write_n(&self.target_primary_index.to_be_bytes(), 8);

if self.length > 5 {
writer.write_n(&self.target_primary_red_x.to_be_bytes(), 16);
writer.write_n(&self.target_primary_red_y.to_be_bytes(), 16);
writer.write_n(&self.target_primary_green_x.to_be_bytes(), 16);
writer.write_n(&self.target_primary_green_y.to_be_bytes(), 16);
writer.write_n(&self.target_primary_blue_x.to_be_bytes(), 16);
writer.write_n(&self.target_primary_blue_y.to_be_bytes(), 16);
writer.write_n(&self.target_primary_white_x.to_be_bytes(), 16);
writer.write_n(&self.target_primary_white_y.to_be_bytes(), 16);
}

Ok(())
}

Expand All @@ -55,10 +112,73 @@ impl ExtMetadataBlockInfo for ExtMetadataBlockLevel10 {
}

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

fn required_bits(&self) -> u64 {
40
match self.length {
5 => 40,
21 => 168,
_ => unreachable!(),
}
}

fn sort_key(&self) -> (u8, u16) {
(self.level(), self.target_display_index as u16)
}
}

impl Default for ExtMetadataBlockLevel10 {
fn default() -> Self {
Self {
length: 5,
target_display_index: 20,
target_max_pq: 2081,
target_min_pq: 0,
target_primary_index: 2,
target_primary_red_x: 0,
target_primary_red_y: 0,
target_primary_green_x: 0,
target_primary_green_y: 0,
target_primary_blue_x: 0,
target_primary_blue_y: 0,
target_primary_white_x: 0,
target_primary_white_y: 0,
}
}
}

#[cfg(feature = "serde_feature")]
impl Serialize for ExtMetadataBlockLevel10 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let name = "ExtMetadataBlockLevel9";
let fields_count = match self.length {
5 => 4,
21 => 12,
_ => unreachable!(),
};

let mut state = serializer.serialize_struct(name, fields_count)?;

state.serialize_field("target_display_index", &self.target_display_index)?;
state.serialize_field("target_max_pq", &self.target_max_pq)?;
state.serialize_field("target_min_pq", &self.target_min_pq)?;
state.serialize_field("target_primary_index", &self.target_primary_index)?;

if self.length > 5 {
state.serialize_field("target_primary_red_x", &self.target_primary_red_x)?;
state.serialize_field("target_primary_red_y", &self.target_primary_white_y)?;
state.serialize_field("target_primary_green_x", &self.target_primary_green_x)?;
state.serialize_field("target_primary_green_y", &self.target_primary_green_y)?;
state.serialize_field("target_primary_blue_x", &self.target_primary_blue_x)?;
state.serialize_field("target_primary_blue_y", &self.target_primary_blue_y)?;
state.serialize_field("target_primary_white_x", &self.target_primary_white_x)?;
state.serialize_field("target_primary_white_y", &self.target_primary_white_y)?;
}

state.end()
}
}
2 changes: 1 addition & 1 deletion dolby_vision/src/rpu/extension_metadata/blocks/level2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl ExtMetadataBlockLevel2 {

pub fn from_nits(target_nits: u16) -> ExtMetadataBlockLevel2 {
ExtMetadataBlockLevel2 {
target_max_pq: (nits_to_pq(target_nits) * 4095.0).round() as u16,
target_max_pq: (nits_to_pq(target_nits.into()) * 4095.0).round() as u16,
..Default::default()
}
}
Expand Down
Loading

0 comments on commit 73a6f45

Please sign in to comment.