mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-12-22 12:06:33 +00:00
Add mp4dump example and update all mp4boxes with get_type and get_size methods.
This commit is contained in:
parent
c4ff8627b0
commit
d51a193272
25 changed files with 403 additions and 0 deletions
90
examples/mp4dump.rs
Normal file
90
examples/mp4dump.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, BufReader};
|
||||
use std::path::Path;
|
||||
|
||||
use mp4::{Result};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
if args.len() < 2 {
|
||||
println!("Usage: mp4dump <filename>");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if let Err(err) = dump(&args[1]) {
|
||||
let _ = writeln!(io::stderr(), "{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
fn dump<P: AsRef<Path>>(filename: &P) -> Result<()> {
|
||||
let f = File::open(filename)?;
|
||||
let size = f.metadata()?.len();
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let mp4 = mp4::Mp4Reader::read_header(reader, size)?;
|
||||
|
||||
// ftyp
|
||||
println!("[{}] size={} ", mp4.ftyp.get_type(), mp4.ftyp.get_size());
|
||||
|
||||
// moov
|
||||
println!("[{}] size={} ", mp4.moov.get_type(), mp4.moov.get_size());
|
||||
println!(" [{}] size={} ", mp4.moov.mvhd.get_type(), mp4.moov.mvhd.get_size());
|
||||
|
||||
// Tracks.
|
||||
for track in mp4.tracks().iter() {
|
||||
|
||||
// trak
|
||||
println!(" [{}] size={} ", track.trak.get_type(), track.trak.get_size());
|
||||
println!(" [{}] size={} ", track.trak.tkhd.get_type(), track.trak.tkhd.get_size());
|
||||
if let Some(ref edts) = track.trak.edts {
|
||||
println!(" [{}] size={} ", edts.get_type(), edts.get_size());
|
||||
if let Some(ref elst) = edts.elst {
|
||||
println!(" [{}] size={} ", elst.get_type(), elst.get_size());
|
||||
}
|
||||
}
|
||||
|
||||
// trak.mdia.
|
||||
println!(" [{}] size={} ", track.trak.mdia.get_type(), track.trak.mdia.get_size());
|
||||
println!(" [{}] size={} ", track.trak.mdia.mdhd.get_type(), track.trak.mdia.mdhd.get_size());
|
||||
println!(" [{}] size={} ", track.trak.mdia.hdlr.get_type(), track.trak.mdia.hdlr.get_size());
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.get_type(), track.trak.mdia.minf.get_size());
|
||||
|
||||
// trak.mdia.minf
|
||||
if let Some(ref vmhd) = track.trak.mdia.minf.vmhd {
|
||||
println!(" [{}] size={} ", vmhd.get_type(), vmhd.get_size());
|
||||
}
|
||||
if let Some(ref smhd) = track.trak.mdia.minf.smhd {
|
||||
println!(" [{}] size={} ", smhd.get_type(), smhd.get_size());
|
||||
}
|
||||
|
||||
// trak.mdia.minf.stbl
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.stbl.get_type(), track.trak.mdia.minf.stbl.get_size());
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.stbl.stsd.get_type(), track.trak.mdia.minf.stbl.stsd.get_size());
|
||||
if let Some(ref avc1) = track.trak.mdia.minf.stbl.stsd.avc1 {
|
||||
println!(" [{}] size={} ", avc1.get_type(), avc1.get_size());
|
||||
}
|
||||
if let Some(ref mp4a) = track.trak.mdia.minf.stbl.stsd.mp4a {
|
||||
println!(" [{}] size={} ", mp4a.get_type(), mp4a.get_size());
|
||||
}
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.stbl.stts.get_type(), track.trak.mdia.minf.stbl.stts.get_size());
|
||||
if let Some(ref ctts) = track.trak.mdia.minf.stbl.ctts {
|
||||
println!(" [{}] size={} ", ctts.get_type(), ctts.get_size());
|
||||
}
|
||||
if let Some(ref stss) = track.trak.mdia.minf.stbl.stss {
|
||||
println!(" [{}] size={} ", stss.get_type(), stss.get_size());
|
||||
}
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.stbl.stsc.get_type(), track.trak.mdia.minf.stbl.stsc.get_size());
|
||||
println!(" [{}] size={} ", track.trak.mdia.minf.stbl.stsz.get_type(), track.trak.mdia.minf.stbl.stsz.get_size());
|
||||
if let Some(ref stco) = track.trak.mdia.minf.stbl.stco {
|
||||
println!(" [{}] size={} ", stco.get_type(), stco.get_size());
|
||||
}
|
||||
if let Some(ref co64) = track.trak.mdia.minf.stbl.co64 {
|
||||
println!(" [{}] size={} ", co64.get_type(), co64.get_size());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -43,6 +43,14 @@ impl Avc1Box {
|
|||
avcc: AvcCBox::new(&config.seq_param_set, &config.pic_param_set),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::Avc1Box
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + 8 + 70 + self.avcc.box_size()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for Avc1Box {
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct Co64Box {
|
|||
pub entries: Vec<u64>,
|
||||
}
|
||||
|
||||
impl Co64Box {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::Co64Box
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (8 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for Co64Box {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::Co64Box
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct CttsBox {
|
|||
pub entries: Vec<CttsEntry>,
|
||||
}
|
||||
|
||||
impl CttsBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::CttsBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (8 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct CttsEntry {
|
||||
pub sample_count: u32,
|
||||
|
|
|
@ -12,6 +12,18 @@ impl EdtsBox {
|
|||
pub(crate) fn new() -> EdtsBox {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::EdtsBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE;
|
||||
if let Some(ref elst) = self.elst {
|
||||
size += elst.box_size();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for EdtsBox {
|
||||
|
|
|
@ -18,6 +18,23 @@ pub struct ElstEntry {
|
|||
pub media_rate_fraction: u16,
|
||||
}
|
||||
|
||||
impl ElstBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::ElstBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE + 4;
|
||||
if self.version == 1 {
|
||||
size += self.entries.len() as u64 * 20;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
size += self.entries.len() as u64 * 12;
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for ElstBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::ElstBox
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct FtypBox {
|
|||
pub compatible_brands: Vec<FourCC>,
|
||||
}
|
||||
|
||||
impl FtypBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::FtypBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + 8 + (4 * self.compatible_brands.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for FtypBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::FtypBox
|
||||
|
|
|
@ -11,6 +11,16 @@ pub struct HdlrBox {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl HdlrBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::HdlrBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 20 + self.name.len() as u64 + 1
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for HdlrBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::HdlrBox
|
||||
|
|
|
@ -15,6 +15,25 @@ pub struct MdhdBox {
|
|||
pub language: String,
|
||||
}
|
||||
|
||||
impl MdhdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::MdhdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE;
|
||||
|
||||
if self.version == 1 {
|
||||
size += 28;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
size += 16;
|
||||
}
|
||||
size += 4;
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MdhdBox {
|
||||
fn default() -> Self {
|
||||
MdhdBox {
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct MdiaBox {
|
|||
pub minf: MinfBox,
|
||||
}
|
||||
|
||||
impl MdiaBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::MdiaBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + self.mdhd.box_size() + self.hdlr.box_size() + self.minf.box_size()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for MdiaBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::MdiaBox
|
||||
|
|
|
@ -10,6 +10,24 @@ pub struct MinfBox {
|
|||
pub stbl: StblBox,
|
||||
}
|
||||
|
||||
impl MinfBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::MinfBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE;
|
||||
if let Some(ref vmhd) = self.vmhd {
|
||||
size += vmhd.box_size();
|
||||
}
|
||||
if let Some(ref smhd) = self.smhd {
|
||||
size += smhd.box_size();
|
||||
}
|
||||
size += self.stbl.box_size();
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for MinfBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::MinfBox
|
||||
|
|
|
@ -9,6 +9,20 @@ pub struct MoovBox {
|
|||
pub traks: Vec<TrakBox>,
|
||||
}
|
||||
|
||||
impl MoovBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::MoovBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + self.mvhd.box_size();
|
||||
for trak in self.traks.iter() {
|
||||
size += trak.box_size();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for MoovBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::MoovBox
|
||||
|
|
|
@ -34,6 +34,18 @@ impl Mp4aBox {
|
|||
esds: Some(EsdsBox::new(config)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::Mp4aBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + 8 + 20;
|
||||
if let Some(ref esds) = self.esds {
|
||||
size += esds.box_size();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for Mp4aBox {
|
||||
|
|
|
@ -14,6 +14,24 @@ pub struct MvhdBox {
|
|||
pub rate: FixedPointU16,
|
||||
}
|
||||
|
||||
impl MvhdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::MvhdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE;
|
||||
if self.version == 1 {
|
||||
size += 28;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
size += 16;
|
||||
}
|
||||
size += 80;
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MvhdBox {
|
||||
fn default() -> Self {
|
||||
MvhdBox {
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct SmhdBox {
|
|||
pub balance: FixedPointI8,
|
||||
}
|
||||
|
||||
impl SmhdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::SmhdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SmhdBox {
|
||||
fn default() -> Self {
|
||||
SmhdBox {
|
||||
|
|
|
@ -18,6 +18,33 @@ pub struct StblBox {
|
|||
pub co64: Option<Co64Box>,
|
||||
}
|
||||
|
||||
impl StblBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StblBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE;
|
||||
size += self.stsd.box_size();
|
||||
size += self.stts.box_size();
|
||||
if let Some(ref ctts) = self.ctts {
|
||||
size += ctts.box_size();
|
||||
}
|
||||
if let Some(ref stss) = self.stss {
|
||||
size += stss.box_size();
|
||||
}
|
||||
size += self.stsc.box_size();
|
||||
size += self.stsz.box_size();
|
||||
if let Some(ref stco) = self.stco {
|
||||
size += stco.box_size();
|
||||
}
|
||||
if let Some(ref co64) = self.co64 {
|
||||
size += co64.box_size();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for StblBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::StblBox
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct StcoBox {
|
|||
pub entries: Vec<u32>,
|
||||
}
|
||||
|
||||
impl StcoBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StcoBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (4 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for StcoBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::StcoBox
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct StscBox {
|
|||
pub entries: Vec<StscEntry>,
|
||||
}
|
||||
|
||||
impl StscBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StscBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (12 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct StscEntry {
|
||||
pub first_chunk: u32,
|
||||
|
|
|
@ -12,6 +12,22 @@ pub struct StsdBox {
|
|||
pub mp4a: Option<Mp4aBox>,
|
||||
}
|
||||
|
||||
impl StsdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StsdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE + 4;
|
||||
if let Some(ref avc1) = self.avc1 {
|
||||
size += avc1.box_size();
|
||||
} else if let Some(ref mp4a) = self.mp4a {
|
||||
size += mp4a.box_size();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for StsdBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::StsdBox
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct StssBox {
|
|||
pub entries: Vec<u32>,
|
||||
}
|
||||
|
||||
impl StssBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StssBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (4 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for StssBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::StssBox
|
||||
|
|
|
@ -12,6 +12,16 @@ pub struct StszBox {
|
|||
pub sample_sizes: Vec<u32>,
|
||||
}
|
||||
|
||||
impl StszBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::StszBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 8 + (4 * self.sample_sizes.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for StszBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::StszBox
|
||||
|
|
|
@ -10,6 +10,16 @@ pub struct SttsBox {
|
|||
pub entries: Vec<SttsEntry>,
|
||||
}
|
||||
|
||||
impl SttsBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::SttsBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4 + (8 * self.entries.len() as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct SttsEntry {
|
||||
pub sample_count: u32,
|
||||
|
|
|
@ -52,6 +52,22 @@ pub struct Matrix {
|
|||
}
|
||||
|
||||
impl TkhdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::TkhdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE;
|
||||
if self.version == 1 {
|
||||
size += 32;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
size += 20;
|
||||
}
|
||||
size += 60;
|
||||
size
|
||||
}
|
||||
|
||||
pub fn set_width(&mut self, width: u16) {
|
||||
self.width = FixedPointU16::new(width);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,22 @@ pub struct TrakBox {
|
|||
pub mdia: MdiaBox,
|
||||
}
|
||||
|
||||
impl TrakBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::TrakBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE;
|
||||
size += self.tkhd.box_size();
|
||||
if let Some(ref edts) = self.edts {
|
||||
size += edts.box_size();
|
||||
}
|
||||
size += self.mdia.box_size();
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for TrakBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::TrakBox
|
||||
|
|
|
@ -18,6 +18,16 @@ pub struct RgbColor {
|
|||
pub blue: u16,
|
||||
}
|
||||
|
||||
impl VmhdBox {
|
||||
pub fn get_type(&self) -> BoxType {
|
||||
BoxType::VmhdBox
|
||||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 8
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for VmhdBox {
|
||||
fn box_type() -> BoxType {
|
||||
BoxType::VmhdBox
|
||||
|
|
Loading…
Reference in a new issue