Skip to content

Commit 4aecd2b

Browse files
committed
Fix parsing Level5
Choose most common per-shot image aspect ratio as global image aspect ratio
1 parent 220ef2c commit 4aecd2b

File tree

4 files changed

+35
-73
lines changed

4 files changed

+35
-73
lines changed

src/functions/convert.rs

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::io::{BufWriter, Write};
44

55
use anyhow::{bail, ensure, Result};
66
use dolby_vision::rpu::utils::parse_rpu_file;
7-
use itertools::{Itertools, MinMaxResult};
87
use quick_xml::events::Event;
98
use quick_xml::se::Serializer;
109
use quick_xml::{Reader, Writer};
@@ -15,9 +14,7 @@ use crate::commands::convert::ConvertArgs;
1514
use crate::metadata::levels::Level11;
1615
use crate::metadata::levels::Level5;
1716
use crate::MDFType::{CMV29, CMV40};
18-
use crate::{
19-
cmv40, display, IntoCMV29, Level254, Level6, UHD_AR, UHD_HEIGHT, UHD_WIDTH, XML_PREFIX,
20-
};
17+
use crate::{cmv40, display, IntoCMV29, Level254, Level6, XML_PREFIX};
2118

2219
#[derive(Debug, Default)]
2320
pub struct Converter {
@@ -195,7 +192,9 @@ impl Converter {
195192
*level11_map.entry(&shot.plugin_node.level11).or_insert(0) += 1_usize;
196193
});
197194

198-
converter.level5 = Some(Self::get_global_ar(level5_map, canvas));
195+
// converter.level5 = Some(Self::get_global_ar(level5_map, canvas));
196+
converter.level5 =
197+
Self::get_common(level5_map).or_else(|| Some(Level5::with_canvas(None, canvas)));
199198

200199
// Choose the most common level11 as track-level metadata,
201200
converter.level11 = Self::get_common(level11_map);
@@ -257,57 +256,13 @@ impl Converter {
257256
}
258257

259258
/// None: Standard UHD
260-
fn parse_canvas_ar(vec: Vec<usize>) -> Result<Option<(usize, usize)>> {
259+
fn parse_canvas_ar(vec: Vec<usize>) -> Result<(usize, usize)> {
261260
ensure!(
262261
vec.len() == 2,
263262
"Invalid canvas size. Use 'x' as delimiter, like 3840x2160"
264263
);
265264
ensure!(vec[0] != 0 && vec[1] != 0, "Invalid canvas size.");
266-
let canvas = (vec[0], vec[1]);
267-
let canvas = if canvas == (UHD_WIDTH, UHD_HEIGHT) {
268-
None
269-
} else {
270-
Some(canvas)
271-
};
272-
273-
// stdout().flush().ok();
274-
275-
Ok(canvas)
276-
}
277-
278-
fn get_global_ar(
279-
map: HashMap<&Option<Level5>, usize>,
280-
canvas: Option<(usize, usize)>,
281-
) -> Level5 {
282-
let canvas_ar = match canvas {
283-
Some((width, height)) => width as f32 / height as f32,
284-
None => UHD_AR,
285-
};
286-
287-
let minmax = map
288-
.into_iter()
289-
.filter(|(value, _)| value.is_some())
290-
.map(|(value, _)| value.clone().unwrap())
291-
.minmax();
292-
293-
match minmax {
294-
MinMaxResult::NoElements => Level5::from(canvas_ar),
295-
MinMaxResult::OneElement(b) => b,
296-
MinMaxResult::MinMax(b_min, b_max) => {
297-
let b_canvas = Level5::from(canvas_ar);
298-
// if b_min > b_canvas {
299-
// // all letterbox types are up/bottom
300-
// b_min
301-
// } else if b_max < b_canvas {
302-
// // all letterbox types are left/right
303-
// b_max
304-
// } else {
305-
// // Mixed type, or no letterbox
306-
// b_canvas
307-
// }
308-
b_canvas.clamp(b_min, b_max)
309-
}
310-
}
265+
Ok((vec[0], vec[1]))
311266
}
312267

313268
fn get_common<K, V>(map: HashMap<&Option<K>, V>) -> Option<K>

src/metadata/cmv40/shot.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl Shot {
3737
}
3838
}
3939

40-
pub fn with_canvas(vdr: &VdrDmData, canvas: Option<(usize, usize)>) -> Self {
40+
pub fn with_canvas(vdr: &VdrDmData, canvas: (usize, usize)) -> Self {
4141
Self {
4242
unique_id: UUIDv4::new(),
4343
record: Default::default(),
@@ -67,7 +67,7 @@ impl Shot {
6767

6868
impl From<&VdrDmData> for Shot {
6969
fn from(vdr: &VdrDmData) -> Self {
70-
Self::with_canvas(vdr, None)
70+
Self::with_canvas(vdr, UHD_CANVAS)
7171
}
7272
}
7373

@@ -94,7 +94,7 @@ pub struct ShotPluginNode {
9494
}
9595

9696
impl ShotPluginNode {
97-
fn with_canvas(vdr: &VdrDmData, canvas: Option<(usize, usize)>) -> Self {
97+
fn with_canvas(vdr: &VdrDmData, canvas: (usize, usize)) -> Self {
9898
let level11 = vdr.get_block(11).and_then(|b| match b {
9999
ExtMetadataBlock::Level11(b) => Some(Level11::from(b)),
100100
_ => None,
@@ -109,7 +109,7 @@ impl ShotPluginNode {
109109

110110
impl From<&VdrDmData> for ShotPluginNode {
111111
fn from(vdr: &VdrDmData) -> Self {
112-
Self::with_canvas(vdr, None)
112+
Self::with_canvas(vdr, UHD_CANVAS)
113113
}
114114
}
115115

@@ -135,7 +135,7 @@ pub struct DVDynamicData {
135135
}
136136

137137
impl DVDynamicData {
138-
pub fn with_canvas(vdr: &VdrDmData, canvas: Option<(usize, usize)>) -> Self {
138+
pub fn with_canvas(vdr: &VdrDmData, canvas: (usize, usize)) -> Self {
139139
let level1 = if let Some(ExtMetadataBlock::Level1(block)) = vdr.get_block(1) {
140140
Level1::from(block)
141141
} else {
@@ -165,13 +165,14 @@ impl DVDynamicData {
165165
_ => None,
166166
});
167167

168-
let level5 = vdr.get_block(5).and_then(|b| match b {
169-
ExtMetadataBlock::Level5(b) => match canvas {
170-
Some(canvas) => Some(Level5::with_canvas(b, canvas)),
171-
None => Some(Level5::from(b)),
172-
},
173-
_ => None,
174-
});
168+
let level5 = {
169+
let b = vdr.get_block(5).and_then(|b| match b {
170+
ExtMetadataBlock::Level5(b) => Some(b),
171+
_ => None,
172+
});
173+
174+
Some(Level5::with_canvas(b, canvas))
175+
};
175176

176177
let level8 = vdr
177178
.level_blocks_iter(8)
@@ -194,7 +195,7 @@ impl DVDynamicData {
194195

195196
impl From<&VdrDmData> for DVDynamicData {
196197
fn from(vdr: &VdrDmData) -> Self {
197-
Self::with_canvas(vdr, None)
198+
Self::with_canvas(vdr, UHD_CANVAS)
198199
}
199200
}
200201

src/metadata/levels/level5.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use dolby_vision::rpu::extension_metadata::blocks::ExtMetadataBlockLevel5;
22
use serde::Serialize;
33
use std::cmp::Ordering;
44

5+
use crate::metadata::levels::UHD_CANVAS;
56
use crate::MDFType::CMV40;
6-
use crate::{IntoCMV29, MDFType, UHD_HEIGHT, UHD_WIDTH};
7+
use crate::{IntoCMV29, MDFType};
78

89
use super::AspectRatio;
910

@@ -26,7 +27,7 @@ impl Level5 {
2627
// For convenience, it assumes the canvas is standard UHD
2728
impl From<&ExtMetadataBlockLevel5> for Level5 {
2829
fn from(block: &ExtMetadataBlockLevel5) -> Self {
29-
Self::with_canvas(block, (UHD_WIDTH, UHD_HEIGHT))
30+
Self::with_canvas(Some(block), UHD_CANVAS)
3031
}
3132
}
3233

@@ -49,18 +50,22 @@ impl IntoCMV29<Self> for Level5 {
4950
}
5051

5152
impl Level5 {
52-
pub fn with_canvas(block: &ExtMetadataBlockLevel5, canvas: (usize, usize)) -> Self {
53+
pub fn with_canvas(block: Option<&ExtMetadataBlockLevel5>, canvas: (usize, usize)) -> Self {
5354
let (width, height) = canvas;
5455
let canvas_ar = width as f32 / height as f32;
5556

56-
let horizontal_crop = block.active_area_left_offset + block.active_area_right_offset;
57-
let vertical_crop = block.active_area_top_offset + block.active_area_bottom_offset;
57+
let image_ar = if let Some(block) = block {
58+
let horizontal_crop = block.active_area_left_offset + block.active_area_right_offset;
59+
let vertical_crop = block.active_area_top_offset + block.active_area_bottom_offset;
5860

59-
let image_ar = if horizontal_crop > 0 {
60-
(width as f32 - horizontal_crop as f32) / height as f32
61+
if horizontal_crop > 0 {
62+
(width as f32 - horizontal_crop as f32) / height as f32
63+
} else {
64+
// Ok because only one of the crop types will be 0
65+
width as f32 / (height as f32 - vertical_crop as f32)
66+
}
6167
} else {
62-
// Ok because only one of the crop types will be 0
63-
width as f32 / (height as f32 - vertical_crop as f32)
68+
canvas_ar
6469
};
6570

6671
Self {

src/metadata/levels/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub const RPU_U8_BIAS: f32 = 128.0;
3333
pub const RPU_U12_BIAS: f32 = 2048.0;
3434
pub const UHD_WIDTH: usize = 3840;
3535
pub const UHD_HEIGHT: usize = 2160;
36+
pub const UHD_CANVAS: (usize, usize) = (UHD_WIDTH, UHD_HEIGHT);
3637
pub const UHD_AR: f32 = 16.0 / 9.0;
3738

3839
pub fn f32_from_rpu_u12_with_bias(u: u16) -> f32 {

0 commit comments

Comments
 (0)