mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-13 14:12:31 +00:00
EBML: Support locking at multiple depths
This commit is contained in:
parent
1c30150836
commit
761b37f655
8 changed files with 218 additions and 140 deletions
|
@ -107,7 +107,7 @@ ebml_master_elements! {
|
|||
Segment: {
|
||||
id: 0x1853_8067,
|
||||
children: [
|
||||
SeekHead: { 0x114D_9B74, Master },
|
||||
// SeekHead: { 0x114D_9B74, Master },
|
||||
Info: { 0x1549_A966, Master },
|
||||
Cluster: { 0x1F43_B675, Master },
|
||||
Tracks: { 0x1654_AE6B, Master },
|
||||
|
@ -118,12 +118,12 @@ ebml_master_elements! {
|
|||
},
|
||||
|
||||
// segment.seekHead
|
||||
SeekHead: {
|
||||
id: 0x114D_9B74,
|
||||
children: [
|
||||
Seek: { 0x4DBB, Master },
|
||||
],
|
||||
},
|
||||
// SeekHead: {
|
||||
// id: 0x114D_9B74,
|
||||
// children: [
|
||||
// Seek: { 0x4DBB, Master },
|
||||
// ],
|
||||
// },
|
||||
|
||||
// segment.info
|
||||
Info: {
|
||||
|
@ -190,6 +190,33 @@ ebml_master_elements! {
|
|||
],
|
||||
},
|
||||
|
||||
// segment.tags.tag.targets
|
||||
Targets: {
|
||||
id: 0x63C0,
|
||||
children: [
|
||||
TargetTypeValue: { 0x68CA, UnsignedInt },
|
||||
TargetType: { 0x63CA, String },
|
||||
TagTrackUID: { 0x63C5, UnsignedInt },
|
||||
TagEditionUID: { 0x63C9, UnsignedInt },
|
||||
TagChapterUID: { 0x63C4, UnsignedInt },
|
||||
TagAttachmentUID: { 0x63C6, UnsignedInt },
|
||||
],
|
||||
},
|
||||
|
||||
// segment.tags.tag.simpleTag
|
||||
SimpleTag: {
|
||||
id: 0x67C8,
|
||||
children: [
|
||||
TagName: { 0x45A3, Utf8 },
|
||||
TagLanguage: { 0x447A, String },
|
||||
TagLanguageBCP47: { 0x447B, String },
|
||||
TagDefault: { 0x4484, UnsignedInt },
|
||||
TagDefaultBogus: { 0x44B4, UnsignedInt },
|
||||
TagString: { 0x4487, Utf8 },
|
||||
TagBinary: { 0x4485, Binary },
|
||||
],
|
||||
},
|
||||
|
||||
// segment.attachments
|
||||
Attachments: {
|
||||
id: 0x1941_A469,
|
||||
|
@ -235,8 +262,13 @@ struct ElementReaderContext {
|
|||
/// This is set with [`ElementReader::lock`], and is used to prevent
|
||||
/// the reader from reading past the end of the current master element.
|
||||
locked: bool,
|
||||
/// The depth at which we are locked to
|
||||
lock_depth: u8,
|
||||
/// The depths at which we are locked
|
||||
///
|
||||
/// When we reach the end of one lock and unlock the reader, we need
|
||||
/// to know which depth to lock the reader at again (if any).
|
||||
///
|
||||
/// This will **always** be sorted, so the current lock will be at the end.
|
||||
lock_depths: Vec<u8>,
|
||||
lock_len: VInt,
|
||||
}
|
||||
|
||||
|
@ -250,7 +282,7 @@ impl Default for ElementReaderContext {
|
|||
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxsizelength-element
|
||||
max_size_length: 8,
|
||||
locked: false,
|
||||
lock_depth: 0,
|
||||
lock_depths: Vec::with_capacity(MAX_DEPTH as usize),
|
||||
lock_len: VInt::ZERO,
|
||||
}
|
||||
}
|
||||
|
@ -285,6 +317,7 @@ impl ElementReaderYield {
|
|||
}
|
||||
}
|
||||
|
||||
/// An EBML element reader.
|
||||
pub struct ElementReader<R> {
|
||||
reader: R,
|
||||
ctx: ElementReaderContext,
|
||||
|
@ -308,6 +341,11 @@ where
|
|||
let ret = self.reader.read(buf)?;
|
||||
let len = self.current_master_length();
|
||||
self.set_current_master_length(len.saturating_sub(ret as u64));
|
||||
|
||||
if self.ctx.locked {
|
||||
self.ctx.lock_len = self.ctx.lock_len.saturating_sub(ret as u64);
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
@ -355,10 +393,6 @@ where
|
|||
return;
|
||||
}
|
||||
|
||||
if self.ctx.locked {
|
||||
self.ctx.lock_len = length;
|
||||
}
|
||||
|
||||
self.ctx.masters[(self.ctx.depth - 1) as usize].remaining_length = length;
|
||||
}
|
||||
|
||||
|
@ -405,7 +439,7 @@ where
|
|||
}
|
||||
|
||||
fn goto_previous_master(&mut self) -> Result<()> {
|
||||
if self.ctx.depth == 0 || self.ctx.depth == self.ctx.lock_depth {
|
||||
if self.ctx.depth == 0 || self.ctx.lock_depths.last() == Some(&self.ctx.depth) {
|
||||
decode_err!(@BAIL Ebml, "Cannot go to previous master element, already at root")
|
||||
}
|
||||
|
||||
|
@ -468,10 +502,22 @@ where
|
|||
pub(crate) fn lock(&mut self) {
|
||||
self.ctx.locked = true;
|
||||
self.ctx.lock_len = self.current_master_length();
|
||||
self.ctx.lock_depths.push(self.ctx.depth);
|
||||
}
|
||||
|
||||
pub(crate) fn unlock(&mut self) {
|
||||
self.ctx.locked = false;
|
||||
let _ = self.ctx.lock_depths.pop();
|
||||
|
||||
let [.., last] = &*self.ctx.lock_depths else {
|
||||
// We can only ever *truly* unlock if we are at the root level.
|
||||
log::trace!("Lock freed");
|
||||
|
||||
self.ctx.locked = false;
|
||||
return;
|
||||
};
|
||||
|
||||
log::trace!("Moving lock to depth: {}", last);
|
||||
self.ctx.lock_len = self.ctx.masters[(*last - 1) as usize].remaining_length;
|
||||
}
|
||||
|
||||
pub(crate) fn children(&mut self) -> ElementChildIterator<'_, R> {
|
||||
|
@ -595,6 +641,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// An iterator over the children of an EBML master element.
|
||||
///
|
||||
/// This is created by calling [`ElementReader::children`].
|
||||
///
|
||||
/// This is essentially a fancy wrapper around `ElementReader` that:
|
||||
///
|
||||
/// * Automatically skips unknown elements ([`ElementReaderYield::Unknown`]).
|
||||
/// * [`Deref`]s to `ElementReader` so you can access the reader's methods.
|
||||
/// * Unlocks the reader when dropped.
|
||||
/// * If the reader is locked at multiple depths (meaning [`ElementReader::children`] was called
|
||||
/// multiple times), it will move the lock to the previously locked depth.
|
||||
pub(crate) struct ElementChildIterator<'a, R>
|
||||
where
|
||||
R: Read,
|
||||
|
@ -622,10 +679,15 @@ where
|
|||
}
|
||||
|
||||
pub(crate) fn master_exhausted(&self) -> bool {
|
||||
let lock_depth = self.reader.ctx.lock_depth;
|
||||
assert!(lock_depth < self.reader.ctx.depth);
|
||||
let lock_depth = *self
|
||||
.reader
|
||||
.ctx
|
||||
.lock_depths
|
||||
.last()
|
||||
.expect("a child iterator should always have a lock depth");
|
||||
assert!(lock_depth <= self.reader.ctx.depth);
|
||||
|
||||
self.reader.ctx.masters[lock_depth as usize].remaining_length == 0
|
||||
self.reader.ctx.masters[(lock_depth - 1) as usize].remaining_length == 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
use super::{
|
||||
segment_attachments, segment_chapters, segment_cluster, segment_info, segment_tags,
|
||||
segment_tracks,
|
||||
};
|
||||
use super::{segment_attachments, segment_cluster, segment_info, segment_tags, segment_tracks};
|
||||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::{ElementHeader, ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::ebml::tag::EbmlTag;
|
||||
use crate::ebml::VInt;
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
|
@ -21,60 +17,69 @@ where
|
|||
R: Read + Seek,
|
||||
{
|
||||
let mut tags = None;
|
||||
let mut children_reader = element_reader.children();
|
||||
|
||||
element_reader.lock();
|
||||
|
||||
loop {
|
||||
let child = element_reader.next()?;
|
||||
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((id, size)) => match id {
|
||||
ElementIdent::Info if parse_options.read_properties => {
|
||||
segment_info::read_from(element_reader, parse_options, properties)?
|
||||
},
|
||||
ElementIdent::Cluster if parse_options.read_properties => {
|
||||
segment_cluster::read_from(element_reader, parse_options, properties)?
|
||||
},
|
||||
ElementIdent::Tracks if parse_options.read_properties => {
|
||||
segment_tracks::read_from(element_reader, parse_options, properties)?
|
||||
},
|
||||
// TODO: ElementIdent::Chapters
|
||||
ElementIdent::Tags if parse_options.read_tags => {
|
||||
let mut tag = tags.unwrap_or_default();
|
||||
ElementReaderYield::Master((id, size)) => {
|
||||
match id {
|
||||
ElementIdent::Info if parse_options.read_properties => {
|
||||
segment_info::read_from(
|
||||
&mut children_reader.children(),
|
||||
parse_options,
|
||||
properties,
|
||||
)?;
|
||||
},
|
||||
ElementIdent::Cluster if parse_options.read_properties => {
|
||||
segment_cluster::read_from(
|
||||
&mut children_reader.children(),
|
||||
parse_options,
|
||||
properties,
|
||||
)?;
|
||||
},
|
||||
ElementIdent::Tracks if parse_options.read_properties => {
|
||||
segment_tracks::read_from(
|
||||
&mut children_reader.children(),
|
||||
parse_options,
|
||||
properties,
|
||||
)?;
|
||||
},
|
||||
// TODO: ElementIdent::Chapters
|
||||
ElementIdent::Tags if parse_options.read_tags => {
|
||||
let mut tag = tags.unwrap_or_default();
|
||||
|
||||
segment_tags::read_from(element_reader, parse_options, &mut tag)?;
|
||||
segment_tags::read_from(
|
||||
&mut children_reader.children(),
|
||||
parse_options,
|
||||
&mut tag,
|
||||
)?;
|
||||
|
||||
tags = Some(tag);
|
||||
},
|
||||
ElementIdent::Attachments if parse_options.read_cover_art => {
|
||||
let mut tag = tags.unwrap_or_default();
|
||||
tags = Some(tag);
|
||||
},
|
||||
ElementIdent::Attachments if parse_options.read_cover_art => {
|
||||
let mut tag = tags.unwrap_or_default();
|
||||
|
||||
segment_attachments::read_from(element_reader, parse_options, &mut tag)?;
|
||||
segment_attachments::read_from(
|
||||
&mut children_reader.children(),
|
||||
parse_options,
|
||||
&mut tag,
|
||||
)?;
|
||||
|
||||
tags = Some(tag);
|
||||
},
|
||||
_ => {
|
||||
// We do not end up using information from all of the segment
|
||||
// elements, so we can just skip any useless ones.
|
||||
tags = Some(tag);
|
||||
},
|
||||
_ => {
|
||||
// We do not end up using information from all of the segment
|
||||
// elements, so we can just skip any useless ones.
|
||||
|
||||
element_reader.skip_element(ElementHeader {
|
||||
id: VInt(id as u64),
|
||||
size,
|
||||
})?;
|
||||
continue;
|
||||
},
|
||||
},
|
||||
ElementReaderYield::Unknown(header) => {
|
||||
element_reader.skip_element(header)?;
|
||||
continue;
|
||||
},
|
||||
ElementReaderYield::Child(_) => {
|
||||
decode_err!(@BAIL Ebml, "Segment element should only contain master elements")
|
||||
},
|
||||
ElementReaderYield::Eof => {
|
||||
element_reader.unlock();
|
||||
break;
|
||||
children_reader.skip_element(ElementHeader {
|
||||
id: VInt(id as u64),
|
||||
size,
|
||||
})?;
|
||||
},
|
||||
}
|
||||
},
|
||||
ElementReaderYield::Eof => break,
|
||||
_ => unreachable!("Unhandled child element in \\Ebml\\Segment: {child:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::element_reader::{
|
||||
ElementChildIterator, ElementIdent, ElementReader, ElementReaderYield,
|
||||
};
|
||||
use crate::ebml::{AttachedFile, EbmlTag};
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
|
@ -8,19 +10,17 @@ use crate::picture::MimeType;
|
|||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
children_reader: &mut ElementChildIterator<'_, R>,
|
||||
_parse_options: ParseOptions,
|
||||
tag: &mut EbmlTag,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
let mut children_reader = element_reader.children();
|
||||
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((ElementIdent::AttachedFile, size)) => {
|
||||
let attached_file = read_attachment(&mut children_reader)?;
|
||||
let attached_file = read_attachment(children_reader)?;
|
||||
tag.attached_files.push(attached_file);
|
||||
},
|
||||
ElementReaderYield::Eof => break,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::ElementReader;
|
||||
use crate::ebml::element_reader::ElementChildIterator;
|
||||
use crate::ebml::EbmlTag;
|
||||
use crate::error::Result;
|
||||
|
||||
|
@ -7,7 +7,7 @@ use std::io::{Read, Seek};
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub(super) fn read_from<R>(
|
||||
_element_reader: &mut ElementReader<R>,
|
||||
_children_reader: &mut ElementChildIterator<'_, R>,
|
||||
_parse_options: ParseOptions,
|
||||
_tag: &mut EbmlTag,
|
||||
) -> Result<()>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::ElementReader;
|
||||
use crate::ebml::element_reader::ElementChildIterator;
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::error::Result;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
_element_reader: &mut ElementReader<R>,
|
||||
_children_reader: &mut ElementChildIterator<'_, R>,
|
||||
_parse_options: ParseOptions,
|
||||
_properties: &mut EbmlProperties,
|
||||
) -> Result<()>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::config::{ParseOptions, ParsingMode};
|
||||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::element_reader::{ElementChildIterator, ElementIdent, ElementReaderYield};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
|
@ -7,15 +7,13 @@ use crate::macros::decode_err;
|
|||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
children_reader: &mut ElementChildIterator<'_, R>,
|
||||
parse_options: ParseOptions,
|
||||
properties: &mut EbmlProperties,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
let mut children_reader = element_reader.children();
|
||||
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((id, size)) => {
|
||||
|
|
|
@ -1,17 +1,59 @@
|
|||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::ElementReader;
|
||||
use crate::ebml::element_reader::{ElementChildIterator, ElementIdent, ElementReaderYield};
|
||||
use crate::ebml::EbmlTag;
|
||||
use crate::error::Result;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
_element_reader: &mut ElementReader<R>,
|
||||
children_reader: &mut ElementChildIterator<'_, R>,
|
||||
_parse_options: ParseOptions,
|
||||
_tag: &mut EbmlTag,
|
||||
tag: &mut EbmlTag,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
unimplemented!("\\Ebml\\Segment\\Tags")
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((ElementIdent::Tag, _size)) => {
|
||||
read_tag(&mut children_reader.children(), tag)?
|
||||
},
|
||||
_ => unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tags: {child:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_tag<R>(children_reader: &mut ElementChildIterator<'_, R>, _tag: &mut EbmlTag) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((ElementIdent::Targets, _size)) => {
|
||||
read_targets(&mut children_reader.children())?
|
||||
},
|
||||
ElementReaderYield::Master((ElementIdent::Tag, _size)) => {
|
||||
read_simple_tag(&mut children_reader.children())?
|
||||
},
|
||||
_ => unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tags: {child:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_targets<R>(_children_reader: &mut ElementChildIterator<'_, R>) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
unimplemented!("\\Ebml\\Segment\\Tags\\Targets")
|
||||
}
|
||||
|
||||
fn read_simple_tag<R>(_children_reader: &mut ElementChildIterator<'_, R>) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
unimplemented!("\\Ebml\\Segment\\Tags\\SimpleTag")
|
||||
}
|
||||
|
|
|
@ -1,55 +1,34 @@
|
|||
use crate::config::ParseOptions;
|
||||
use crate::ebml::element_reader::{
|
||||
ChildElementDescriptor, ElementHeader, ElementIdent, ElementReader, ElementReaderYield,
|
||||
ChildElementDescriptor, ElementChildIterator, ElementIdent, ElementReaderYield,
|
||||
};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::ebml::VInt;
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
children_reader: &mut ElementChildIterator<'_, R>,
|
||||
parse_options: ParseOptions,
|
||||
properties: &mut EbmlProperties,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
element_reader.lock();
|
||||
|
||||
let mut audio_tracks = Vec::new();
|
||||
|
||||
loop {
|
||||
let child = element_reader.next()?;
|
||||
if let ElementReaderYield::Eof = child {
|
||||
break;
|
||||
}
|
||||
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Master((ElementIdent::TrackEntry, size)) => {
|
||||
element_reader.unlock();
|
||||
read_track_entry(element_reader, parse_options, &mut audio_tracks)?;
|
||||
element_reader.lock();
|
||||
ElementReaderYield::Master((ElementIdent::TrackEntry, _size)) => {
|
||||
read_track_entry(children_reader, parse_options, &mut audio_tracks)?;
|
||||
},
|
||||
ElementReaderYield::Eof => break,
|
||||
_ => {
|
||||
let id = child
|
||||
.ident()
|
||||
.expect("Child element must have an identifier");
|
||||
let size = child.size().expect("Child element must have a size");
|
||||
|
||||
log::warn!(
|
||||
"Unexpected child element in \\EBML\\Segment\\Tracks: {:?}, skipping",
|
||||
id
|
||||
);
|
||||
element_reader.skip(size)?;
|
||||
continue;
|
||||
unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tracks: {child:?}");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
element_reader.unlock();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -64,81 +43,74 @@ struct AudioTrack {
|
|||
const AUDIO_TRACK_TYPE: u64 = 2;
|
||||
|
||||
fn read_track_entry<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
children_reader: &mut ElementChildIterator<'_, R>,
|
||||
parse_options: ParseOptions,
|
||||
audio_tracks: &mut Vec<AudioTrack>,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
element_reader.lock();
|
||||
|
||||
let mut track = AudioTrack::default();
|
||||
|
||||
loop {
|
||||
let child = element_reader.next()?;
|
||||
if let ElementReaderYield::Eof = child {
|
||||
break;
|
||||
}
|
||||
|
||||
while let Some(child) = children_reader.next()? {
|
||||
match child {
|
||||
ElementReaderYield::Child((ChildElementDescriptor { ident, .. }, size)) => {
|
||||
match ident {
|
||||
ElementIdent::TrackType => {
|
||||
let track_type = element_reader.read_unsigned_int(size.value())?;
|
||||
let track_type = children_reader.read_unsigned_int(size.value())?;
|
||||
log::trace!("Encountered new track of type: {}", track_type);
|
||||
|
||||
if track_type != AUDIO_TRACK_TYPE {
|
||||
element_reader.exhaust_current_master()?;
|
||||
children_reader.exhaust_current_master()?;
|
||||
break;
|
||||
}
|
||||
},
|
||||
ElementIdent::FlagEnabled => {
|
||||
let enabled = element_reader.read_flag(size.value())?;
|
||||
let enabled = children_reader.read_flag(size.value())?;
|
||||
track.enabled = enabled;
|
||||
},
|
||||
ElementIdent::FlagDefault => {
|
||||
let default = element_reader.read_flag(size.value())?;
|
||||
let default = children_reader.read_flag(size.value())?;
|
||||
track.default = default;
|
||||
},
|
||||
ElementIdent::DefaultDuration => {
|
||||
let _default_duration = element_reader.read_unsigned_int(size.value())?;
|
||||
let _default_duration = children_reader.read_unsigned_int(size.value())?;
|
||||
},
|
||||
ElementIdent::TrackTimecodeScale => {
|
||||
let _timecode_scale = element_reader.read_float(size.value())?;
|
||||
let _timecode_scale = children_reader.read_float(size.value())?;
|
||||
},
|
||||
ElementIdent::Language => {
|
||||
let _language = element_reader.read_string(size.value())?;
|
||||
let _language = children_reader.read_string(size.value())?;
|
||||
},
|
||||
ElementIdent::CodecID => {
|
||||
let codec_id = element_reader.read_string(size.value())?;
|
||||
let codec_id = children_reader.read_string(size.value())?;
|
||||
track.codec_id = codec_id;
|
||||
},
|
||||
ElementIdent::CodecDelay => {
|
||||
let _codec_delay = element_reader.read_unsigned_int(size.value())?;
|
||||
let _codec_delay = children_reader.read_unsigned_int(size.value())?;
|
||||
},
|
||||
ElementIdent::CodecName => {
|
||||
let codec_name = element_reader.read_utf8(size.value())?;
|
||||
let codec_name = children_reader.read_utf8(size.value())?;
|
||||
track.codec_name = codec_name;
|
||||
},
|
||||
ElementIdent::SeekPreRoll => {
|
||||
let _seek_pre_roll = element_reader.read_unsigned_int(size.value())?;
|
||||
let _seek_pre_roll = children_reader.read_unsigned_int(size.value())?;
|
||||
},
|
||||
_ => unreachable!("Unhandled child element in TrackEntry: {:?}", ident),
|
||||
}
|
||||
},
|
||||
ElementReaderYield::Master((id, size)) => match id {
|
||||
ElementIdent::Audio => {
|
||||
element_reader.skip(size.value())?;
|
||||
children_reader.skip(size.value())?;
|
||||
},
|
||||
_ => {
|
||||
unreachable!("Unhandled master element in TrackEntry: {:?}", id);
|
||||
},
|
||||
},
|
||||
ElementReaderYield::Unknown(ElementHeader { size, id }) => {
|
||||
element_reader.skip(size.value())?;
|
||||
ElementReaderYield::Eof => break,
|
||||
_ => {
|
||||
unreachable!("Unhandled child element in TrackEntry: {child:?}");
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,6 +121,5 @@ where
|
|||
|
||||
audio_tracks.push(track);
|
||||
|
||||
element_reader.unlock();
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue