Skip to content
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
Binary file added assets/tests/level253-ext-metadata.bin
Binary file not shown.
4 changes: 4 additions & 0 deletions dolby_vision/examples/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ int process_dm_metadata(DoviRpuOpaque *rpu, const DoviRpuDataHeader *header) {
meta->content_type, (meta->whitepoint * 375) + 6504, meta->reference_mode_flag);
}

if (vdr_dm_data->dm_data.level253) {
printf(" L253 filler bytes: %d bytes\n", vdr_dm_data->dm_data.level253->len);
}

if (vdr_dm_data->dm_data.level254) {
const DoviExtMetadataBlockLevel254 *meta = vdr_dm_data->dm_data.level254;

Expand Down
13 changes: 13 additions & 0 deletions dolby_vision/src/c_structs/extension_metadata.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use libc::size_t;
use std::ptr::null;

use crate::c_structs::Freeable;
use crate::rpu::extension_metadata::DmData as RuDmData;
use crate::rpu::extension_metadata::WithExtMetadataBlocks;
use crate::rpu::extension_metadata::blocks::*;
use crate::rpu::vdr_dm_data::CmVersion;

use super::Data;

/// C struct for the list of ext_metadata_block()
#[repr(C)]
pub struct DmData {
Expand All @@ -22,6 +25,7 @@ pub struct DmData {
level9: *const ExtMetadataBlockLevel9,
level10: Level10BlockList,
level11: *const ExtMetadataBlockLevel11,
level253: *const Data,
level254: *const ExtMetadataBlockLevel254,
level255: *const ExtMetadataBlockLevel255,
}
Expand Down Expand Up @@ -106,6 +110,10 @@ impl DmData {
self.level11 =
Box::into_raw(Box::new(b.clone())) as *const ExtMetadataBlockLevel11
}
ExtMetadataBlock::Level253(b) => {
self.level253 =
Box::into_raw(Box::new(Data::from(b.bytes.clone()))) as *const Data;
}
ExtMetadataBlock::Level254(b) => {
self.level254 =
Box::into_raw(Box::new(b.clone())) as *const ExtMetadataBlockLevel254
Expand Down Expand Up @@ -156,6 +164,10 @@ impl DmData {
if !self.level11.is_null() {
drop(Box::from_raw(self.level11 as *mut ExtMetadataBlockLevel11));
}
if !self.level253.is_null() {
let data = Box::from_raw(self.level253 as *mut Data);
data.free();
}
if !self.level254.is_null() {
drop(Box::from_raw(
self.level254 as *mut ExtMetadataBlockLevel254,
Expand Down Expand Up @@ -184,6 +196,7 @@ impl Default for DmData {
level9: null(),
level10: Default::default(),
level11: null(),
level253: null(),
level254: null(),
level255: null(),
}
Expand Down
57 changes: 57 additions & 0 deletions dolby_vision/src/rpu/extension_metadata/blocks/level253.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use anyhow::{Result, ensure};
use bitvec_helpers::{
bitstream_io_reader::BsIoSliceReader, bitstream_io_writer::BitstreamIoWriter,
};

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use super::{ExtMetadataBlock, ExtMetadataBlockInfo};

// Unknown - filler bytes?
#[repr(C)]
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct ExtMetadataBlockLevel253 {
pub bytes: Vec<u8>,
}

pub const LEVEL253_FILLER_BYTE: u8 = 0x55;

impl ExtMetadataBlockLevel253 {
pub(crate) fn parse(reader: &mut BsIoSliceReader, length: u64) -> Result<ExtMetadataBlock> {
ensure!(length <= 66, "Level 253 block should be at most 66 bytes");

let mut bytes = vec![0; length as usize];
reader.read_bytes(&mut bytes)?;

Ok(ExtMetadataBlock::Level253(Self { bytes }))
}

pub fn validate(&self) -> Result<()> {
ensure!(self.bytes.iter().all(|e| *e == LEVEL253_FILLER_BYTE));

Ok(())
}

pub fn write(&self, writer: &mut BitstreamIoWriter) -> Result<()> {
writer.write_bytes(&self.bytes)?;

Ok(())
}
}

impl ExtMetadataBlockInfo for ExtMetadataBlockLevel253 {
fn level(&self) -> u8 {
253
}

fn bytes_size(&self) -> u64 {
self.bytes.len() as u64
}

fn required_bits(&self) -> u64 {
self.bytes_size() * 8
}
}
10 changes: 10 additions & 0 deletions dolby_vision/src/rpu/extension_metadata/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod level1;
pub mod level10;
pub mod level11;
pub mod level2;
pub mod level253;
pub mod level254;
pub mod level255;
pub mod level3;
Expand All @@ -30,6 +31,7 @@ pub use level8::ExtMetadataBlockLevel8;
pub use level9::ExtMetadataBlockLevel9;
pub use level10::ExtMetadataBlockLevel10;
pub use level11::ExtMetadataBlockLevel11;
pub use level253::ExtMetadataBlockLevel253;
pub use level254::ExtMetadataBlockLevel254;
pub use level255::ExtMetadataBlockLevel255;
pub use reserved::ReservedExtMetadataBlock;
Expand All @@ -52,6 +54,7 @@ pub enum ExtMetadataBlock {
Level9(ExtMetadataBlockLevel9),
Level10(ExtMetadataBlockLevel10),
Level11(ExtMetadataBlockLevel11),
Level253(ExtMetadataBlockLevel253),
Level254(ExtMetadataBlockLevel254),
Level255(ExtMetadataBlockLevel255),
Reserved(ReservedExtMetadataBlock),
Expand Down Expand Up @@ -84,6 +87,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.bytes_size(),
ExtMetadataBlock::Level10(b) => b.bytes_size(),
ExtMetadataBlock::Level11(b) => b.bytes_size(),
ExtMetadataBlock::Level253(b) => b.bytes_size(),
ExtMetadataBlock::Level254(b) => b.bytes_size(),
ExtMetadataBlock::Level255(b) => b.bytes_size(),
ExtMetadataBlock::Reserved(b) => b.bytes_size(),
Expand All @@ -102,6 +106,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.bits_size(),
ExtMetadataBlock::Level10(b) => b.bits_size(),
ExtMetadataBlock::Level11(b) => b.bits_size(),
ExtMetadataBlock::Level253(b) => b.bits_size(),
ExtMetadataBlock::Level254(b) => b.bits_size(),
ExtMetadataBlock::Level255(b) => b.bits_size(),
ExtMetadataBlock::Reserved(b) => b.bits_size(),
Expand All @@ -120,6 +125,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.required_bits(),
ExtMetadataBlock::Level10(b) => b.required_bits(),
ExtMetadataBlock::Level11(b) => b.required_bits(),
ExtMetadataBlock::Level253(b) => b.required_bits(),
ExtMetadataBlock::Level254(b) => b.required_bits(),
ExtMetadataBlock::Level255(b) => b.required_bits(),
ExtMetadataBlock::Reserved(b) => b.required_bits(),
Expand All @@ -138,6 +144,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.level(),
ExtMetadataBlock::Level10(b) => b.level(),
ExtMetadataBlock::Level11(b) => b.level(),
ExtMetadataBlock::Level253(b) => b.level(),
ExtMetadataBlock::Level254(b) => b.level(),
ExtMetadataBlock::Level255(b) => b.level(),
ExtMetadataBlock::Reserved(b) => b.level(),
Expand All @@ -156,6 +163,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.sort_key(),
ExtMetadataBlock::Level10(b) => b.sort_key(),
ExtMetadataBlock::Level11(b) => b.sort_key(),
ExtMetadataBlock::Level253(b) => b.sort_key(),
ExtMetadataBlock::Level254(b) => b.sort_key(),
ExtMetadataBlock::Level255(b) => b.sort_key(),
ExtMetadataBlock::Reserved(b) => b.sort_key(),
Expand All @@ -174,6 +182,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.write(writer),
ExtMetadataBlock::Level10(b) => b.write(writer),
ExtMetadataBlock::Level11(b) => b.write(writer),
ExtMetadataBlock::Level253(b) => b.write(writer),
ExtMetadataBlock::Level254(b) => b.write(writer),
ExtMetadataBlock::Level255(b) => b.write(writer),
ExtMetadataBlock::Reserved(b) => b.write(writer),
Expand Down Expand Up @@ -232,6 +241,7 @@ impl ExtMetadataBlock {
ExtMetadataBlock::Level9(b) => b.serialize(serializer),
ExtMetadataBlock::Level10(b) => b.serialize(serializer),
ExtMetadataBlock::Level11(b) => b.serialize(serializer),
ExtMetadataBlock::Level253(b) => b.serialize(serializer),
ExtMetadataBlock::Level254(b) => b.serialize(serializer),
ExtMetadataBlock::Level255(b) => b.serialize(serializer),
ExtMetadataBlock::Reserved(b) => b.serialize(serializer),
Expand Down
3 changes: 2 additions & 1 deletion dolby_vision/src/rpu/extension_metadata/cmv40.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct CmV40DmData {

impl WithExtMetadataBlocks for CmV40DmData {
const VERSION: &'static str = "CM v4.0";
const ALLOWED_BLOCK_LEVELS: &'static [u8] = &[3, 8, 9, 10, 11, 254];
const ALLOWED_BLOCK_LEVELS: &'static [u8] = &[3, 8, 9, 10, 11, 253, 254];

fn with_blocks_allocation(num_ext_blocks: u64) -> Self {
Self {
Expand Down Expand Up @@ -51,6 +51,7 @@ impl WithExtMetadataBlocks for CmV40DmData {
9 => level9::ExtMetadataBlockLevel9::parse(reader, ext_block_length)?,
10 => level10::ExtMetadataBlockLevel10::parse(reader, ext_block_length)?,
11 => level11::ExtMetadataBlockLevel11::parse(reader)?,
253 => level253::ExtMetadataBlockLevel253::parse(reader, ext_block_length)?,
254 => level254::ExtMetadataBlockLevel254::parse(reader)?,
1 | 2 | 4 | 5 | 6 | 255 => bail!("Disallowed block level {}", ext_block_level),
_ => {
Expand Down
1 change: 1 addition & 0 deletions dolby_vision/src/rpu/vdr_dm_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ impl VdrDmData {
}
}
ExtMetadataBlock::Level11(_) => self.replace_metadata_level(block),
ExtMetadataBlock::Level253(_) => self.replace_metadata_level(block),
ExtMetadataBlock::Level254(_) => self.replace_metadata_level(block),
ExtMetadataBlock::Level255(_) => self.replace_metadata_level(block),
ExtMetadataBlock::Reserved(_) => bail!("Cannot replace specific reserved block"),
Expand Down
1 change: 1 addition & 0 deletions src/dovi/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ impl<'a> Serialize for CsvHeaders<'a> {
ExtMetadataBlock::Level9(b) => json!(b),
ExtMetadataBlock::Level10(b) => json!(b),
ExtMetadataBlock::Level11(b) => json!(b),
ExtMetadataBlock::Level253(b) => json!(b),
ExtMetadataBlock::Level254(b) => json!(b),
ExtMetadataBlock::Level255(b) => json!(b),
ExtMetadataBlock::Reserved(b) => json!(b),
Expand Down
23 changes: 23 additions & 0 deletions src/tests/rpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,3 +1145,26 @@ fn profile20_apple() -> Result<()> {

Ok(())
}

#[test]
fn level253_ext_metadata() -> Result<()> {
let (original_data, dovi_rpu) =
_parse_file(PathBuf::from("./assets/tests/level253-ext-metadata.bin"))?;
assert_eq!(dovi_rpu.dovi_profile, 5);

let vdr_dm_data = dovi_rpu.vdr_dm_data.as_ref().unwrap();

let l253_meta = vdr_dm_data.get_block(253).unwrap();
assert_eq!(l253_meta.length_bytes(), 2);
assert_eq!(l253_meta.length_bits(), 16);

if let ExtMetadataBlock::Level253(b) = l253_meta {
assert_eq!(b.bytes, vec![0x55; 2]);
}

let parsed_data = dovi_rpu.write_hevc_unspec62_nalu()?;

assert_eq!(&original_data[4..], &parsed_data[2..]);

Ok(())
}