1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-06-02 13:39:54 +00:00

Refactor BMFF

This commit is contained in:
Ian Jun 2020-07-30 15:55:44 +09:00
parent 928fa66cf0
commit 75d5599a94
3 changed files with 66 additions and 75 deletions

View file

@ -10,23 +10,19 @@ fn main() {
let filename = &args[1];
let f = File::open(filename).unwrap();
let bmff = mp4::read_mp4(f).unwrap();
let bmff = mp4::BMFF::read_from_file(f).unwrap();
let moov = bmff.moov.unwrap();
// Print results.
println!("File:");
println!(" file size: {}", bmff.size);
println!(
" brands: {:?} {:?}\n",
bmff.ftyp.major_brand, bmff.ftyp.compatible_brands
);
println!(" size: {}", bmff.size);
println!(" brands: {:?} {:?}\n",
bmff.ftyp.major_brand, bmff.ftyp.compatible_brands);
println!("Movie:");
println!(" version: {:?}", moov.mvhd.version);
println!(
" creation time: {}",
creation_time(moov.mvhd.creation_time)
);
println!(" creation time: {}",
creation_time(moov.mvhd.creation_time));
println!(" duration: {:?}", moov.mvhd.duration);
println!(" timescale: {:?}\n", moov.mvhd.timescale);
@ -50,10 +46,8 @@ fn main() {
.map(|m| m.stbl.as_ref().map(|s| s.stts.as_ref()).flatten())
.flatten();
println!(
" type: {:?}",
get_handler_type(hdlr.handler_type.value.as_ref())
);
println!(" type: {:?}",
get_handler_type(hdlr.handler_type.value.as_ref()));
println!(" language: {:?}", mdhd.language);
println!(" media:");
@ -61,20 +55,15 @@ fn main() {
println!(" sample count: {:?}", s.entries[0].sample_count);
}
println!(" timescale: {:?}", mdhd.timescale);
println!(
" duration: {:?} (media timescale units)",
mdhd.duration
);
println!(
" duration: {:?} (ms)",
get_duration_ms(mdhd.duration, mdhd.timescale)
);
println!(" duration: {:?} (media timescale units)",
mdhd.duration);
println!(" duration: {:?} (ms)",
get_duration_ms(mdhd.duration, mdhd.timescale));
if get_handler_type(hdlr.handler_type.value.as_ref()) == mp4::TrackType::Video {
if let Some(ref s) = stts {
println!(
" frame rate: (computed): {:?}",
get_framerate(s.entries[0].sample_count, mdhd.duration, mdhd.timescale)
);
println!(" frame rate: (computed): {:?}",
get_framerate(s.entries[0].sample_count,
mdhd.duration, mdhd.timescale));
}
}
}

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek};
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::fs::File;
use std::convert::TryInto;
@ -26,56 +26,58 @@ pub struct BMFF {
}
impl BMFF {
fn new() -> BMFF {
pub fn new() -> BMFF {
Default::default()
}
}
pub fn read_mp4(f: File) -> Result<BMFF> {
pub fn read_from_file(f: File) -> Result<BMFF> {
let size = f.metadata()?.len();
let mut reader = BufReader::new(f);
// Open file and read boxes.
let bmff = read_boxes(f)?;
let mut bmff = BMFF::new();
bmff.size = bmff.read(&mut reader, size)?;
Ok(bmff)
}
fn read_boxes(f: File) -> Result<BMFF> {
let filesize = f.metadata()?.len();
let mut reader = BufReader::new(f);
let mut bmff = BMFF::new();
bmff.size = filesize;
let mut current = reader.seek(SeekFrom::Current(0))?;
while current < filesize {
// Get box header.
let header = BoxHeader::read(&mut reader)?;
let BoxHeader{ name, size } = header;
// Match and parse the atom boxes.
match name {
BoxType::FtypBox => {
let ftyp = FtypBox::read_box(&mut reader, size)?;
bmff.ftyp = ftyp;
}
BoxType::FreeBox => {
skip_box(&mut reader, size)?;
}
BoxType::MdatBox => {
skip_box(&mut reader, size)?;
}
BoxType::MoovBox => {
let moov = MoovBox::read_box(&mut reader, size)?;
bmff.moov = Some(moov);
}
BoxType::MoofBox => {
skip_box(&mut reader, size)?;
}
_ => {
// XXX warn!()
skip_box(&mut reader, size)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
Ok(bmff)
}
pub fn read<R: Read + Seek>(
&mut self,
reader: &mut BufReader<R>,
size: u64
) -> Result<u64> {
let start = reader.seek(SeekFrom::Current(0))?;
let mut current = start;
while current < size {
// Get box header.
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
// Match and parse the atom boxes.
match name {
BoxType::FtypBox => {
let ftyp = FtypBox::read_box(reader, s)?;
self.ftyp = ftyp;
}
BoxType::FreeBox => {
skip_box(reader, s)?;
}
BoxType::MdatBox => {
skip_box(reader, s)?;
}
BoxType::MoovBox => {
let moov = MoovBox::read_box(reader, s)?;
self.moov = Some(moov);
}
BoxType::MoofBox => {
skip_box(reader, s)?;
}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
}
Ok(current - start)
}
Ok(bmff)
}

View file

@ -6,7 +6,7 @@ use std::fs::File;
fn test_read_mp4() {
let filename = "tests/samples/minimal.mp4";
let f = File::open(filename).unwrap();
let bmff = mp4::read_mp4(f).unwrap();
let bmff = mp4::BMFF::read_from_file(f).unwrap();
assert_eq!(2591, bmff.size);
@ -35,4 +35,4 @@ fn test_read_mp4() {
assert_eq!(moov.mvhd.timescale, 1000);
assert_eq!(moov.traks.len(), 2);
}
}