mirror of
https://github.com/alfg/mp4-rust.git
synced 2025-01-05 09:58:40 +00:00
edts/elst box parsing
This commit is contained in:
parent
b400b02aee
commit
b50097b784
1 changed files with 97 additions and 4 deletions
101
src/lib.rs
101
src/lib.rs
|
@ -78,6 +78,7 @@ struct MvhdBox {
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct TrakBox {
|
struct TrakBox {
|
||||||
tkhd: Option<TkhdBox>,
|
tkhd: Option<TkhdBox>,
|
||||||
|
edts: Option<EdtsBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrakBox {
|
impl TrakBox {
|
||||||
|
@ -115,6 +116,38 @@ struct Matrix {
|
||||||
w: i32,
|
w: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct EdtsBox {
|
||||||
|
elst: Option<ElstBox>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EdtsBox {
|
||||||
|
fn new() -> EdtsBox {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct ElstBox {
|
||||||
|
version: u32,
|
||||||
|
entry_count: u32,
|
||||||
|
entries: Vec<ElstEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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)]
|
#[derive(Default, PartialEq, Clone)]
|
||||||
pub struct FourCC {
|
pub struct FourCC {
|
||||||
|
@ -340,14 +373,12 @@ fn parse_trak_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<Tr
|
||||||
|
|
||||||
match b.head.name.as_ref() {
|
match b.head.name.as_ref() {
|
||||||
"tkhd" => {
|
"tkhd" => {
|
||||||
println!("found tkhd");
|
|
||||||
let tkhd = parse_tkhd_box(f, 0, s as u32).unwrap();
|
let tkhd = parse_tkhd_box(f, 0, s as u32).unwrap();
|
||||||
trak.tkhd = Some(tkhd);
|
trak.tkhd = Some(tkhd);
|
||||||
start = (s as u32 - HEADER_SIZE) as u64;
|
|
||||||
}
|
}
|
||||||
"edts" => {
|
"edts" => {
|
||||||
println!("found edts");
|
let edts = parse_edts_box(f, 0, s as u32).unwrap();
|
||||||
start = (s as u32 - HEADER_SIZE) as u64;
|
trak.edts = Some(edts);
|
||||||
}
|
}
|
||||||
"mdia" => {
|
"mdia" => {
|
||||||
println!("found mdia");
|
println!("found mdia");
|
||||||
|
@ -418,3 +449,65 @@ fn parse_tkhd_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<Tk
|
||||||
height,
|
height,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_edts_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<EdtsBox> {
|
||||||
|
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<File>, _offset: u64, size: u32) -> Result<ElstBox> {
|
||||||
|
let current = f.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
|
let version = f.read_u32::<byteorder::BigEndian>().unwrap();
|
||||||
|
let entry_count = f.read_u32::<byteorder::BigEndian>().unwrap();
|
||||||
|
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
|
for i in 0..entry_count {
|
||||||
|
let entry = ElstEntry{
|
||||||
|
segment_duration: f.read_u32::<byteorder::BigEndian>().unwrap(),
|
||||||
|
media_time: f.read_u32::<byteorder::BigEndian>().unwrap(),
|
||||||
|
media_rate: f.read_u16::<byteorder::BigEndian>().unwrap(),
|
||||||
|
media_rate_fraction: f.read_u16::<byteorder::BigEndian>().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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue