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

Refactor BoxHeader

This commit is contained in:
Ian Jun 2020-07-30 15:34:15 +09:00
parent 4ce23997ad
commit 928fa66cf0
25 changed files with 197 additions and 149 deletions

View file

@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -65,7 +66,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Avc1Box {
let depth = reader.read_u16::<BigEndian>()?;
reader.read_i16::<BigEndian>()?; // pre-defined
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
if name == BoxType::AvcCBox {
let avcc = AvcCBox::read_box(reader, s)?;
@ -91,7 +92,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Avc1Box {
impl<W: Write> WriteBox<&mut BufWriter<W>> for Avc1Box {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
writer.write_u32::<BigEndian>(0)?; // reserved
writer.write_u16::<BigEndian>(0)?; // reserved
@ -187,7 +188,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for AvcCBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for AvcCBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
writer.write_u8(self.configuration_version)?;
writer.write_u8(self.avc_profile_indication)?;

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -47,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Co64Box {
impl<W: Write> WriteBox<&mut BufWriter<W>> for Co64Box {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -63,7 +64,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for Co64Box {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -82,7 +83,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::Co64Box);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,6 +1,7 @@
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use crate::*;
use crate::atoms::*;
use crate::atoms::elst::ElstBox;
@ -35,7 +36,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
let mut edts = EdtsBox::new();
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -55,7 +56,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for EdtsBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
if let Some(elst) = &self.elst {
elst.write_box(writer)?;

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -80,7 +81,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for ElstBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -104,7 +105,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for ElstBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -128,7 +129,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::ElstBox);
assert_eq!(src_box.box_size(), header.size);
@ -159,7 +160,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::ElstBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -51,7 +52,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for FtypBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
writer.write_u32::<BigEndian>((&self.major_brand).into())?;
writer.write_u32::<BigEndian>(self.minor_version)?;
@ -65,7 +66,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for FtypBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -89,7 +90,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::FtypBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -59,7 +60,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for HdlrBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -81,7 +82,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for HdlrBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -101,7 +102,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::HdlrBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -3,6 +3,7 @@ use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -92,7 +93,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdhdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for MdhdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -143,7 +144,7 @@ fn get_language_code(language: &str) -> u16 {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
fn test_language_code(lang: &str) {
@ -179,7 +180,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MdhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -209,7 +210,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MdhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,6 +1,7 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use crate::*;
use crate::atoms::*;
use crate::atoms::{mdhd::MdhdBox, hdlr::HdlrBox, minf::MinfBox};
@ -47,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -63,7 +64,10 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
let minf = MinfBox::read_box(reader, s)?;
mdia.minf = Some(minf);
}
_ => {}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
@ -78,7 +82,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for MdiaBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
if let Some(mdhd) = &self.mdhd {
mdhd.write_box(writer)?;

View file

@ -1,11 +1,8 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use crate::*;
use crate::atoms::{
vmhd::VmhdBox,
smhd::SmhdBox,
stbl::StblBox
};
use crate::atoms::*;
use crate::atoms::{vmhd::VmhdBox, smhd::SmhdBox, stbl::StblBox};
#[derive(Debug, Default)]
@ -51,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -63,12 +60,17 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
let smhd = SmhdBox::read_box(reader, s)?;
minf.smhd = Some(smhd);
}
BoxType::DinfBox => {}
BoxType::DinfBox => {// XXX warn!()
skip_box(reader, s)?;
}
BoxType::StblBox => {
let stbl = StblBox::read_box(reader, s)?;
minf.stbl = Some(stbl);
}
_ => {}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
@ -83,7 +85,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for MinfBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
if let Some(vmhd) = &self.vmhd {
vmhd.write_box(writer)?;

View file

@ -31,6 +31,8 @@ mod mp4a;
pub use ftyp::FtypBox;
pub use moov::MoovBox;
const HEADER_SIZE: u64 = 8;
// const HEADER_LARGE_SIZE: u64 = 16;
pub const HEADER_EXT_SIZE: u64 = 4;
macro_rules! boxtype {
@ -194,20 +196,50 @@ pub trait WriteBox<T>: Sized {
fn write_box(&self, _: T) -> Result<u64>;
}
pub fn read_box_header_ext<R: Read>(reader: &mut BufReader<R>) -> Result<(u8, u32)> {
let version = reader.read_u8()?;
let flags = reader.read_u24::<BigEndian>()?;
Ok((version, flags))
#[derive(Debug, Clone, Copy)]
pub struct BoxHeader {
pub name: BoxType,
pub size: u64,
}
pub fn write_box_header_ext<W: Write>(w: &mut BufWriter<W>, v: u8, f: u32) -> Result<u64> {
w.write_u8(v)?;
w.write_u24::<BigEndian>(f)?;
Ok(4)
}
impl BoxHeader {
fn new(name: BoxType, size: u64) -> Self {
Self { name, size }
}
impl<W: Write> WriteBox<&mut BufWriter<W>> for BoxHeader {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
// TODO: if size is 0, then this box is the last one in the file
pub fn read<R: Read>(reader: &mut BufReader<R>) -> Result<Self> {
// Create and read to buf.
let mut buf = [0u8;8]; // 8 bytes for box header.
reader.read(&mut buf)?;
// Get size.
let s = buf[0..4].try_into().unwrap();
let size = u32::from_be_bytes(s);
// Get box type string.
let t = buf[4..8].try_into().unwrap();
let typ = u32::from_be_bytes(t);
// Get largesize if size is 1
if size == 1 {
reader.read(&mut buf)?;
let s = buf.try_into().unwrap();
let largesize = u64::from_be_bytes(s);
Ok(BoxHeader {
name: BoxType::from(typ),
size: largesize,
})
} else {
Ok(BoxHeader {
name: BoxType::from(typ),
size: size as u64,
})
}
}
fn write<W: Write>(&self, writer: &mut BufWriter<W>) -> Result<u64> {
if self.size > u32::MAX as u64 {
writer.write_u32::<BigEndian>(1)?;
writer.write_u32::<BigEndian>(self.name.into())?;
@ -221,6 +253,18 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for BoxHeader {
}
}
pub fn read_box_header_ext<R: Read>(reader: &mut BufReader<R>) -> Result<(u8, u32)> {
let version = reader.read_u8()?;
let flags = reader.read_u24::<BigEndian>()?;
Ok((version, flags))
}
pub fn write_box_header_ext<W: Write>(w: &mut BufWriter<W>, v: u8, f: u32) -> Result<u64> {
w.write_u8(v)?;
w.write_u24::<BigEndian>(f)?;
Ok(4)
}
pub fn get_box_start<R: Seek>(reader: &mut BufReader<R>) -> Result<u64> {
Ok(reader.seek(SeekFrom::Current(0))? - HEADER_SIZE)
}
@ -236,6 +280,12 @@ pub fn skip_read_to<R: Read + Seek>(reader: &mut BufReader<R>, pos: u64) -> Resu
Ok(())
}
pub fn skip_box<R: Read + Seek>(reader: &mut BufReader<R>, size: u64) -> Result<()> {
let start = get_box_start(reader)?;
skip_read_to(reader, start + size)?;
Ok(())
}
pub fn skip_write<W: Write>(writer: &mut BufWriter<W>, size: u64) -> Result<()> {
for _ in 0..size {
writer.write_u8(0)?;

View file

@ -1,6 +1,7 @@
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, SeekFrom, Read, BufWriter, Write};
use crate::*;
use crate::atoms::*;
use crate::atoms::{mvhd::MvhdBox, trak::TrakBox};
@ -40,7 +41,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -51,8 +52,14 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
let trak = TrakBox::read_box(reader, s)?;
moov.traks.push(trak);
}
BoxType::UdtaBox => {}
_ => {}
BoxType::UdtaBox => {
// XXX warn!()
skip_box(reader, s)?;
}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
@ -67,7 +74,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for MoovBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
self.mvhd.write_box(writer)?;
for trak in self.traks.iter() {

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -49,7 +50,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Mp4aBox {
reader.read_u32::<BigEndian>()?; // pre-defined, reserved
let samplerate = reader.read_u32::<BigEndian>()?;
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
if name == BoxType::EsdsBox {
let esds = EsdsBox::read_box(reader, s)?;
@ -72,7 +73,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Mp4aBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for Mp4aBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
writer.write_u32::<BigEndian>(0)?; // reserved
writer.write_u16::<BigEndian>(0)?; // reserved
@ -129,7 +130,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EsdsBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for EsdsBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;

View file

@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -91,7 +92,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for MvhdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -119,7 +120,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for MvhdBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -142,7 +143,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MvhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -172,7 +173,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MvhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -54,7 +55,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SmhdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for SmhdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -69,7 +70,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for SmhdBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -88,7 +89,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::SmhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,6 +1,7 @@
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, SeekFrom, Read, BufWriter, Write};
use crate::*;
use crate::atoms::*;
use crate::atoms::{
stsd::StsdBox,
stts::SttsBox,
@ -71,7 +72,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -103,7 +104,10 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
let co64 = Co64Box::read_box(reader, s)?;
stbl.co64 = Some(co64);
}
_ => {}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
}
@ -117,7 +121,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StblBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
if let Some(stsd) = &self.stsd {
stsd.write_box(writer)?;

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -47,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StcoBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StcoBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -63,7 +64,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for StcoBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -82,7 +83,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::StcoBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -58,7 +59,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StscBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StscBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -76,7 +77,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for StscBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -106,7 +107,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::StscBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
use crate::atoms::{avc::Avc1Box, mp4a::Mp4aBox};
@ -41,7 +42,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
let mut mp4a = None;
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -68,7 +69,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StsdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -47,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StssBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StssBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -63,7 +64,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for StssBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -82,7 +83,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::StssBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -52,7 +53,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StszBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for StszBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -71,7 +72,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for StszBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -91,7 +92,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::StszBox);
assert_eq!(src_box.box_size(), header.size);
@ -118,7 +119,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::StszBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -56,7 +57,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SttsBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for SttsBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -73,7 +74,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for SttsBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -95,7 +96,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::SttsBox);
assert_eq!(src_box.box_size(), header.size);
@ -124,7 +125,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::SttsBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
use crate::*;
use crate::atoms::*;
#[derive(Debug, PartialEq)]
@ -140,7 +141,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for TkhdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -186,7 +187,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for TkhdBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -224,7 +225,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::TkhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -269,7 +270,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::TkhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,6 +1,7 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use crate::*;
use crate::atoms::*;
use crate::atoms::{tkhd::TkhdBox, edts::EdtsBox, mdia::MdiaBox};
@ -47,7 +48,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader)?;
let header = BoxHeader::read(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -63,7 +64,10 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
let mdia = MdiaBox::read_box(reader, s)?;
trak.mdia = Some(mdia);
}
_ => {}
_ => {
// XXX warn!()
skip_box(reader, s)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
@ -78,7 +82,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for TrakBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
if let Some(tkhd) = &self.tkhd {
tkhd.write_box(writer)?;

View file

@ -2,6 +2,7 @@ use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
use crate::atoms::*;
#[derive(Debug, Default, PartialEq)]
@ -56,7 +57,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
impl<W: Write> WriteBox<&mut BufWriter<W>> for VmhdBox {
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
let size = self.box_size();
BoxHeader::new(Self::box_type(), size).write_box(writer)?;
BoxHeader::new(Self::box_type(), size).write(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -73,7 +74,7 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for VmhdBox {
#[cfg(test)]
mod tests {
use super::*;
use crate::read_box_header;
use crate::atoms::BoxHeader;
use std::io::Cursor;
#[test]
@ -93,7 +94,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader).unwrap();
let header = BoxHeader::read(&mut reader).unwrap();
assert_eq!(header.name, BoxType::VmhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, Read, SeekFrom, Seek};
use std::io::{BufReader, SeekFrom, Seek};
use std::fs::File;
use std::convert::TryInto;
@ -10,9 +10,6 @@ pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
// XXX if box has largesize
const HEADER_SIZE: u64 = 8;
#[derive(Debug, PartialEq)]
pub enum TrackType {
Audio,
@ -34,18 +31,6 @@ impl BMFF {
}
}
#[derive(Debug, Clone, Copy)]
struct BoxHeader {
name: BoxType,
size: u64,
}
impl BoxHeader {
fn new(name: BoxType, size: u64) -> Self {
Self { name, size }
}
}
pub fn read_mp4(f: File) -> Result<BMFF> {
// Open file and read boxes.
@ -62,9 +47,8 @@ fn read_boxes(f: File) -> Result<BMFF> {
let mut current = reader.seek(SeekFrom::Current(0))?;
while current < filesize {
// Get box header.
let header = read_box_header(&mut reader)?;
let header = BoxHeader::read(&mut reader)?;
let BoxHeader{ name, size } = header;
// Match and parse the atom boxes.
@ -73,50 +57,25 @@ fn read_boxes(f: File) -> Result<BMFF> {
let ftyp = FtypBox::read_box(&mut reader, size)?;
bmff.ftyp = ftyp;
}
BoxType::FreeBox => {}
BoxType::MdatBox => {}
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 => {}
_ => {}
BoxType::MoofBox => {
skip_box(&mut reader, size)?;
}
_ => {
// XXX warn!()
skip_box(&mut reader, size)?;
}
}
current = reader.seek(SeekFrom::Current(0))?;
}
Ok(bmff)
}
// TODO: if size is 0, then this box is the last one in the file
fn read_box_header<R: Read>(reader: &mut BufReader<R>) -> Result<BoxHeader> {
// Create and read to buf.
let mut buf = [0u8;8]; // 8 bytes for box header.
reader.read(&mut buf)?;
// Get size.
let s = buf[0..4].try_into().unwrap();
let size = u32::from_be_bytes(s);
// Get box type string.
let t = buf[4..8].try_into().unwrap();
let typ = u32::from_be_bytes(t);
// Get largesize if size is 1
if size == 1 {
reader.read(&mut buf)?;
let s = buf.try_into().unwrap();
let largesize = u64::from_be_bytes(s);
Ok(BoxHeader {
name: BoxType::from(typ),
size: largesize,
})
} else {
Ok(BoxHeader {
name: BoxType::from(typ),
size: size as u64,
})
}
}