Skip to content

Commit b5dd3cc

Browse files
committed
EBML: Start parsing segment.Info
Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
1 parent f1f01ff commit b5dd3cc

File tree

5 files changed

+81
-5
lines changed

5 files changed

+81
-5
lines changed

src/ebml/element_reader.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ where
224224
self.ctx.max_size_length = len
225225
}
226226

227+
fn store_previous_master(&mut self) {
228+
self.ctx.previous_master = self.ctx.current_master;
229+
self.ctx.previous_master_length = self.ctx.master_length;
230+
}
231+
227232
fn next_master(&mut self) -> Result<ElementReaderYield> {
228233
let header = ElementHeader::read(
229234
&mut self.reader,
@@ -235,8 +240,7 @@ where
235240
return Ok(ElementReaderYield::Unknown(header));
236241
};
237242

238-
self.ctx.previous_master = self.ctx.current_master;
239-
self.ctx.previous_master_length = self.ctx.master_length;
243+
self.store_previous_master();
240244
self.ctx.current_master = Some(*master);
241245
self.ctx.master_length = header.size.value();
242246
Ok(ElementReaderYield::Master((
@@ -288,6 +292,7 @@ where
288292
};
289293

290294
if child.data_type == ElementDataType::Master {
295+
self.store_previous_master();
291296
self.ctx.current_master = Some(
292297
*MASTER_ELEMENTS
293298
.get(&header.id)

src/ebml/properties.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@ pub struct EbmlExtension {
1717
pub(crate) version: u64,
1818
}
1919

20+
#[derive(Debug, Clone, PartialEq, Default)]
21+
pub struct SegmentInfo {
22+
pub(crate) timecode_scale: u64,
23+
pub(crate) muxing_app: String,
24+
pub(crate) writing_app: String,
25+
}
26+
2027
/// EBML audio properties
2128
#[derive(Debug, Clone, PartialEq, Default)]
2229
pub struct EbmlProperties {
2330
pub(crate) header: EbmlHeaderProperties,
2431
pub(crate) extensions: Vec<EbmlExtension>,
32+
pub(crate) segment_info: SegmentInfo,
2533
}
2634

2735
impl From<EbmlProperties> for FileProperties {

src/ebml/read.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod segment;
2+
mod segment_info;
23

34
use super::EbmlFile;
45
use crate::ebml::element_reader::{ElementHeader, ElementIdent, ElementReader, ElementReaderYield};

src/ebml/read/segment.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::segment_info;
12
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
23
use crate::ebml::properties::EbmlProperties;
34
use crate::ebml::tag::EbmlTag;
@@ -9,8 +10,8 @@ use std::io::{Read, Seek};
910

1011
pub(super) fn read_from<R>(
1112
element_reader: &mut ElementReader<R>,
12-
_parse_options: ParseOptions,
13-
_properties: &mut EbmlProperties,
13+
parse_options: ParseOptions,
14+
properties: &mut EbmlProperties,
1415
) -> Result<Option<EbmlTag>>
1516
where
1617
R: Read + Seek,
@@ -23,7 +24,9 @@ where
2324
let res = element_reader.next()?;
2425
match res {
2526
ElementReaderYield::Master((id, size)) => match id {
26-
ElementIdent::Info => todo!("Support segment.Info"),
27+
ElementIdent::Info => {
28+
segment_info::read_from(element_reader, parse_options, properties)?
29+
},
2730
ElementIdent::Cluster => todo!("Support segment.Cluster"),
2831
ElementIdent::Tracks => todo!("Support segment.Tracks"),
2932
ElementIdent::Tags => todo!("Support segment.Tags"),

src/ebml/read/segment_info.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
2+
use crate::ebml::properties::EbmlProperties;
3+
use crate::error::Result;
4+
use crate::probe::ParseOptions;
5+
6+
use std::io::{Read, Seek};
7+
8+
pub(super) fn read_from<R>(
9+
element_reader: &mut ElementReader<R>,
10+
_parse_options: ParseOptions,
11+
_properties: &mut EbmlProperties,
12+
) -> Result<()>
13+
where
14+
R: Read + Seek,
15+
{
16+
element_reader.lock();
17+
18+
loop {
19+
let res = element_reader.next()?;
20+
match res {
21+
ElementReaderYield::Master((id, size)) => {
22+
// We do not end up using information from any of the nested master
23+
// elements, so we can just skip them.
24+
25+
log::debug!("Skipping EBML master element: {:?}", id);
26+
element_reader.skip(size)?;
27+
element_reader.goto_previous_master()?;
28+
continue;
29+
},
30+
ElementReaderYield::Child((child, size)) => {
31+
match child.ident {
32+
ElementIdent::TimecodeScale => todo!("Support segment.Info.TimecodeScale"),
33+
ElementIdent::MuxingApp => todo!("Support segment.Info.MuxingApp"),
34+
ElementIdent::WritingApp => todo!("Support segment.Info.WritingApp"),
35+
_ => {
36+
// We do not end up using information from all of the segment
37+
// elements, so we can just skip any useless ones.
38+
39+
log::debug!("Skipping EBML child element: {:?}", child);
40+
element_reader.skip(size)?;
41+
continue;
42+
},
43+
}
44+
},
45+
ElementReaderYield::Unknown(element) => {
46+
log::debug!("Skipping unknown EBML element: {:X}", element.id.0);
47+
element_reader.skip(element.size.value())?;
48+
continue;
49+
},
50+
ElementReaderYield::Eof => {
51+
element_reader.unlock();
52+
break;
53+
},
54+
}
55+
}
56+
57+
element_reader.goto_previous_master()?;
58+
Ok(())
59+
}

0 commit comments

Comments
 (0)