Skip to content

Commit

Permalink
Add l1_avg_pq_cm_version to generate config
Browse files Browse the repository at this point in the history
  • Loading branch information
quietvoid committed Nov 12, 2022
1 parent c996228 commit d745df6
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 6 deletions.
38 changes: 38 additions & 0 deletions assets/generator_examples/l1_cmv29_override_avg_cmv40.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"cm_version": "V29",
"l1_avg_pq_cm_version": "V40",
"level6": {
"max_display_mastering_luminance": 1000,
"min_display_mastering_luminance": 1,
"max_content_light_level": 1000,
"max_frame_average_light_level": 400
},
"shots": [
{
"start": 0,
"duration": 1,
"metadata_blocks": [
{
"Level1": {
"min_pq": 0,
"max_pq": 1678,
"avg_pq": 948
}
}
]
},
{
"start": 1,
"duration": 1,
"metadata_blocks": [
{
"Level1": {
"min_pq": 0,
"max_pq": 3074,
"avg_pq": 1450
}
}
]
}
]
}
3 changes: 3 additions & 0 deletions docs/generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ A JSON config example:
"source_min_pq": int,
"source_max_pq": int,

// CM version to override the minimum L1 `avg_pq`
"l1_avg_pq_cm_version": string,

// L5 metadata, optional.
// If not specified, L5 metadata is added with 0 offsets.
"level5": {
Expand Down
3 changes: 3 additions & 0 deletions dolby_vision/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## 2.0.1
- Added `replace_levels_from_rpu` function to `DoviRpu`.
- Added `l1_avg_pq_cm_version` to `GenerateConfig`.
- Allows overriding the minimum L1 `avg_pq` CM version.
- Example use case: Some grades are done in `CM v4.0` but distributed as `CM v2.9` RPU.

## 2.0.0
- Modified `extension_metadata::blocks` parsing functions to return a `Result`.
Expand Down
7 changes: 6 additions & 1 deletion dolby_vision/src/rpu/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct GenerateConfig {
#[cfg_attr(feature = "serde_feature", serde(default))]
pub source_max_pq: Option<u16>,

/// CM version to override the minimum L1 `avg_pq`
#[cfg_attr(feature = "serde_feature", serde(default))]
pub l1_avg_pq_cm_version: Option<CmVersion>,

/// Active area offsets.
/// Defaults to zero offsets, should be present in RPU
#[cfg_attr(feature = "serde_feature", serde(default))]
Expand Down Expand Up @@ -222,7 +226,7 @@ impl GenerateConfig {
pub fn fixup_l1(&mut self) {
let clamp_l1 = |block: &mut ExtMetadataBlock| {
if let ExtMetadataBlock::Level1(l1) = block {
l1.clamp_values_cm_version(self.cm_version);
l1.clamp_values_cm_version(self.l1_avg_pq_cm_version.unwrap_or(self.cm_version));
}
};

Expand All @@ -246,6 +250,7 @@ impl Default for GenerateConfig {
long_play_mode: Default::default(),
source_min_pq: Default::default(),
source_max_pq: Default::default(),
l1_avg_pq_cm_version: Default::default(),
default_metadata_blocks: Default::default(),
level5: Default::default(),
level6: Some(ExtMetadataBlockLevel6 {
Expand Down
11 changes: 7 additions & 4 deletions src/dovi/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,12 @@ impl Generator {
let mut config = if let Some(json_path) = &self.json_path {
let json_file = File::open(json_path)?;

println!("Reading generator config file...");
println!("Reading generate config file...");
let mut config: GenerateConfig = serde_json::from_reader(&json_file)?;

// Set default to the config's CM version if it wasn't specified
config.l1_avg_pq_cm_version.get_or_insert(config.cm_version);

if let Some(hdr10plus_path) = &self.hdr10plus_path {
parse_hdr10plus_for_l1(hdr10plus_path, &mut config)?;
} else if let Some(madvr_path) = &self.madvr_path {
Expand Down Expand Up @@ -241,7 +244,7 @@ fn parse_hdr10plus_for_l1<P: AsRef<Path>>(
min_pq,
max_pq,
avg_pq,
config.cm_version,
config.l1_avg_pq_cm_version.unwrap(),
),
)],
..Default::default()
Expand Down Expand Up @@ -302,7 +305,7 @@ pub fn generate_metadata_from_madvr<P: AsRef<Path>>(
min_pq,
max_pq,
avg_pq,
config.cm_version,
config.l1_avg_pq_cm_version.unwrap(),
),
)],
..Default::default()
Expand All @@ -326,7 +329,7 @@ pub fn generate_metadata_from_madvr<P: AsRef<Path>>(
min_pq,
max_pq,
avg_pq,
config.cm_version,
config.l1_avg_pq_cm_version.unwrap(),
),
)],
};
Expand Down
68 changes: 67 additions & 1 deletion tests/rpu/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,75 @@ fn generate_l1_cmv40() -> Result<()> {

assert_eq!(shot2_vdr_dm_data.scene_refresh_flag, 1);

// Only L5 and L6
// Only L1, L5 and L6
assert_eq!(shot2_vdr_dm_data.metadata_blocks(1).unwrap().len(), 3);

if let ExtMetadataBlock::Level1(level1) = shot2_vdr_dm_data.get_block(1).unwrap() {
assert_eq!(level1.min_pq, 0);
assert_eq!(level1.max_pq, 3074);
assert_eq!(level1.avg_pq, 1450);
}

Ok(())
}

#[test]
fn l1_cmv29_override_avg_cmv40() -> Result<()> {
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
let temp = assert_fs::TempDir::new().unwrap();

let generate_config = Path::new("assets/generator_examples/l1_cmv29_override_avg_cmv40.json");
let output_rpu = temp.child("RPU.bin");

let assert = cmd
.arg(SUBCOMMAND)
.arg("--json")
.arg(generate_config)
.arg("--rpu-out")
.arg(output_rpu.as_ref())
.assert();

println!(
"{:?}",
std::str::from_utf8(assert.get_output().stdout.as_ref())
);
assert.success().stderr(predicate::str::is_empty());

output_rpu.assert(predicate::path::is_file());

let rpus = dolby_vision::rpu::utils::parse_rpu_file(output_rpu.as_ref())?;
assert_eq!(rpus.len(), 2);

let shot1_rpu = &rpus[0];
let shot1_vdr_dm_data = shot1_rpu.vdr_dm_data.as_ref().unwrap();

assert_eq!(shot1_vdr_dm_data.scene_refresh_flag, 1);

// Only L1, L5 and L6
assert_eq!(shot1_vdr_dm_data.metadata_blocks(1).unwrap().len(), 3);

// No CM v4.0
assert!(shot1_vdr_dm_data.metadata_blocks(3).is_none());

if let ExtMetadataBlock::Level1(level1) = shot1_vdr_dm_data.get_block(1).unwrap() {
assert_eq!(level1.min_pq, 0);
// Clamped to 2081
assert_eq!(level1.max_pq, 2081);
// Clamped to 1229
assert_eq!(level1.avg_pq, 1229);
}

let shot2_rpu = &rpus[1];
let shot2_vdr_dm_data = shot2_rpu.vdr_dm_data.as_ref().unwrap();

assert_eq!(shot2_vdr_dm_data.scene_refresh_flag, 1);

// Only L1, L5 and L6
assert_eq!(shot2_vdr_dm_data.metadata_blocks(1).unwrap().len(), 3);

// No CM v4.0
assert!(shot2_vdr_dm_data.metadata_blocks(3).is_none());

if let ExtMetadataBlock::Level1(level1) = shot2_vdr_dm_data.get_block(1).unwrap() {
assert_eq!(level1.min_pq, 0);
assert_eq!(level1.max_pq, 3074);
Expand Down

0 comments on commit d745df6

Please sign in to comment.