From 85f55af8f2d7a185898f46a4c1ab5daec5372e92 Mon Sep 17 00:00:00 2001 From: quietvoid <39477805+quietvoid@users.noreply.github.com> Date: Fri, 10 Jun 2022 22:08:11 -0400 Subject: [PATCH] Add info summary --- Cargo.lock | 2 +- Cargo.toml | 4 +- README.md | 9 +++-- src/commands/info.rs | 3 ++ src/dovi/rpu_info.rs | 93 ++++++++++++++++++++++++++++++++++---------- 5 files changed, 85 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08a087c..ba3697d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -229,7 +229,7 @@ dependencies = [ [[package]] name = "dovi_tool" -version = "1.5.3" +version = "1.5.4" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index 9220aac..1858407 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "dovi_tool" -version = "1.5.3" +version = "1.5.4" authors = ["quietvoid"] edition = "2021" -rust-version = "1.56.0" +rust-version = "1.58.0" license = "MIT" build = "build.rs" diff --git a/README.md b/README.md index cb9d610..7567f93 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The **`dolby_vision`** crate is also hosted in this repo, see [README](dolby_vis ## **Building** ### **Toolchain** -The minimum Rust version to build **`dovi_tool`** is 1.56.0. +The minimum Rust version to build **`dovi_tool`** is 1.58.0. ### **Release binary** To build release binary in `target/release/dovi_tool` run: @@ -43,8 +43,11 @@ dovi_tool --help **`dovi_tool`** provides an important set of tools for analyzing, editing and generating Dolby Vision metadata. ## **Commands** * ### **info** - Prints the parsed RPU data as JSON for a specific frame. - Frame indices start at 0. + Prints the parsed RPU information. + To get the summary, use `--summary` or `-s`. + + Using `--frame`: prints the RPU data as JSON for a specific frame. + - Frame indices start at 0. **Example to get metadata for frame 124**: ```console diff --git a/src/commands/info.rs b/src/commands/info.rs index 283f7ac..e7e77b0 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -30,4 +30,7 @@ pub struct InfoArgs { help = "Frame number to show info for" )] pub frame: Option, + + #[clap(name = "summary", long, short = 's', help = "Show the RPU summary")] + pub summary: bool, } diff --git a/src/dovi/rpu_info.rs b/src/dovi/rpu_info.rs index 2d7e3f7..03c5850 100644 --- a/src/dovi/rpu_info.rs +++ b/src/dovi/rpu_info.rs @@ -1,3 +1,4 @@ +use std::fmt::Write as FmtWrite; use std::io::{stdout, Write}; use std::path::PathBuf; @@ -11,7 +12,6 @@ use crate::commands::InfoArgs; pub struct RpuInfo { input: PathBuf, - frame: Option, rpus: Option>, } @@ -21,19 +21,16 @@ impl RpuInfo { input, input_pos, frame, + summary, } = args; - if frame.is_none() { + if !summary && frame.is_none() { bail!("No frame number to look up"); } let input = input_from_either("info", input, input_pos)?; - let mut info = RpuInfo { - input, - frame, - rpus: None, - }; + let mut info = RpuInfo { input, rpus: None }; println!("Parsing RPU file..."); stdout().flush().ok(); @@ -41,19 +38,75 @@ impl RpuInfo { info.rpus = parse_rpu_file(&info.input)?; if let Some(ref rpus) = info.rpus { - let f = info.frame.unwrap(); - ensure!( - f < rpus.len(), - format!( - "info: invalid frame number (out of range).\nNumber of valid RPUs parsed: {}", - rpus.len() - ) - ); - - let rpu = &rpus[f]; - - if let Ok(rpu_serialized) = serde_json::to_string_pretty(&rpu) { - println!("{}", rpu_serialized); + if let Some(f) = frame { + ensure!( + f < rpus.len(), + format!( + "info: invalid frame number (out of range).\nNumber of valid RPUs parsed: {}", + rpus.len() + ) + ); + + let rpu = &rpus[f]; + + if let Ok(rpu_serialized) = serde_json::to_string_pretty(&rpu) { + println!("{}", rpu_serialized); + } + } + + if summary { + let count = rpus.len(); + + let dmv1_count = rpus + .iter() + .filter(|rpu| { + rpu.vdr_dm_data + .as_ref() + .and_then(|vdr| vdr.cmv29_metadata.as_ref()) + .is_some() + }) + .count(); + let dmv2_count = rpus + .iter() + .filter(|rpu| { + rpu.vdr_dm_data + .as_ref() + .and_then(|vdr| vdr.cmv40_metadata.as_ref()) + .is_some() + }) + .count(); + + let (needs_count, dm_version) = if dmv2_count == dmv1_count { + (false, "2 (CM v4.x)") + } else if dmv2_count == 0 { + (false, "1 (CM v2.9)") + } else { + (true, "1 + 2 (CM 2.9 and 4.x)") + }; + + let scene_count = rpus + .iter() + .filter(|rpu| { + rpu.vdr_dm_data + .as_ref() + .and_then(|vdr| (vdr.scene_refresh_flag == 1).then(|| 1)) + .is_some() + }) + .count(); + + let mut summary_str = + format!("Summary:\n Frmaes: {count}\n DM version: {dm_version}"); + + if needs_count { + write!( + summary_str, + "\n v2.9 count: {dmv1_count}\n v4.x count: {dmv2_count}" + )?; + } + + write!(summary_str, "\n Scene/shot count: {scene_count}")?; + + println!("\n{}", summary_str) } }