mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-12 13:42:34 +00:00
EBML: Start parsing segment.Info
Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
parent
eb5253ba50
commit
131049cd4b
5 changed files with 81 additions and 5 deletions
|
@ -224,6 +224,11 @@ where
|
|||
self.ctx.max_size_length = len
|
||||
}
|
||||
|
||||
fn store_previous_master(&mut self) {
|
||||
self.ctx.previous_master = self.ctx.current_master;
|
||||
self.ctx.previous_master_length = self.ctx.master_length;
|
||||
}
|
||||
|
||||
fn next_master(&mut self) -> Result<ElementReaderYield> {
|
||||
let header = ElementHeader::read(
|
||||
&mut self.reader,
|
||||
|
@ -235,8 +240,7 @@ where
|
|||
return Ok(ElementReaderYield::Unknown(header));
|
||||
};
|
||||
|
||||
self.ctx.previous_master = self.ctx.current_master;
|
||||
self.ctx.previous_master_length = self.ctx.master_length;
|
||||
self.store_previous_master();
|
||||
self.ctx.current_master = Some(*master);
|
||||
self.ctx.master_length = header.size.value();
|
||||
Ok(ElementReaderYield::Master((
|
||||
|
@ -288,6 +292,7 @@ where
|
|||
};
|
||||
|
||||
if child.data_type == ElementDataType::Master {
|
||||
self.store_previous_master();
|
||||
self.ctx.current_master = Some(
|
||||
*MASTER_ELEMENTS
|
||||
.get(&header.id)
|
||||
|
|
|
@ -17,11 +17,19 @@ pub struct EbmlExtension {
|
|||
pub(crate) version: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct SegmentInfo {
|
||||
pub(crate) timecode_scale: u64,
|
||||
pub(crate) muxing_app: String,
|
||||
pub(crate) writing_app: String,
|
||||
}
|
||||
|
||||
/// EBML audio properties
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct EbmlProperties {
|
||||
pub(crate) header: EbmlHeaderProperties,
|
||||
pub(crate) extensions: Vec<EbmlExtension>,
|
||||
pub(crate) segment_info: SegmentInfo,
|
||||
}
|
||||
|
||||
impl From<EbmlProperties> for FileProperties {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
mod segment;
|
||||
mod segment_info;
|
||||
|
||||
use super::EbmlFile;
|
||||
use crate::ebml::element_reader::{ElementHeader, ElementIdent, ElementReader, ElementReaderYield};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use super::segment_info;
|
||||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::ebml::tag::EbmlTag;
|
||||
|
@ -9,8 +10,8 @@ use std::io::{Read, Seek};
|
|||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
_parse_options: ParseOptions,
|
||||
_properties: &mut EbmlProperties,
|
||||
parse_options: ParseOptions,
|
||||
properties: &mut EbmlProperties,
|
||||
) -> Result<Option<EbmlTag>>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -23,7 +24,9 @@ where
|
|||
let res = element_reader.next()?;
|
||||
match res {
|
||||
ElementReaderYield::Master((id, size)) => match id {
|
||||
ElementIdent::Info => todo!("Support segment.Info"),
|
||||
ElementIdent::Info => {
|
||||
segment_info::read_from(element_reader, parse_options, properties)?
|
||||
},
|
||||
ElementIdent::Cluster => todo!("Support segment.Cluster"),
|
||||
ElementIdent::Tracks => todo!("Support segment.Tracks"),
|
||||
ElementIdent::Tags => todo!("Support segment.Tags"),
|
||||
|
|
59
src/ebml/read/segment_info.rs
Normal file
59
src/ebml/read/segment_info.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::error::Result;
|
||||
use crate::probe::ParseOptions;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
_parse_options: ParseOptions,
|
||||
_properties: &mut EbmlProperties,
|
||||
) -> Result<()>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
element_reader.lock();
|
||||
|
||||
loop {
|
||||
let res = element_reader.next()?;
|
||||
match res {
|
||||
ElementReaderYield::Master((id, size)) => {
|
||||
// We do not end up using information from any of the nested master
|
||||
// elements, so we can just skip them.
|
||||
|
||||
log::debug!("Skipping EBML master element: {:?}", id);
|
||||
element_reader.skip(size)?;
|
||||
element_reader.goto_previous_master()?;
|
||||
continue;
|
||||
},
|
||||
ElementReaderYield::Child((child, size)) => {
|
||||
match child.ident {
|
||||
ElementIdent::TimecodeScale => todo!("Support segment.Info.TimecodeScale"),
|
||||
ElementIdent::MuxingApp => todo!("Support segment.Info.MuxingApp"),
|
||||
ElementIdent::WritingApp => todo!("Support segment.Info.WritingApp"),
|
||||
_ => {
|
||||
// We do not end up using information from all of the segment
|
||||
// elements, so we can just skip any useless ones.
|
||||
|
||||
log::debug!("Skipping EBML child element: {:?}", child);
|
||||
element_reader.skip(size)?;
|
||||
continue;
|
||||
},
|
||||
}
|
||||
},
|
||||
ElementReaderYield::Unknown(element) => {
|
||||
log::debug!("Skipping unknown EBML element: {:X}", element.id.0);
|
||||
element_reader.skip(element.size.value())?;
|
||||
continue;
|
||||
},
|
||||
ElementReaderYield::Eof => {
|
||||
element_reader.unlock();
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
element_reader.goto_previous_master()?;
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue