diff --git a/examples/mp4dump.rs b/examples/mp4dump.rs new file mode 100644 index 0000000..33b3ec0 --- /dev/null +++ b/examples/mp4dump.rs @@ -0,0 +1,116 @@ +use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::io::{self, BufReader}; +use std::path::Path; + +use mp4::{Result, Mp4Box}; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 2 { + println!("Usage: mp4dump "); + std::process::exit(1); + } + + if let Err(err) = dump(&args[1]) { + let _ = writeln!(io::stderr(), "{}", err); + } +} + +fn dump>(filename: &P) -> Result<()> { + let f = File::open(filename)?; + let boxes = get_boxes(f)?; + + // print out boxes + for b in boxes.iter() { + println!("[{}] size={}", b.name, b.size); + } + + Ok(()) +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct Box { + name: String, + size: u64, + indent: u32, +} + +fn get_boxes(file: File) -> Result> { + let size = file.metadata()?.len(); + let reader = BufReader::new(file); + let mp4 = mp4::Mp4Reader::read_header(reader, size)?; + + // collect known boxes + let mut boxes = Vec::new(); + + // ftyp, moov, mvhd + boxes.push(build_box(&mp4.ftyp)); + boxes.push(build_box(&mp4.moov)); + boxes.push(build_box(&mp4.moov.mvhd)); + + // trak. + for track in mp4.tracks().iter() { + boxes.push(build_box(&track.trak)); + boxes.push(build_box(&track.trak.tkhd)); + if let Some(ref edts) = track.trak.edts { + boxes.push(build_box(edts)); + if let Some(ref elst) = edts.elst { + boxes.push(build_box(elst)); + } + } + + // trak.mdia + let mdia = &track.trak.mdia; + boxes.push(build_box(mdia)); + boxes.push(build_box(&mdia.mdhd)); + boxes.push(build_box(&mdia.hdlr)); + boxes.push(build_box(&track.trak.mdia.minf)); + + // trak.mdia.minf + let minf = &track.trak.mdia.minf; + if let Some(ref vmhd) = &minf.vmhd { + boxes.push(build_box(vmhd)); + } + if let Some(ref smhd) = &minf.smhd { + boxes.push(build_box(smhd)); + } + + // trak.mdia.minf.stbl + let stbl = &track.trak.mdia.minf.stbl; + boxes.push(build_box(stbl)); + boxes.push(build_box(&stbl.stsd)); + if let Some(ref avc1) = &stbl.stsd.avc1 { + boxes.push(build_box(avc1)); + } + if let Some(ref mp4a) = &stbl.stsd.mp4a { + boxes.push(build_box(mp4a)); + } + boxes.push(build_box(&stbl.stts)); + if let Some(ref ctts) = &stbl.ctts { + boxes.push(build_box(ctts)); + } + if let Some(ref stss) = &stbl.stss { + boxes.push(build_box(stss)); + } + boxes.push(build_box(&stbl.stsc)); + boxes.push(build_box(&stbl.stsz)); + if let Some(ref stco) = &stbl.stco { + boxes.push(build_box(stco)); + } + if let Some(ref co64) = &stbl.co64 { + boxes.push(build_box(co64)); + } + } + Ok(boxes) +} + +fn build_box(ref m: &M) -> Box { + return Box{ + name: m.box_type().to_string(), + size: m.box_size(), + indent: 0, + }; +} diff --git a/examples/simple.rs b/examples/simple.rs new file mode 100644 index 0000000..783150a --- /dev/null +++ b/examples/simple.rs @@ -0,0 +1,27 @@ +use mp4; +use std::env; +use std::fs::File; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 2 { + println!("Usage: mp4dump "); + std::process::exit(1); + } + + let filename = &args[1]; + let f = File::open(filename).unwrap(); + let mp4 = mp4::read_mp4(f).unwrap(); + + println!("Major Brand: {}", mp4.major_brand()); + + for track in mp4.tracks().iter() { + println!("Track: #{}({}) {} {}", + track.track_id(), + track.language(), + track.track_type().unwrap(), + track.box_type().unwrap(), + ); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fde9222..5cfa938 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +use std::io::{BufReader}; +use std::fs::File; + mod error; pub use error::Error; @@ -7,6 +10,7 @@ mod types; pub use types::*; mod mp4box; +pub use mp4box::{Mp4Box}; mod track; pub use track::{Mp4Track, TrackConfig}; @@ -16,3 +20,10 @@ pub use reader::Mp4Reader; mod writer; pub use writer::{Mp4Config, Mp4Writer}; + +pub fn read_mp4(f: File) -> Result>> { + let size = f.metadata()?.len(); + let reader = BufReader::new(f); + let mp4 = reader::Mp4Reader::read_header(reader, size)?; + Ok(mp4) +} \ No newline at end of file diff --git a/src/mp4box/avc1.rs b/src/mp4box/avc1.rs index 27f428e..f051c6c 100644 --- a/src/mp4box/avc1.rs +++ b/src/mp4box/avc1.rs @@ -43,18 +43,26 @@ impl Avc1Box { avcc: AvcCBox::new(&config.seq_param_set, &config.pic_param_set), } } -} -impl Mp4Box for Avc1Box { - fn box_type() -> BoxType { + pub fn get_type(&self) -> BoxType { BoxType::Avc1Box } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { HEADER_SIZE + 8 + 70 + self.avcc.box_size() } } +impl Mp4Box for Avc1Box { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for Avc1Box { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -102,7 +110,7 @@ impl ReadBox<&mut R> for Avc1Box { impl WriteBox<&mut W> for Avc1Box { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; writer.write_u32::(0)?; // reserved writer.write_u16::(0)?; // reserved @@ -154,7 +162,7 @@ impl AvcCBox { } impl Mp4Box for AvcCBox { - fn box_type() -> BoxType { + fn box_type(&self) -> BoxType { BoxType::AvcCBox } @@ -209,7 +217,7 @@ impl ReadBox<&mut R> for AvcCBox { impl WriteBox<&mut W> for AvcCBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; writer.write_u8(self.configuration_version)?; writer.write_u8(self.avc_profile_indication)?; diff --git a/src/mp4box/co64.rs b/src/mp4box/co64.rs index 511db77..829acf8 100644 --- a/src/mp4box/co64.rs +++ b/src/mp4box/co64.rs @@ -10,16 +10,26 @@ pub struct Co64Box { pub entries: Vec, } -impl Mp4Box for Co64Box { - fn box_type() -> BoxType { +impl Co64Box { + pub fn get_type(&self) -> BoxType { BoxType::Co64Box } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for Co64Box { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -46,7 +56,7 @@ impl ReadBox<&mut R> for Co64Box { impl WriteBox<&mut W> for Co64Box { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/ctts.rs b/src/mp4box/ctts.rs index 49d666a..db0ccd3 100644 --- a/src/mp4box/ctts.rs +++ b/src/mp4box/ctts.rs @@ -10,6 +10,16 @@ pub struct CttsBox { pub entries: Vec, } +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, @@ -17,12 +27,12 @@ pub struct CttsEntry { } impl Mp4Box for CttsBox { - fn box_type() -> BoxType { - BoxType::CttsBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_size(&self) -> u64 { - HEADER_SIZE + HEADER_EXT_SIZE + 4 + (8 * self.entries.len() as u64) + return self.get_size(); } } @@ -55,7 +65,7 @@ impl ReadBox<&mut R> for CttsBox { impl WriteBox<&mut W> for CttsBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/edts.rs b/src/mp4box/edts.rs index c36b59c..2cd0d09 100644 --- a/src/mp4box/edts.rs +++ b/src/mp4box/edts.rs @@ -12,14 +12,12 @@ impl EdtsBox { pub(crate) fn new() -> EdtsBox { Default::default() } -} -impl Mp4Box for EdtsBox { - fn box_type() -> BoxType { + pub fn get_type(&self) -> BoxType { BoxType::EdtsBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { let mut size = HEADER_SIZE; if let Some(ref elst) = self.elst { size += elst.box_size(); @@ -28,6 +26,16 @@ impl Mp4Box for EdtsBox { } } +impl Mp4Box for EdtsBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for EdtsBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -54,7 +62,7 @@ impl ReadBox<&mut R> for EdtsBox { impl WriteBox<&mut W> for EdtsBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; if let Some(ref elst) = self.elst { elst.write_box(writer)?; diff --git a/src/mp4box/elst.rs b/src/mp4box/elst.rs index ecd1d32..ebbbaf0 100644 --- a/src/mp4box/elst.rs +++ b/src/mp4box/elst.rs @@ -18,12 +18,12 @@ pub struct ElstEntry { pub media_rate_fraction: u16, } -impl Mp4Box for ElstBox { - fn box_type() -> BoxType { +impl ElstBox { + pub fn get_type(&self) -> BoxType { BoxType::ElstBox } - fn box_size(&self) -> u64 { + 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; @@ -35,6 +35,16 @@ impl Mp4Box for ElstBox { } } +impl Mp4Box for ElstBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for ElstBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -78,7 +88,7 @@ impl ReadBox<&mut R> for ElstBox { impl WriteBox<&mut W> for ElstBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/ftyp.rs b/src/mp4box/ftyp.rs index 418f3a0..dfdf524 100644 --- a/src/mp4box/ftyp.rs +++ b/src/mp4box/ftyp.rs @@ -10,16 +10,26 @@ pub struct FtypBox { pub compatible_brands: Vec, } -impl Mp4Box for FtypBox { - fn box_type() -> BoxType { +impl FtypBox { + pub fn get_type(&self) -> BoxType { BoxType::FtypBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { HEADER_SIZE + 8 + (4 * self.compatible_brands.len() as u64) } } +impl Mp4Box for FtypBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for FtypBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -50,7 +60,7 @@ impl ReadBox<&mut R> for FtypBox { impl WriteBox<&mut W> for FtypBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; writer.write_u32::((&self.major_brand).into())?; writer.write_u32::(self.minor_version)?; diff --git a/src/mp4box/hdlr.rs b/src/mp4box/hdlr.rs index a7bf34b..62d7a32 100644 --- a/src/mp4box/hdlr.rs +++ b/src/mp4box/hdlr.rs @@ -11,16 +11,26 @@ pub struct HdlrBox { pub name: String, } -impl Mp4Box for HdlrBox { - fn box_type() -> BoxType { +impl HdlrBox { + pub fn get_type(&self) -> BoxType { BoxType::HdlrBox } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for HdlrBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -58,7 +68,7 @@ impl ReadBox<&mut R> for HdlrBox { impl WriteBox<&mut W> for HdlrBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/mdhd.rs b/src/mp4box/mdhd.rs index 5e53982..7696088 100644 --- a/src/mp4box/mdhd.rs +++ b/src/mp4box/mdhd.rs @@ -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 { @@ -30,21 +49,12 @@ impl Default for MdhdBox { } impl Mp4Box for MdhdBox { - fn box_type() -> BoxType { - BoxType::MdhdBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_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 + return self.get_size(); } } @@ -90,7 +100,7 @@ impl ReadBox<&mut R> for MdhdBox { impl WriteBox<&mut W> for MdhdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/mdia.rs b/src/mp4box/mdia.rs index cf7ff07..e8ea27a 100644 --- a/src/mp4box/mdia.rs +++ b/src/mp4box/mdia.rs @@ -10,16 +10,26 @@ pub struct MdiaBox { pub minf: MinfBox, } -impl Mp4Box for MdiaBox { - fn box_type() -> BoxType { +impl MdiaBox { + pub fn get_type(&self) -> BoxType { BoxType::MdiaBox } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for MdiaBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -77,7 +87,7 @@ impl ReadBox<&mut R> for MdiaBox { impl WriteBox<&mut W> for MdiaBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; self.mdhd.write_box(writer)?; self.hdlr.write_box(writer)?; diff --git a/src/mp4box/minf.rs b/src/mp4box/minf.rs index 0da39a9..1dad192 100644 --- a/src/mp4box/minf.rs +++ b/src/mp4box/minf.rs @@ -10,12 +10,12 @@ pub struct MinfBox { pub stbl: StblBox, } -impl Mp4Box for MinfBox { - fn box_type() -> BoxType { +impl MinfBox { + pub fn get_type(&self) -> BoxType { BoxType::MinfBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { let mut size = HEADER_SIZE; if let Some(ref vmhd) = self.vmhd { size += vmhd.box_size(); @@ -28,6 +28,16 @@ impl Mp4Box for MinfBox { } } +impl Mp4Box for MinfBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for MinfBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -83,7 +93,7 @@ impl ReadBox<&mut R> for MinfBox { impl WriteBox<&mut W> for MinfBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; if let Some(ref vmhd) = self.vmhd { vmhd.write_box(writer)?; diff --git a/src/mp4box/mod.rs b/src/mp4box/mod.rs index 0721e2c..180a96c 100644 --- a/src/mp4box/mod.rs +++ b/src/mp4box/mod.rs @@ -99,7 +99,7 @@ boxtype! { } pub trait Mp4Box: Sized { - fn box_type() -> BoxType; + fn box_type(&self) -> BoxType; fn box_size(&self) -> u64; } diff --git a/src/mp4box/moov.rs b/src/mp4box/moov.rs index 045440e..3a9cae5 100644 --- a/src/mp4box/moov.rs +++ b/src/mp4box/moov.rs @@ -9,12 +9,12 @@ pub struct MoovBox { pub traks: Vec, } -impl Mp4Box for MoovBox { - fn box_type() -> BoxType { +impl MoovBox { + pub fn get_type(&self) -> BoxType { BoxType::MoovBox } - fn box_size(&self) -> u64 { + 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(); @@ -23,6 +23,16 @@ impl Mp4Box for MoovBox { } } +impl Mp4Box for MoovBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for MoovBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -74,7 +84,7 @@ impl ReadBox<&mut R> for MoovBox { impl WriteBox<&mut W> for MoovBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; self.mvhd.write_box(writer)?; for trak in self.traks.iter() { diff --git a/src/mp4box/mp4a.rs b/src/mp4box/mp4a.rs index 77d0b3f..8a44cff 100644 --- a/src/mp4box/mp4a.rs +++ b/src/mp4box/mp4a.rs @@ -34,14 +34,12 @@ impl Mp4aBox { esds: Some(EsdsBox::new(config)), } } -} -impl Mp4Box for Mp4aBox { - fn box_type() -> BoxType { + pub fn get_type(&self) -> BoxType { BoxType::Mp4aBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { let mut size = HEADER_SIZE + 8 + 20; if let Some(ref esds) = self.esds { size += esds.box_size(); @@ -50,6 +48,16 @@ impl Mp4Box for Mp4aBox { } } +impl Mp4Box for Mp4aBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for Mp4aBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -86,7 +94,7 @@ impl ReadBox<&mut R> for Mp4aBox { impl WriteBox<&mut W> for Mp4aBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; writer.write_u32::(0)?; // reserved writer.write_u16::(0)?; // reserved @@ -124,7 +132,7 @@ impl EsdsBox { } impl Mp4Box for EsdsBox { - fn box_type() -> BoxType { + fn box_type(&self) -> BoxType { BoxType::EsdsBox } @@ -171,7 +179,7 @@ impl ReadBox<&mut R> for EsdsBox { impl WriteBox<&mut W> for EsdsBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/mvhd.rs b/src/mp4box/mvhd.rs index bd38fbf..377bab8 100644 --- a/src/mp4box/mvhd.rs +++ b/src/mp4box/mvhd.rs @@ -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 { @@ -29,20 +47,12 @@ impl Default for MvhdBox { } impl Mp4Box for MvhdBox { - fn box_type() -> BoxType { - BoxType::MvhdBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_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 + return self.get_size(); } } @@ -87,7 +97,7 @@ impl ReadBox<&mut R> for MvhdBox { impl WriteBox<&mut W> for MvhdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/smhd.rs b/src/mp4box/smhd.rs index 3879a18..454bea9 100644 --- a/src/mp4box/smhd.rs +++ b/src/mp4box/smhd.rs @@ -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 { @@ -21,12 +31,12 @@ impl Default for SmhdBox { } impl Mp4Box for SmhdBox { - fn box_type() -> BoxType { - BoxType::SmhdBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_size(&self) -> u64 { - HEADER_SIZE + HEADER_EXT_SIZE + 4 + return self.get_size(); } } @@ -51,7 +61,7 @@ impl ReadBox<&mut R> for SmhdBox { impl WriteBox<&mut W> for SmhdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stbl.rs b/src/mp4box/stbl.rs index 8f7db65..0d37416 100644 --- a/src/mp4box/stbl.rs +++ b/src/mp4box/stbl.rs @@ -18,12 +18,12 @@ pub struct StblBox { pub co64: Option, } -impl Mp4Box for StblBox { - fn box_type() -> BoxType { +impl StblBox { + pub fn get_type(&self) -> BoxType { BoxType::StblBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { let mut size = HEADER_SIZE; size += self.stsd.box_size(); size += self.stts.box_size(); @@ -45,6 +45,16 @@ impl Mp4Box for StblBox { } } +impl Mp4Box for StblBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for StblBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -132,7 +142,7 @@ impl ReadBox<&mut R> for StblBox { impl WriteBox<&mut W> for StblBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; self.stsd.write_box(writer)?; self.stts.write_box(writer)?; diff --git a/src/mp4box/stco.rs b/src/mp4box/stco.rs index 301cb50..c63295a 100644 --- a/src/mp4box/stco.rs +++ b/src/mp4box/stco.rs @@ -10,16 +10,26 @@ pub struct StcoBox { pub entries: Vec, } -impl Mp4Box for StcoBox { - fn box_type() -> BoxType { +impl StcoBox { + pub fn get_type(&self) -> BoxType { BoxType::StcoBox } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for StcoBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -46,7 +56,7 @@ impl ReadBox<&mut R> for StcoBox { impl WriteBox<&mut W> for StcoBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stsc.rs b/src/mp4box/stsc.rs index fe83cc7..78b7686 100644 --- a/src/mp4box/stsc.rs +++ b/src/mp4box/stsc.rs @@ -10,6 +10,16 @@ pub struct StscBox { pub entries: Vec, } +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, @@ -19,12 +29,12 @@ pub struct StscEntry { } impl Mp4Box for StscBox { - fn box_type() -> BoxType { - BoxType::StscBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_size(&self) -> u64 { - HEADER_SIZE + HEADER_EXT_SIZE + 4 + (12 * self.entries.len() as u64) + return self.get_size(); } } @@ -72,7 +82,7 @@ impl ReadBox<&mut R> for StscBox { impl WriteBox<&mut W> for StscBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stsd.rs b/src/mp4box/stsd.rs index 5731c7f..d09da49 100644 --- a/src/mp4box/stsd.rs +++ b/src/mp4box/stsd.rs @@ -12,12 +12,12 @@ pub struct StsdBox { pub mp4a: Option, } -impl Mp4Box for StsdBox { - fn box_type() -> BoxType { +impl StsdBox { + pub fn get_type(&self) -> BoxType { BoxType::StsdBox } - fn box_size(&self) -> u64 { + 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(); @@ -28,6 +28,16 @@ impl Mp4Box for StsdBox { } } +impl Mp4Box for StsdBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for StsdBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -67,7 +77,7 @@ impl ReadBox<&mut R> for StsdBox { impl WriteBox<&mut W> for StsdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stss.rs b/src/mp4box/stss.rs index 412174b..6d60bd9 100644 --- a/src/mp4box/stss.rs +++ b/src/mp4box/stss.rs @@ -10,16 +10,26 @@ pub struct StssBox { pub entries: Vec, } -impl Mp4Box for StssBox { - fn box_type() -> BoxType { +impl StssBox { + pub fn get_type(&self) -> BoxType { BoxType::StssBox } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for StssBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -46,7 +56,7 @@ impl ReadBox<&mut R> for StssBox { impl WriteBox<&mut W> for StssBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stsz.rs b/src/mp4box/stsz.rs index 99a4de6..78fc0e6 100644 --- a/src/mp4box/stsz.rs +++ b/src/mp4box/stsz.rs @@ -12,16 +12,26 @@ pub struct StszBox { pub sample_sizes: Vec, } -impl Mp4Box for StszBox { - fn box_type() -> BoxType { +impl StszBox { + pub fn get_type(&self) -> BoxType { BoxType::StszBox } - fn box_size(&self) -> u64 { + 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(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for StszBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -53,7 +63,7 @@ impl ReadBox<&mut R> for StszBox { impl WriteBox<&mut W> for StszBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/stts.rs b/src/mp4box/stts.rs index 8ca673f..bb46d5b 100644 --- a/src/mp4box/stts.rs +++ b/src/mp4box/stts.rs @@ -10,6 +10,16 @@ pub struct SttsBox { pub entries: Vec, } +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, @@ -17,12 +27,12 @@ pub struct SttsEntry { } impl Mp4Box for SttsBox { - fn box_type() -> BoxType { - BoxType::SttsBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_size(&self) -> u64 { - HEADER_SIZE + HEADER_EXT_SIZE + 4 + (8 * self.entries.len() as u64) + return self.get_size(); } } @@ -55,7 +65,7 @@ impl ReadBox<&mut R> for SttsBox { impl WriteBox<&mut W> for SttsBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/tkhd.rs b/src/mp4box/tkhd.rs index effe5c2..9023269 100644 --- a/src/mp4box/tkhd.rs +++ b/src/mp4box/tkhd.rs @@ -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); } @@ -62,20 +78,12 @@ impl TkhdBox { } impl Mp4Box for TkhdBox { - fn box_type() -> BoxType { - BoxType::TkhdBox + fn box_type(&self) -> BoxType { + return self.get_type(); } fn box_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 + return self.get_size(); } } @@ -146,7 +154,7 @@ impl ReadBox<&mut R> for TkhdBox { impl WriteBox<&mut W> for TkhdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?; diff --git a/src/mp4box/trak.rs b/src/mp4box/trak.rs index 30e0353..2c9724f 100644 --- a/src/mp4box/trak.rs +++ b/src/mp4box/trak.rs @@ -10,12 +10,12 @@ pub struct TrakBox { pub mdia: MdiaBox, } -impl Mp4Box for TrakBox { - fn box_type() -> BoxType { +impl TrakBox { + pub fn get_type(&self) -> BoxType { BoxType::TrakBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { let mut size = HEADER_SIZE; size += self.tkhd.box_size(); if let Some(ref edts) = self.edts { @@ -26,6 +26,16 @@ impl Mp4Box for TrakBox { } } +impl Mp4Box for TrakBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for TrakBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -80,7 +90,7 @@ impl ReadBox<&mut R> for TrakBox { impl WriteBox<&mut W> for TrakBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; self.tkhd.write_box(writer)?; if let Some(ref edts) = self.edts { diff --git a/src/mp4box/vmhd.rs b/src/mp4box/vmhd.rs index 623c2ff..685a3eb 100644 --- a/src/mp4box/vmhd.rs +++ b/src/mp4box/vmhd.rs @@ -18,16 +18,26 @@ pub struct RgbColor { pub blue: u16, } -impl Mp4Box for VmhdBox { - fn box_type() -> BoxType { +impl VmhdBox { + pub fn get_type(&self) -> BoxType { BoxType::VmhdBox } - fn box_size(&self) -> u64 { + pub fn get_size(&self) -> u64 { HEADER_SIZE + HEADER_EXT_SIZE + 8 } } +impl Mp4Box for VmhdBox { + fn box_type(&self) -> BoxType { + return self.get_type(); + } + + fn box_size(&self) -> u64 { + return self.get_size(); + } +} + impl ReadBox<&mut R> for VmhdBox { fn read_box(reader: &mut R, size: u64) -> Result { let start = box_start(reader)?; @@ -55,7 +65,7 @@ impl ReadBox<&mut R> for VmhdBox { impl WriteBox<&mut W> for VmhdBox { fn write_box(&self, writer: &mut W) -> Result { let size = self.box_size(); - BoxHeader::new(Self::box_type(), size).write(writer)?; + BoxHeader::new(self.box_type(), size).write(writer)?; write_box_header_ext(writer, self.version, self.flags)?;