diff --git a/symphonia-format-mkv/src/codecs.rs b/symphonia-format-mkv/src/codecs.rs index ee9a4144..cca3bae2 100644 --- a/symphonia-format-mkv/src/codecs.rs +++ b/symphonia-format-mkv/src/codecs.rs @@ -7,7 +7,8 @@ use extra_data::{ VIDEO_EXTRA_DATA_ID_AV1_DECODER_CONFIG, VIDEO_EXTRA_DATA_ID_AVC_DECODER_CONFIG, - VIDEO_EXTRA_DATA_ID_HEVC_DECODER_CONFIG, VIDEO_EXTRA_DATA_ID_VP9_DECODER_CONFIG, + VIDEO_EXTRA_DATA_ID_DOLBY_VISION_CONFIG, VIDEO_EXTRA_DATA_ID_HEVC_DECODER_CONFIG, + VIDEO_EXTRA_DATA_ID_VP9_DECODER_CONFIG, }; use log::warn; @@ -138,6 +139,15 @@ fn make_video_codec_params( codec_params.add_extra_data(VideoExtraData { id: extra_data_id, data: codec_private }); } + if let Some(block_addition_mapping) = track.block_addition_mapping { + if let Some(dvvc_data) = block_addition_mapping.dvvc_data { + codec_params.add_extra_data(VideoExtraData { + id: VIDEO_EXTRA_DATA_ID_DOLBY_VISION_CONFIG, + data: dvvc_data, + }); + } + } + Ok(Some(CodecParameters::Video(codec_params))) } diff --git a/symphonia-format-mkv/src/element_ids.rs b/symphonia-format-mkv/src/element_ids.rs index 858c36ff..f65603bc 100644 --- a/symphonia-format-mkv/src/element_ids.rs +++ b/symphonia-format-mkv/src/element_ids.rs @@ -54,6 +54,7 @@ pub enum ElementType { BlockMore, BlockAddId, BlockAdditional, + BlockAdditionMapping, BlockDuration, ReferenceBlock, DiscardPadding, @@ -93,6 +94,7 @@ pub enum ElementType { DisplayHeight, DisplayUnit, AspectRatioType, + DolbyVisionConfiguration, Audio, SamplingFrequency, OutputSamplingFrequency, @@ -219,6 +221,7 @@ lazy_static! { elems.insert(0xA6, (Type::Master, ElementType::BlockMore)); elems.insert(0xEE, (Type::Unsigned, ElementType::BlockAddId)); elems.insert(0xA5, (Type::Binary, ElementType::BlockAdditional)); + elems.insert(0x41E4, (Type::Binary, ElementType::BlockAdditionMapping)); elems.insert(0x9B, (Type::Unsigned, ElementType::BlockDuration)); elems.insert(0xFB, (Type::Signed, ElementType::ReferenceBlock)); elems.insert(0x75A2, (Type::Signed, ElementType::DiscardPadding)); @@ -258,6 +261,7 @@ lazy_static! { elems.insert(0x54BA, (Type::Unsigned, ElementType::DisplayHeight)); elems.insert(0x54B2, (Type::Unsigned, ElementType::DisplayUnit)); elems.insert(0x54B3, (Type::Unsigned, ElementType::AspectRatioType)); + elems.insert(0x41ED, (Type::Binary, ElementType::DolbyVisionConfiguration)); elems.insert(0xE1, (Type::Master, ElementType::Audio)); elems.insert(0xB5, (Type::Float, ElementType::SamplingFrequency)); elems.insert(0x78B5, (Type::Float, ElementType::OutputSamplingFrequency)); diff --git a/symphonia-format-mkv/src/segment.rs b/symphonia-format-mkv/src/segment.rs index a0c84eab..67ef14c0 100644 --- a/symphonia-format-mkv/src/segment.rs +++ b/symphonia-format-mkv/src/segment.rs @@ -21,6 +21,7 @@ pub(crate) struct TrackElement { pub(crate) language: Option, pub(crate) codec_id: String, pub(crate) codec_private: Option>, + pub(crate) block_addition_mapping: Option, pub(crate) audio: Option, pub(crate) video: Option, pub(crate) default_duration: Option, @@ -36,6 +37,7 @@ impl Element for TrackElement { let mut audio = None; let mut video = None; let mut codec_private = None; + let mut block_addition_mapping = None; let mut codec_id = None; let mut default_duration = None; @@ -63,6 +65,9 @@ impl Element for TrackElement { ElementType::Video => { video = Some(it.read_element_data()?); } + ElementType::BlockAdditionMapping => { + block_addition_mapping = Some(it.read_element_data()?); + } ElementType::DefaultDuration => { default_duration = Some(it.read_u64()?); } @@ -78,6 +83,7 @@ impl Element for TrackElement { language, codec_id: codec_id.ok_or(Error::DecodeError("mkv: missing codec id"))?, codec_private, + block_addition_mapping, audio, video, default_duration, @@ -166,6 +172,33 @@ impl Element for VideoElement { } } +#[derive(Debug)] +pub(crate) struct BlockAdditionMappingElement { + pub(crate) dvvc_data: Option>, +} + +impl Element for BlockAdditionMappingElement { + const ID: ElementType = ElementType::BlockAdditionMapping; + + fn read(reader: &mut B, header: ElementHeader) -> Result { + let mut dvvc_data = None; + + let mut it = header.children(reader); + while let Some(header) = it.read_header()? { + match header.etype { + ElementType::DolbyVisionConfiguration => { + dvvc_data = Some(it.read_boxed_slice()?); + } + other => { + log::debug!("ignored element {:?}", other); + } + } + } + + Ok(Self { dvvc_data }) + } +} + #[derive(Debug)] pub(crate) struct SeekHeadElement { pub(crate) seeks: Box<[SeekElement]>,