Skip to content

Add L2/L8 plots and extend summary info/plots with L5 offsets, L8 trims, and L9 MDP #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dolby_vision/src/rpu/extension_metadata/blocks/level5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const MAX_RESOLUTION_13_BITS: u16 = 8191;

/// Active area of the picture (letterbox, aspect ratio)
#[repr(C)]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ExtMetadataBlockLevel5 {
pub active_area_left_offset: u16,
Expand Down
12 changes: 12 additions & 0 deletions dolby_vision/src/rpu/extension_metadata/blocks/level8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ impl ExtMetadataBlockLevel8 {

Ok(())
}

pub fn trim_target_nits(&self) -> u16 {
match self.target_display_index {
16 | 18 | 21 => 48,
42 => 108,
24 | 25 => 300,
27 | 28 => 600,
48 | 49 => 1000,
37 | 38 => 2000,
_ => 100,
}
}
}

impl ExtMetadataBlockInfo for ExtMetadataBlockLevel8 {
Expand Down
34 changes: 34 additions & 0 deletions dolby_vision/src/rpu/extension_metadata/primaries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,40 @@ pub enum MasteringDisplayPrimaries {
SGamut3Cine,
}

impl From<u8> for MasteringDisplayPrimaries {
fn from(value: u8) -> Self {
match value {
0 => Self::DCIP3D65,
1 => Self::BT709,
2 => Self::BT2020,
3 => Self::SMPTEC,
4 => Self::BT601,
5 => Self::DCIP3,
6 => Self::ACES,
7 => Self::SGamut,
8 => Self::SGamut3Cine,
_ => Self::DCIP3D65,
}
}
}

impl std::fmt::Display for MasteringDisplayPrimaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let alias = match self {
Self::DCIP3D65 => "DCI-P3 D65",
Self::BT709 => "BT.709",
Self::BT2020 => "BT.2020",
Self::SMPTEC => "SMPTE-C",
Self::BT601 => "BT.601",
Self::DCIP3 => "DCI-P3",
Self::ACES => "ACES",
Self::SGamut => "S-Gamut",
Self::SGamut3Cine => "S-Gamut-3.Cine",
};
write!(f, "{}", alias)
}
}

impl ColorPrimaries {
pub fn from_array_int(primaries: &[u16; 8]) -> ColorPrimaries {
Self {
Expand Down
6 changes: 6 additions & 0 deletions dolby_vision/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ pub fn nits_to_pq(nits: f64) -> f64 {
.powf(ST2084_M2)
}

/// Helper function to calculate PQ codes from nits (cd/m2) values
#[inline(always)]
pub fn nits_to_pq_12_bit(nits: f64) -> u16 {
(nits_to_pq(nits) * 4095.0).round() as u16
}

/// Copied from hevc_parser for convenience, and to avoid a dependency
/// Unescapes a byte slice from annexb.
/// Allocates a new Vec.
Expand Down
2 changes: 1 addition & 1 deletion src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub enum Commands {
#[command(about = "Interleaves the enhancement layer into a base layer HEVC bitstream")]
Mux(MuxArgs),

#[command(about = "Plot the L1 dynamic brightness metadata")]
#[command(about = "Plot the L1/L2/L8 metadata")]
Plot(PlotArgs),

#[command(about = "Removes the enhancement layer and RPU data from the video")]
Expand Down
26 changes: 26 additions & 0 deletions src/commands/plot.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::dovi::plotter::{PlotType, TrimsFilter};
use clap::{Args, ValueHint};
use std::path::PathBuf;

Expand Down Expand Up @@ -39,4 +40,29 @@ pub struct PlotArgs {

#[arg(long, short = 'e', help = "Set frame range end (inclusive)")]
pub end: Option<usize>,

#[arg(
long,
short = 'p',
help = "Sets the DV metadata level to plot",
value_enum,
default_value = "l1"
)]
pub plot_type: PlotType,

#[arg(
long = "target-nits",
help = "Target brightness in nits for L2/L8 plots",
default_value = "100",
value_parser = ["100", "300", "600", "1000"]
)]
pub target_nits_str: String,

#[arg(
long,
help = "Parameters to exclude from L2/L8 trims plots\nSupports multiple occurrences prefixed by --trims-filter or delimited by ','",
value_enum,
value_delimiter = ','
)]
pub trims_filter: Vec<TrimsFilter>,
}
Loading