mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-06-11 01:19:21 +00:00
stts and sample box parsing. Update mp4info example with more details.
This commit is contained in:
parent
1a9c7ff977
commit
7c85d3b571
|
@ -3,9 +3,9 @@ extern crate mp4;
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::any::Any;
|
||||
use mp4::{FourCC, TrackType};
|
||||
use std::borrow::Borrow;
|
||||
use std::fmt::Debug;
|
||||
use mp4::{TrackType};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -33,17 +33,28 @@ fn main() {
|
|||
let mdia = trak.mdia.as_ref().unwrap();
|
||||
let hdlr = mdia.hdlr.as_ref().unwrap();
|
||||
let mdhd = mdia.mdhd.as_ref().unwrap();
|
||||
let stts= mdia.minf.as_ref().unwrap()
|
||||
.stbl.as_ref().unwrap()
|
||||
.stts.as_ref().unwrap();
|
||||
|
||||
println!("Track: {:?}", tkhd.track_id);
|
||||
println!(" flags: {:?}", tkhd.flags);
|
||||
println!(" id: {:?}", tkhd.track_id);
|
||||
println!(" type: {:?}", get_handler_type(hdlr.handler_type.value.as_ref()));
|
||||
println!(" duration: {:?}", tkhd.duration);
|
||||
println!(" language: {:?}", mdhd.language_string);
|
||||
println!("media:");
|
||||
// println!(" sample count: {:?}", mdia.minf.stbl.stts.sample_counts);
|
||||
|
||||
println!(" media:");
|
||||
println!(" sample count: {:?}", stts.sample_counts[0]);
|
||||
println!(" timescale: {:?}", mdhd.timescale);
|
||||
println!(" duration: {:?} (media timescale units)", mdhd.duration);
|
||||
println!(" duration: {:?} (ms)", getDurationMS(mdhd.duration, mdhd.timescale));
|
||||
if tkhd.width != 0 && tkhd.height != 0 {
|
||||
println!(" width: {:?}", tkhd.width);
|
||||
println!(" height: {:?}\n", tkhd.height);
|
||||
println!(" width: {:?}", tkhd.width);
|
||||
println!(" height: {:?}", tkhd.height);
|
||||
}
|
||||
if get_handler_type(hdlr.handler_type.value.as_ref()) == TrackType::Video {
|
||||
println!(" frame rate: (computed): {:?}", getFramerate(&stts.sample_counts, mdhd.duration, mdhd.timescale));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -62,4 +73,15 @@ fn get_handler_type(handler: &str) -> TrackType {
|
|||
_ => (),
|
||||
}
|
||||
return typ;
|
||||
}
|
||||
|
||||
fn getDurationMS(duration: u32, timescale: u32) -> String {
|
||||
let ms = (duration as f64 / timescale as f64) * 1000.0;
|
||||
return format!("{:.2}", ms.floor());
|
||||
}
|
||||
|
||||
fn getFramerate(sample_counts: &Vec<u32>, duration: u32, timescale: u32) -> String {
|
||||
let sc = (sample_counts[0] as f64) * 1000.0;
|
||||
let ms = (duration as f64 / timescale as f64) * 1000.0;
|
||||
return format!("{:.2}", sc / ms.floor());
|
||||
}
|
63
src/lib.rs
63
src/lib.rs
|
@ -244,11 +244,11 @@ impl StblBox {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SttsBox {
|
||||
// pub version: u8,
|
||||
// pub flags: u32,
|
||||
// pub entry_count: u32,
|
||||
// pub sample_counts: Vec<u32>,
|
||||
// pub sample_deltas: Vec<u32>,
|
||||
pub version: u8,
|
||||
pub flags: u32,
|
||||
pub entry_count: u32,
|
||||
pub sample_counts: Vec<u32>,
|
||||
pub sample_deltas: Vec<u32>,
|
||||
}
|
||||
|
||||
impl SttsBox {
|
||||
|
@ -857,14 +857,12 @@ fn parse_stbl_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<St
|
|||
match b.head.name.as_ref() {
|
||||
"stsd" => {
|
||||
println!("found stsd: {:?}", s);
|
||||
let stsd = parse_stsd_box(f, 0, s as u32).unwrap();
|
||||
// start = (s as u32 - HEADER_SIZE) as u64;
|
||||
// let stsd = parse_stsd_box(f, 0, s as u32).unwrap();
|
||||
start = (s as u32 - HEADER_SIZE) as u64;
|
||||
}
|
||||
"stts" => {
|
||||
println!("found stts");
|
||||
// let stts = parse_stts_box(f, 0, s as u32).unwrap();
|
||||
// stbl.stts = Some(stts);
|
||||
start = (s as u32 - HEADER_SIZE) as u64;
|
||||
let stts = parse_stts_box(f, 0, s as u32).unwrap();
|
||||
stbl.stts = Some(stts);
|
||||
}
|
||||
"stss" => {
|
||||
println!("found stss");
|
||||
|
@ -900,24 +898,21 @@ fn parse_stbl_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<St
|
|||
fn parse_stts_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<SttsBox> {
|
||||
let current = f.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||
|
||||
// let version = f.read_u8().unwrap();
|
||||
// let flags_a = f.read_u8().unwrap();
|
||||
// let flags_b = f.read_u8().unwrap();
|
||||
// let flags_c = f.read_u8().unwrap();
|
||||
// let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
||||
// f.read_u32::<BigEndian>().unwrap(); // skip.
|
||||
//
|
||||
// let entry_count = f.read_u32::<BigEndian>().unwrap();
|
||||
//
|
||||
// let mut sample_counts = Vec::new();
|
||||
// let mut sample_deltas = Vec::new();
|
||||
//
|
||||
// for _i in 0..entry_count {
|
||||
// let sc = f.read_u32::<BigEndian>().unwrap();
|
||||
// let sd = f.read_u32::<BigEndian>().unwrap();
|
||||
// sample_counts.push(sc);
|
||||
// sample_deltas.push(sd);
|
||||
// }
|
||||
let version = f.read_u8().unwrap();
|
||||
let flags_a = f.read_u8().unwrap();
|
||||
let flags_b = f.read_u8().unwrap();
|
||||
let flags_c = f.read_u8().unwrap();
|
||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
||||
let entry_count = f.read_u32::<BigEndian>().unwrap();
|
||||
let mut sample_counts = Vec::new();
|
||||
let mut sample_deltas = Vec::new();
|
||||
|
||||
for _i in 0..entry_count {
|
||||
let sc = f.read_u32::<BigEndian>().unwrap();
|
||||
let sd = f.read_u32::<BigEndian>().unwrap();
|
||||
sample_counts.push(sc);
|
||||
sample_deltas.push(sd);
|
||||
}
|
||||
|
||||
// Skip remaining bytes.
|
||||
let after = f.seek(SeekFrom::Current(0)).unwrap();
|
||||
|
@ -925,11 +920,11 @@ fn parse_stts_box(f: &mut BufReader<File>, _offset: u64, size: u32) -> Result<St
|
|||
f.seek(SeekFrom::Current(remaining_bytes - HEADER_SIZE as i64)).unwrap();
|
||||
|
||||
Ok(SttsBox {
|
||||
// version,
|
||||
// flags,
|
||||
// entry_count,
|
||||
// sample_counts,
|
||||
// sample_deltas,
|
||||
version,
|
||||
flags,
|
||||
entry_count,
|
||||
sample_counts,
|
||||
sample_deltas,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue