mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-14 06:32:33 +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
|
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> {
|
fn next_master(&mut self) -> Result<ElementReaderYield> {
|
||||||
let header = ElementHeader::read(
|
let header = ElementHeader::read(
|
||||||
&mut self.reader,
|
&mut self.reader,
|
||||||
|
@ -235,8 +240,7 @@ where
|
||||||
return Ok(ElementReaderYield::Unknown(header));
|
return Ok(ElementReaderYield::Unknown(header));
|
||||||
};
|
};
|
||||||
|
|
||||||
self.ctx.previous_master = self.ctx.current_master;
|
self.store_previous_master();
|
||||||
self.ctx.previous_master_length = self.ctx.master_length;
|
|
||||||
self.ctx.current_master = Some(*master);
|
self.ctx.current_master = Some(*master);
|
||||||
self.ctx.master_length = header.size.value();
|
self.ctx.master_length = header.size.value();
|
||||||
Ok(ElementReaderYield::Master((
|
Ok(ElementReaderYield::Master((
|
||||||
|
@ -288,6 +292,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if child.data_type == ElementDataType::Master {
|
if child.data_type == ElementDataType::Master {
|
||||||
|
self.store_previous_master();
|
||||||
self.ctx.current_master = Some(
|
self.ctx.current_master = Some(
|
||||||
*MASTER_ELEMENTS
|
*MASTER_ELEMENTS
|
||||||
.get(&header.id)
|
.get(&header.id)
|
||||||
|
|
|
@ -17,11 +17,19 @@ pub struct EbmlExtension {
|
||||||
pub(crate) version: u64,
|
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
|
/// EBML audio properties
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub struct EbmlProperties {
|
pub struct EbmlProperties {
|
||||||
pub(crate) header: EbmlHeaderProperties,
|
pub(crate) header: EbmlHeaderProperties,
|
||||||
pub(crate) extensions: Vec<EbmlExtension>,
|
pub(crate) extensions: Vec<EbmlExtension>,
|
||||||
|
pub(crate) segment_info: SegmentInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<EbmlProperties> for FileProperties {
|
impl From<EbmlProperties> for FileProperties {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
mod segment;
|
mod segment;
|
||||||
|
mod segment_info;
|
||||||
|
|
||||||
use super::EbmlFile;
|
use super::EbmlFile;
|
||||||
use crate::ebml::element_reader::{ElementHeader, ElementIdent, ElementReader, ElementReaderYield};
|
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::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||||
use crate::ebml::properties::EbmlProperties;
|
use crate::ebml::properties::EbmlProperties;
|
||||||
use crate::ebml::tag::EbmlTag;
|
use crate::ebml::tag::EbmlTag;
|
||||||
|
@ -9,8 +10,8 @@ use std::io::{Read, Seek};
|
||||||
|
|
||||||
pub(super) fn read_from<R>(
|
pub(super) fn read_from<R>(
|
||||||
element_reader: &mut ElementReader<R>,
|
element_reader: &mut ElementReader<R>,
|
||||||
_parse_options: ParseOptions,
|
parse_options: ParseOptions,
|
||||||
_properties: &mut EbmlProperties,
|
properties: &mut EbmlProperties,
|
||||||
) -> Result<Option<EbmlTag>>
|
) -> Result<Option<EbmlTag>>
|
||||||
where
|
where
|
||||||
R: Read + Seek,
|
R: Read + Seek,
|
||||||
|
@ -23,7 +24,9 @@ where
|
||||||
let res = element_reader.next()?;
|
let res = element_reader.next()?;
|
||||||
match res {
|
match res {
|
||||||
ElementReaderYield::Master((id, size)) => match id {
|
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::Cluster => todo!("Support segment.Cluster"),
|
||||||
ElementIdent::Tracks => todo!("Support segment.Tracks"),
|
ElementIdent::Tracks => todo!("Support segment.Tracks"),
|
||||||
ElementIdent::Tags => todo!("Support segment.Tags"),
|
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