diff --git a/Cargo.lock b/Cargo.lock index 7a8d802..6959f76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,7 +172,7 @@ dependencies = [ [[package]] name = "dolby_vision" -version = "1.3.1" +version = "1.3.2" dependencies = [ "anyhow", "bitvec", @@ -185,7 +185,7 @@ dependencies = [ [[package]] name = "dovi_tool" -version = "1.3.1" +version = "1.3.2" dependencies = [ "anyhow", "bitvec", diff --git a/Cargo.toml b/Cargo.toml index 089c3a4..f8dd4a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dovi_tool" -version = "1.3.1" +version = "1.3.2" authors = ["quietvoid"] edition = "2018" rust-version = "1.51.0" diff --git a/assets/tests/profile5-02.bin b/assets/tests/profile5-02.bin new file mode 100644 index 0000000..0d2b0e7 Binary files /dev/null and b/assets/tests/profile5-02.bin differ diff --git a/assets/tests/profile8_from_profile5-02.bin b/assets/tests/profile8_from_profile5-02.bin new file mode 100644 index 0000000..e3fde62 Binary files /dev/null and b/assets/tests/profile8_from_profile5-02.bin differ diff --git a/dolby_vision/Cargo.toml b/dolby_vision/Cargo.toml index db62af1..350f653 100644 --- a/dolby_vision/Cargo.toml +++ b/dolby_vision/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dolby_vision" -version = "1.3.1" +version = "1.3.2" authors = ["quietvoid"] edition = "2018" rust-version = "1.55.0" diff --git a/dolby_vision/src/rpu/dovi_rpu.rs b/dolby_vision/src/rpu/dovi_rpu.rs index 139f531..1c45997 100644 --- a/dolby_vision/src/rpu/dovi_rpu.rs +++ b/dolby_vision/src/rpu/dovi_rpu.rs @@ -324,15 +324,10 @@ impl DoviRpu { self.header.bl_video_full_range_flag = false; self.header.num_pivots_minus_2 = [0, 0, 0]; - self.header - .pred_pivot_value - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(2); - v[0] = 0; - v[1] = 1023; - }); + self.header.pred_pivot_value.iter_mut().for_each(|v| { + v.clear(); + v.extend(&[0, 1023]); + }); if let Some(ref mut rpu_data_mapping) = self.rpu_data_mapping { rpu_data_mapping.p5_to_p81(); diff --git a/dolby_vision/src/rpu/rpu_data_mapping.rs b/dolby_vision/src/rpu/rpu_data_mapping.rs index 5fb4ab7..37a3e98 100644 --- a/dolby_vision/src/rpu/rpu_data_mapping.rs +++ b/dolby_vision/src/rpu/rpu_data_mapping.rs @@ -319,133 +319,65 @@ impl RpuDataMapping { } pub fn p5_to_p81(&mut self) { - self.mapping_idc - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.mapping_idc.iter_mut().for_each(|v| { + v.clear(); + v.push(0); + }); - self.mapping_param_pred_flag - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = false; - }); + self.mapping_param_pred_flag.iter_mut().for_each(|v| { + v.clear(); + v.push(false); + }); - self.num_mapping_param_predictors - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.num_mapping_param_predictors.iter_mut().for_each(|v| { + v.clear(); + v.push(0); + }); self.diff_pred_part_idx_mapping_minus1 .iter_mut() - .filter(|v| !v.is_empty()) .for_each(|v| { - v.truncate(1); - v[0] = 0; + v.clear(); + v.push(0); }); - self.poly_order_minus1 - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.poly_order_minus1.iter_mut().for_each(|v| { + v.clear(); + v.push(0); + }); - self.linear_interp_flag - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = false; - }); + self.linear_interp_flag.iter_mut().for_each(|v| { + v.clear(); + v.push(false); + }); self.pred_linear_interp_value_int .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + .for_each(|v| v.clear()); self.pred_linear_interp_value .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + .for_each(|v| v.clear()); - self.poly_coef_int - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v.iter_mut().filter(|v| !v.is_empty()).for_each(|v2| { - v2.truncate(2); - v2[0] = 0; - v2[1] = 1; - }); - }); + self.poly_coef_int.iter_mut().for_each(|v| { + v.clear(); + v.push(vec![0, 1]); + }); - self.poly_coef - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v.iter_mut().filter(|v| !v.is_empty()).for_each(|v2| { - v2.truncate(2); - v2[0] = 0; - v2[1] = 0; - }); - }); + self.poly_coef.iter_mut().for_each(|v| { + v.clear(); + v.push(vec![0, 0]); + }); - self.mmr_order_minus1 - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.mmr_order_minus1.iter_mut().for_each(|v| v.clear()); - self.mmr_constant_int - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.mmr_constant_int.iter_mut().for_each(|v| v.clear()); - self.mmr_constant - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = 0; - }); + self.mmr_constant.iter_mut().for_each(|v| v.clear()); - self.mmr_coef_int - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = vec![]; - }); + self.mmr_coef_int.iter_mut().for_each(|v| v.clear()); - self.mmr_coef - .iter_mut() - .filter(|v| !v.is_empty()) - .for_each(|v| { - v.truncate(1); - v[0] = vec![]; - }); + self.mmr_coef.iter_mut().for_each(|v| v.clear()); } pub fn p8_default() -> RpuDataMapping { diff --git a/src/dovi/tests.rs b/src/dovi/tests.rs index b2e09e3..d20b9e1 100644 --- a/src/dovi/tests.rs +++ b/src/dovi/tests.rs @@ -16,6 +16,25 @@ pub fn _parse_file(input: PathBuf) -> Result<(Vec, DoviRpu)> { Ok((original_data, dovi_rpu)) } +fn _debug(data: &[u8]) -> Result<()> { + use crate::dovi::OUT_NAL_HEADER; + use std::fs::OpenOptions; + use std::io::Write; + + let mut file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open("test.bin")?; + + file.write_all(OUT_NAL_HEADER)?; + file.write_all(&data[2..])?; + + file.flush()?; + + Ok(()) +} + #[test] fn profile4() -> Result<()> { let (original_data, dovi_rpu) = _parse_file(PathBuf::from("./assets/tests/profile4.bin"))?; @@ -329,3 +348,48 @@ fn p8_to_mel() -> Result<()> { Ok(()) } + +#[test] +fn profile5_to_p81() -> Result<()> { + let (original_data, mut dovi_rpu) = _parse_file(PathBuf::from("./assets/tests/profile5.bin"))?; + assert_eq!(dovi_rpu.dovi_profile, 5); + let mut parsed_data = dovi_rpu.write_hevc_unspec62_nalu()?; + + assert_eq!(&original_data[4..], &parsed_data[2..]); + + // Profile 5 to 8.1 + let (p81_data, p81_rpu) = _parse_file(PathBuf::from("./assets/tests/profile8.bin"))?; + assert_eq!(p81_rpu.dovi_profile, 8); + + dovi_rpu.convert_with_mode(3)?; + parsed_data = dovi_rpu.write_hevc_unspec62_nalu()?; + assert_eq!(&p81_data[4..], &parsed_data[2..]); + + assert_eq!(dovi_rpu.dovi_profile, 8); + + Ok(()) +} + +#[test] +fn profile5_to_p81_2() -> Result<()> { + let (original_data, mut dovi_rpu) = + _parse_file(PathBuf::from("./assets/tests/profile5-02.bin"))?; + assert_eq!(dovi_rpu.dovi_profile, 5); + let mut parsed_data = dovi_rpu.write_hevc_unspec62_nalu()?; + + assert_eq!(&original_data[4..], &parsed_data[2..]); + + // Profile 5 to 8.1 + let (p81_data, p81_rpu) = _parse_file(PathBuf::from( + "./assets/tests/profile8_from_profile5-02.bin", + ))?; + assert_eq!(p81_rpu.dovi_profile, 8); + + dovi_rpu.convert_with_mode(3)?; + parsed_data = dovi_rpu.write_hevc_unspec62_nalu()?; + assert_eq!(&p81_data[4..], &parsed_data[2..]); + + assert_eq!(dovi_rpu.dovi_profile, 8); + + Ok(()) +}