From adf622d5f2ef79c7a61603112fb4b67d218cd9c7 Mon Sep 17 00:00:00 2001 From: quietvoid <39477805+quietvoid@users.noreply.github.com> Date: Wed, 5 May 2021 15:26:34 -0400 Subject: [PATCH] Add profile 4 handling, info subcommand --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 7 +++++++ profiles.md | 2 ++ src/commands.rs | 19 +++++++++++++++++++ src/dovi/mod.rs | 1 + src/dovi/rpu/rpu_data.rs | 12 ++++++++++++ src/dovi/rpu/rpu_data_header.rs | 8 ++++++-- src/dovi/rpu/tests.rs | 9 +++++++++ src/dovi/rpu/vdr_dm_data.rs | 9 +++++---- src/dovi/rpu_info.rs | 29 +++++++++++++++++++++++++++++ src/main.rs | 3 ++- 12 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 src/dovi/rpu_info.rs diff --git a/Cargo.lock b/Cargo.lock index 76b6538..df23e67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" [[package]] name = "dovi_tool" -version = "0.3.1" +version = "0.3.2" dependencies = [ "ansi_term 0.12.1", "bitvec 0.20.2", diff --git a/Cargo.toml b/Cargo.toml index 7939907..012f285 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dovi_tool" -version = "0.3.1" +version = "0.3.2" authors = ["quietvoid"] edition = "2018" license = "MIT" diff --git a/README.md b/README.md index 92c39d5..caae1eb 100644 --- a/README.md +++ b/README.md @@ -42,5 +42,12 @@ See examples in `assets` folder. * `dovi_tool editor -i RPU.bin -j assets/editor_examples/mode.json --rpu-out RPU_mode2.bin` +#### info +Prints the parsed RPU data for a specific frame. + +* `dovi_tool info -i RPU.bin -f 0` + +  + Build artifacts can be found in the Github Actions. More features may or may not be added in the future. diff --git a/profiles.md b/profiles.md index 095e166..3688d18 100644 --- a/profiles.md +++ b/profiles.md @@ -1,4 +1,6 @@ Differentiating between Dolby Vision profiles. +##### Profile 4 +Possibly `vdr_bit_depth_minus_8` > 4 ##### Profile 5 `vdr_rpu_profile = 0` `bl_video_full_range_flag = 0` diff --git a/src/commands.rs b/src/commands.rs index 7bc68c8..2a0b5d1 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -130,4 +130,23 @@ pub enum Command { #[structopt(long, help = "Output HEVC file location", parse(from_os_str))] output: Option, }, + + Info { + #[structopt( + name = "input", + short = "i", + long, + help = "Sets the input RPU file to use", + parse(from_os_str) + )] + input: PathBuf, + + #[structopt( + name = "frame", + short = "f", + long, + help = "Frame number to show info for" + )] + frame: Option, + }, } diff --git a/src/dovi/mod.rs b/src/dovi/mod.rs index 339416d..77742f6 100644 --- a/src/dovi/mod.rs +++ b/src/dovi/mod.rs @@ -2,6 +2,7 @@ pub mod converter; pub mod demuxer; pub mod editor; pub mod rpu_extractor; +pub mod rpu_info; pub mod rpu_injector; mod io; diff --git a/src/dovi/rpu/rpu_data.rs b/src/dovi/rpu/rpu_data.rs index 059fee9..606b7da 100644 --- a/src/dovi/rpu/rpu_data.rs +++ b/src/dovi/rpu/rpu_data.rs @@ -41,6 +41,7 @@ impl DoviRpu { let reader = &mut dovi_rpu.reader; dovi_rpu.header = RpuDataHeader::rpu_data_header(reader); + // Preliminary header validation dovi_rpu.dovi_profile = dovi_rpu.header.get_dovi_profile(); dovi_rpu.header.validate(dovi_rpu.dovi_profile); @@ -78,6 +79,8 @@ impl DoviRpu { assert_eq!(last_byte, 0x80); } + dovi_rpu.validate(); + dovi_rpu } @@ -228,4 +231,13 @@ impl DoviRpu { panic!("Attempt to convert profile 5: RPU is not profile 5!"); } } + + pub fn validate(&mut self) { + self.dovi_profile = self.header.get_dovi_profile(); + self.header.validate(self.dovi_profile); + + if let Some(ref mut vdr_dm_data) = self.vdr_dm_data { + vdr_dm_data.validate(self.dovi_profile); + } + } } diff --git a/src/dovi/rpu/rpu_data_header.rs b/src/dovi/rpu/rpu_data_header.rs index 56c877b..cf98fd1 100644 --- a/src/dovi/rpu/rpu_data_header.rs +++ b/src/dovi/rpu/rpu_data_header.rs @@ -149,9 +149,13 @@ impl RpuDataHeader { } } 1 => { - // 7 or 8 + // 4, 7 or 8 if self.el_spatial_resampling_filter_flag && !self.disable_residual_flag { - 7 + if self.vdr_bit_depth_minus_8 == 4 { + 7 + } else { + 4 + } } else { 8 } diff --git a/src/dovi/rpu/tests.rs b/src/dovi/rpu/tests.rs index b40a90c..9113341 100644 --- a/src/dovi/rpu/tests.rs +++ b/src/dovi/rpu/tests.rs @@ -16,6 +16,15 @@ pub fn _parse_file(input: PathBuf) -> (Vec, DoviRpu) { (original_data, dovi_rpu) } +#[test] +fn profile4() { + let (original_data, mut dovi_rpu) = _parse_file(PathBuf::from("./assets/profile4.bin")); + assert_eq!(dovi_rpu.dovi_profile, 4); + let parsed_data = dovi_rpu.write_rpu_data(); + + assert_eq!(&original_data, &parsed_data); +} + #[test] fn profile5() { let (original_data, mut dovi_rpu) = _parse_file(PathBuf::from("./assets/profile5.bin")); diff --git a/src/dovi/rpu/vdr_dm_data.rs b/src/dovi/rpu/vdr_dm_data.rs index cb2a156..7f36fae 100644 --- a/src/dovi/rpu/vdr_dm_data.rs +++ b/src/dovi/rpu/vdr_dm_data.rs @@ -171,15 +171,16 @@ impl VdrDmData { } } - data.validate(); - data } - pub fn validate(&self) { + pub fn validate(&self, profile: u8) { assert!(self.affected_dm_metadata_id <= 15); assert!(self.signal_bit_depth >= 8 && self.signal_bit_depth <= 16); - assert_eq!(self.signal_eotf, 65535); + + if profile > 4 { + assert_eq!(self.signal_eotf, 65535); + } } pub fn write(&self, writer: &mut BitVecWriter) { diff --git a/src/dovi/rpu_info.rs b/src/dovi/rpu_info.rs new file mode 100644 index 0000000..54eef04 --- /dev/null +++ b/src/dovi/rpu_info.rs @@ -0,0 +1,29 @@ +use std::path::PathBuf; + +use super::{parse_rpu_file, rpu::DoviRpu}; + +pub struct RpuInfo { + input: PathBuf, + frame: Option, + rpus: Option>, +} + +impl RpuInfo { + pub fn info(input: PathBuf, frame: Option) { + let mut info = RpuInfo { + input, + frame, + rpus: None, + }; + + info.rpus = parse_rpu_file(&info.input); + + if let Some(ref rpus) = info.rpus { + if let Some(f) = info.frame { + assert!(f < rpus.len()); + + println!("{:#?}", rpus[f]); + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 0554b4f..5a4f7f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use commands::Command; mod dovi; use dovi::{ converter::Converter, demuxer::Demuxer, editor::Editor, rpu_extractor::RpuExtractor, - rpu_injector::RpuInjector, Format, RpuOptions, + rpu_info::RpuInfo, rpu_injector::RpuInjector, Format, RpuOptions, }; #[derive(StructOpt, Debug)] @@ -75,6 +75,7 @@ fn main() { rpu_in, output, } => RpuInjector::inject_rpu(input, rpu_in, output), + Command::Info { input, frame } => RpuInfo::info(input, frame), } }