From b50097b78480b879e0e9912fd8a16207f1c4f60d Mon Sep 17 00:00:00 2001 From: Alf Date: Sun, 19 Jan 2020 20:34:22 -0800 Subject: [PATCH] edts/elst box parsing --- src/lib.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index eac580c..13711b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,6 +78,7 @@ struct MvhdBox { #[derive(Debug, Default)] struct TrakBox { tkhd: Option, + edts: Option, } impl TrakBox { @@ -115,6 +116,38 @@ struct Matrix { w: i32, } +#[derive(Debug, Default)] +struct EdtsBox { + elst: Option, +} + +impl EdtsBox { + fn new() -> EdtsBox { + Default::default() + } +} + +#[derive(Debug, Default)] +struct ElstBox { + version: u32, + entry_count: u32, + entries: Vec, +} + +impl ElstBox { + fn new() -> ElstBox { + Default::default() + } +} + +#[derive(Debug, Default)] +struct ElstEntry { + segment_duration: u32, + media_time: u32, + media_rate: u16, + media_rate_fraction: u16, +} + #[derive(Default, PartialEq, Clone)] pub struct FourCC { @@ -340,14 +373,12 @@ fn parse_trak_box(f: &mut BufReader, _offset: u64, size: u32) -> Result { - println!("found tkhd"); let tkhd = parse_tkhd_box(f, 0, s as u32).unwrap(); trak.tkhd = Some(tkhd); - start = (s as u32 - HEADER_SIZE) as u64; } "edts" => { - println!("found edts"); - start = (s as u32 - HEADER_SIZE) as u64; + let edts = parse_edts_box(f, 0, s as u32).unwrap(); + trak.edts = Some(edts); } "mdia" => { println!("found mdia"); @@ -418,3 +449,65 @@ fn parse_tkhd_box(f: &mut BufReader, _offset: u64, size: u32) -> Result, _offset: u64, size: u32) -> Result { + let current = f.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position. + let mut edts = EdtsBox::new(); + + let mut start = 0u64; + while start < size as u64 { + // Get box header. + let header = read_box_header(f, start).unwrap(); + let BoxHeader{ name, size: s, offset } = header; + + let mut b = BMFFBox::new(); + b.head = BoxHeader{ + name: name.try_into().unwrap(), + size: s as u64, + offset: offset as u64, + }; + + match b.head.name.as_ref() { + "elst" => { + let elst = parse_elst_box(f, 0, s as u32).unwrap(); + edts.elst = Some(elst); + } + _ => break + } + } + + // Skip remaining bytes. + let after = f.seek(SeekFrom::Current(0)).unwrap(); + let remaining_bytes = (size as u64 - (after - current)) as i64; + f.seek(SeekFrom::Current(remaining_bytes - HEADER_SIZE as i64)).unwrap(); + Ok(edts) +} +fn parse_elst_box(f: &mut BufReader, _offset: u64, size: u32) -> Result { + let current = f.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position. + + let version = f.read_u32::().unwrap(); + let entry_count = f.read_u32::().unwrap(); + + let mut entries = Vec::new(); + + for i in 0..entry_count { + let entry = ElstEntry{ + segment_duration: f.read_u32::().unwrap(), + media_time: f.read_u32::().unwrap(), + media_rate: f.read_u16::().unwrap(), + media_rate_fraction: f.read_u16::().unwrap(), + }; + entries.push(entry); + } + + // Skip remaining bytes. + let after = f.seek(SeekFrom::Current(0)).unwrap(); + let remaining_bytes = (size as u64 - (after - current)) as i64; + f.seek(SeekFrom::Current(remaining_bytes - HEADER_SIZE as i64)).unwrap(); + + Ok(ElstBox { + version, + entry_count, + entries, + }) +}