1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-06-10 17:09:22 +00:00

Improve ReadBox::read_box()

This commit is contained in:
Ian Jun 2020-07-30 14:03:35 +09:00
parent f09085f75e
commit 948dc016d9
16 changed files with 181 additions and 168 deletions

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
@ -33,7 +33,7 @@ impl Default for Avc1Box {
}
impl Mp4Box for Avc1Box {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::Avc1Box
}
@ -44,7 +44,7 @@ impl Mp4Box for Avc1Box {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Avc1Box {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
reader.read_u32::<BigEndian>()?; // reserved
reader.read_u16::<BigEndian>()?; // reserved
@ -61,19 +61,16 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Avc1Box {
let vertresolution = Ratio::new_raw(vertnumer, 0x10000);
reader.read_u32::<BigEndian>()?; // reserved
let frame_count = reader.read_u16::<BigEndian>()?;
// skip compressorname
for _ in 0..4 {
reader.read_u64::<BigEndian>()?;
}
skip_read(reader, 32)?; // compressorname
let depth = reader.read_u16::<BigEndian>()?;
reader.read_i16::<BigEndian>()?; // pre-defined
let header = read_box_header(reader, 0)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
if name == BoxType::AvcCBox {
let avcc = AvcCBox::read_box(reader, s)?;
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(Avc1Box {
data_reference_index,
@ -94,7 +91,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_box(writer)?;
writer.write_u32::<BigEndian>(0)?; // reserved
writer.write_u16::<BigEndian>(0)?; // reserved
@ -135,7 +132,7 @@ pub struct AvcCBox {
}
impl Mp4Box for AvcCBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::AvcCBox
}
@ -153,7 +150,7 @@ impl Mp4Box for AvcCBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for AvcCBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let configuration_version = reader.read_u8()?;
let avc_profile_indication = reader.read_u8()?;
@ -173,8 +170,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for AvcCBox {
picture_parameter_sets.push(nal_unit);
}
// TODO
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(AvcCBox {
configuration_version,
@ -191,7 +187,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_box(writer)?;
writer.write_u8(self.configuration_version)?;
writer.write_u8(self.avc_profile_indication)?;

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use crate::*;
use crate::atoms::elst::ElstBox;
@ -16,7 +16,7 @@ impl EdtsBox {
}
impl Mp4Box for EdtsBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::EdtsBox
}
@ -31,24 +31,22 @@ impl Mp4Box for EdtsBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let mut edts = EdtsBox::new();
let start = 0u64;
while start < size {
// Get box header.
let header = read_box_header(reader, start)?;
let BoxHeader{ name, size: s } = header;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
BoxType::ElstBox => {
let elst = ElstBox::read_box(reader, s)?;
edts.elst = Some(elst);
}
_ => break
match name {
BoxType::ElstBox => {
let elst = ElstBox::read_box(reader, s)?;
edts.elst = Some(elst);
}
_ => {}
}
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(edts)
}
@ -57,7 +55,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_box(writer)?;
if let Some(elst) = &self.elst {
elst.write_box(writer)?;

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
@ -20,7 +20,7 @@ pub struct ElstEntry {
}
impl Mp4Box for ElstBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::ElstBox
}
@ -38,7 +38,7 @@ impl Mp4Box for ElstBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
@ -66,7 +66,8 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
};
entries.push(entry);
}
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(ElstBox {
version,
@ -79,7 +80,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -127,7 +128,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::ElstBox);
assert_eq!(src_box.box_size(), header.size);
@ -158,7 +159,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::ElstBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -12,7 +12,7 @@ pub struct FtypBox {
}
impl Mp4Box for FtypBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::FtypBox
}
@ -23,6 +23,8 @@ impl Mp4Box for FtypBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let start = get_box_start(reader)?;
let major = reader.read_u32::<BigEndian>()?;
let minor = reader.read_u32::<BigEndian>()?;
if size % 4 != 0 {
@ -36,6 +38,8 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
brands.push(From::from(b));
}
skip_read_to(reader, start + size)?;
Ok(FtypBox {
major_brand: From::from(major),
minor_version: minor,
@ -47,7 +51,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_box(writer)?;
writer.write_u32::<BigEndian>((&self.major_brand).into())?;
writer.write_u32::<BigEndian>(self.minor_version)?;
@ -85,7 +89,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::FtypBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
@ -13,7 +13,7 @@ pub struct HdlrBox {
}
impl Mp4Box for HdlrBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::HdlrBox
}
@ -24,16 +24,16 @@ impl Mp4Box for HdlrBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
reader.read_u32::<BigEndian>()?; // pre-defined
let handler = reader.read_u32::<BigEndian>()?;
let n = reader.seek(SeekFrom::Current(12))?; // 12 bytes reserved.
skip_read(reader, 12)?; // reserved
let buf_size = (size - (n - current)) - HEADER_SIZE - 1;
let buf_size = size - HEADER_SIZE - HEADER_EXT_SIZE - 20 - 1;
let mut buf = vec![0u8; buf_size as usize];
reader.read_exact(&mut buf)?;
@ -45,7 +45,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
_ => String::from("null"),
};
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(HdlrBox {
version,
@ -59,7 +59,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -101,7 +101,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::HdlrBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
@ -31,7 +31,7 @@ impl Default for MdhdBox {
}
impl Mp4Box for MdhdBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::MdhdBox
}
@ -51,7 +51,7 @@ impl Mp4Box for MdhdBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdhdBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
@ -74,7 +74,8 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdhdBox {
};
let language_code = reader.read_u16::<BigEndian>()?;
let language = get_language_string(language_code);
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(MdhdBox {
version,
@ -91,7 +92,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -178,7 +179,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MdhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -208,7 +209,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MdhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -18,7 +18,7 @@ impl MdiaBox {
}
impl Mp4Box for MdiaBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::MdiaBox
}
@ -39,13 +39,15 @@ impl Mp4Box for MdiaBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let mut mdia = MdiaBox::new();
let start = 0u64;
while start < size {
let mut current = reader.seek(SeekFrom::Current(0))?;
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader, start)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -61,10 +63,13 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
let minf = MinfBox::read_box(reader, s)?;
mdia.minf = Some(minf);
}
_ => break
_ => {}
}
current = reader.seek(SeekFrom::Current(0))?;
}
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(mdia)
}
@ -73,7 +78,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_box(writer)?;
if let Some(mdhd) = &self.mdhd {
mdhd.write_box(writer)?;

View file

@ -17,7 +17,7 @@ impl MinfBox {
}
impl Mp4Box for MinfBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::MinfBox
}
@ -35,13 +35,15 @@ impl Mp4Box for MinfBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let mut minf = MinfBox::new();
let mut start = 0u64;
while start < size {
let mut current = reader.seek(SeekFrom::Current(0))?;
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader, start)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -49,20 +51,19 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
let vmhd = VmhdBox::read_box(reader, s)?;
minf.vmhd = Some(vmhd);
}
BoxType::SmhdBox => {
start = s - HEADER_SIZE;
}
BoxType::DinfBox => {
start = s - HEADER_SIZE;
}
BoxType::SmhdBox => {}
BoxType::DinfBox => {}
BoxType::StblBox => {
let stbl = StblBox::read_box(reader, s)?;
minf.stbl = Some(stbl);
}
_ => break
_ => {}
}
current = reader.seek(SeekFrom::Current(0))?;
}
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(minf)
}
@ -71,7 +72,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_box(writer)?;
if let Some(vmhd) = &self.vmhd {
vmhd.write_box(writer)?;

View file

@ -17,8 +17,13 @@ mod hdlr;
mod minf;
mod vmhd;
mod stbl;
mod stts;
mod stsd;
mod stts;
mod stss;
mod stsc;
mod stsz;
mod stco;
mod co64;
mod avc;
mod mp4a;
@ -73,6 +78,11 @@ boxtype!{
StblBox => 0x7374626c,
StsdBox => 0x73747364,
SttsBox => 0x73747473,
StssBox => 0x73747373,
StscBox => 0x73747363,
StszBox => 0x7374737A,
StcoBox => 0x7374636F,
Co64Box => 0x636F3634,
TrakBox => 0x7472616b,
UdtaBox => 0x75647461,
DinfBox => 0x64696e66,
@ -171,7 +181,7 @@ impl fmt::Display for FourCC {
}
pub trait Mp4Box: Sized {
fn box_type(&self) -> BoxType;
fn box_type() -> BoxType;
fn box_size(&self) -> u64;
}
@ -210,19 +220,26 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for BoxHeader {
}
}
pub fn skip_read<R: Read + Seek>(reader: &mut BufReader<R>, current: u64, size: u64) -> Result<i64> {
let after = reader.seek(SeekFrom::Current(0))?;
let remaining_bytes = (size - (after - current)) as i64;
let size = remaining_bytes - HEADER_SIZE as i64;
reader.seek(SeekFrom::Current(size))?;
Ok(size)
pub fn get_box_start<R: Seek>(reader: &mut BufReader<R>) -> Result<u64> {
Ok(reader.seek(SeekFrom::Current(0))? - HEADER_SIZE)
}
pub fn skip_write<W: Write>(writer: &mut BufWriter<W>, size: u64) -> Result<u64> {
pub fn skip_read<R: Read + Seek>(reader: &mut BufReader<R>, size: i64) -> Result<()> {
assert!(size >= 0);
reader.seek(SeekFrom::Current(size))?;
Ok(())
}
pub fn skip_read_to<R: Read + Seek>(reader: &mut BufReader<R>, pos: u64) -> Result<()> {
reader.seek(SeekFrom::Start(pos))?;
Ok(())
}
pub fn skip_write<W: Write>(writer: &mut BufWriter<W>, size: u64) -> Result<()> {
for _ in 0..size {
writer.write_u8(0)?;
}
Ok(size)
Ok(())
}
#[cfg(test)]
@ -237,10 +254,4 @@ mod tests {
let ftyp_fcc2 = ftyp_value.into();
assert_eq!(ftyp_fcc, ftyp_fcc2);
}
// #[test]
// fn test_a() {
// let a: u32 = FourCC::from("co64").into();
// assert_eq!(a, 0);
// }
}

View file

@ -17,7 +17,7 @@ impl MoovBox {
}
impl Mp4Box for MoovBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::MoovBox
}
@ -32,13 +32,15 @@ impl Mp4Box for MoovBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let start = get_box_start(reader)?;
let mut moov = MoovBox::new();
let mut start = 0u64;
while start < size {
let mut current = reader.seek(SeekFrom::Current(0))?;
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader, start)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -49,12 +51,15 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
let trak = TrakBox::read_box(reader, s)?;
moov.traks.push(trak);
}
BoxType::UdtaBox => {
start = s - HEADER_SIZE;
}
_ => break
BoxType::UdtaBox => {}
_ => {}
}
current = reader.seek(SeekFrom::Current(0))?;
}
skip_read_to(reader, start + size)?;
Ok(moov)
}
}
@ -62,7 +67,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_box(writer)?;
self.mvhd.write_box(writer)?;
for trak in self.traks.iter() {

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
@ -26,7 +26,7 @@ impl Default for Mp4aBox {
}
impl Mp4Box for Mp4aBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::Mp4aBox
}
@ -37,7 +37,7 @@ impl Mp4Box for Mp4aBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for Mp4aBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
reader.read_u32::<BigEndian>()?; // reserved
reader.read_u16::<BigEndian>()?; // reserved
@ -49,12 +49,12 @@ 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, 0)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
if name == BoxType::EsdsBox {
let esds = EsdsBox::read_box(reader, s)?;
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(Mp4aBox {
data_reference_index,
@ -72,7 +72,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_box(writer)?;
writer.write_u32::<BigEndian>(0)?; // reserved
writer.write_u16::<BigEndian>(0)?; // reserved
@ -99,7 +99,7 @@ pub struct EsdsBox {
}
impl Mp4Box for EsdsBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::EsdsBox
}
@ -110,13 +110,13 @@ impl Mp4Box for EsdsBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EsdsBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
let es_desc = ESDescriptor::read_desc(reader)?;
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(EsdsBox {
version,
@ -129,7 +129,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
@ -31,7 +31,7 @@ impl Default for MvhdBox {
}
impl Mp4Box for MvhdBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::MvhdBox
}
@ -50,7 +50,7 @@ impl Mp4Box for MvhdBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
@ -73,7 +73,8 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
};
let numer = reader.read_u32::<BigEndian>()?;
let rate = Ratio::new_raw(numer, 0x10000);
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(MvhdBox{
version,
@ -90,7 +91,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -141,7 +142,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MvhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -171,7 +172,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::MvhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, Seek, SeekFrom, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use num_rational::Ratio;
@ -54,7 +54,7 @@ pub struct Matrix {
}
impl Mp4Box for TkhdBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::TkhdBox
}
@ -73,7 +73,7 @@ impl Mp4Box for TkhdBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
@ -118,7 +118,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
let width = reader.read_u32::<BigEndian>()? >> 16;
let height = reader.read_u32::<BigEndian>()? >> 16;
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(TkhdBox {
version,
@ -140,7 +140,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -224,7 +224,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::TkhdBox);
assert_eq!(src_box.box_size(), header.size);
@ -269,7 +269,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::TkhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -18,7 +18,7 @@ impl TrakBox {
}
impl Mp4Box for TrakBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::TrakBox
}
@ -39,13 +39,15 @@ impl Mp4Box for TrakBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let mut trak = TrakBox::new();
let start = 0u64;
while start < size {
let mut current = reader.seek(SeekFrom::Current(0))?;
let end = start + size;
while current < end {
// Get box header.
let header = read_box_header(reader, start)?;
let header = read_box_header(reader)?;
let BoxHeader{ name, size: s } = header;
match name {
@ -61,10 +63,13 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
let mdia = MdiaBox::read_box(reader, s)?;
trak.mdia = Some(mdia);
}
_ => break
_ => {}
}
current = reader.seek(SeekFrom::Current(0))?;
}
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(trak)
}
@ -73,7 +78,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_box(writer)?;
if let Some(tkhd) = &self.tkhd {
tkhd.write_box(writer)?;

View file

@ -1,4 +1,4 @@
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
use std::io::{BufReader, Seek, Read, BufWriter, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::*;
@ -20,7 +20,7 @@ pub struct RgbColor {
}
impl Mp4Box for VmhdBox {
fn box_type(&self) -> BoxType {
fn box_type() -> BoxType {
BoxType::VmhdBox
}
@ -31,7 +31,7 @@ impl Mp4Box for VmhdBox {
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
let start = get_box_start(reader)?;
let (version, flags) = read_box_header_ext(reader)?;
@ -41,7 +41,8 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
green: reader.read_u16::<BigEndian>()?,
blue: reader.read_u16::<BigEndian>()?,
};
skip_read(reader, current, size)?;
skip_read_to(reader, start + size)?;
Ok(VmhdBox {
version,
@ -55,7 +56,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_box(writer)?;
write_box_header_ext(writer, self.version, self.flags)?;
@ -92,7 +93,7 @@ mod tests {
{
let mut reader = BufReader::new(Cursor::new(&buf));
let header = read_box_header(&mut reader, 0).unwrap();
let header = read_box_header(&mut reader).unwrap();
assert_eq!(header.name, BoxType::VmhdBox);
assert_eq!(src_box.box_size(), header.size);

View file

@ -60,11 +60,11 @@ fn read_boxes(f: File) -> Result<BMFF> {
let mut bmff = BMFF::new();
bmff.size = filesize;
let mut start = 0u64;
while start < filesize {
let mut current = reader.seek(SeekFrom::Current(0))?;
while current < filesize {
// Get box header.
let header = read_box_header(&mut reader, start)?;
let header = read_box_header(&mut reader)?;
let BoxHeader{ name, size } = header;
// Match and parse the atom boxes.
@ -73,38 +73,22 @@ fn read_boxes(f: File) -> Result<BMFF> {
let ftyp = FtypBox::read_box(&mut reader, size)?;
bmff.ftyp = ftyp;
}
BoxType::FreeBox => {
start = 0;
}
BoxType::MdatBox => {
start = size - HEADER_SIZE;
}
BoxType::FreeBox => {}
BoxType::MdatBox => {}
BoxType::MoovBox => {
let moov = MoovBox::read_box(&mut reader, size)?;
bmff.moov = Some(moov);
}
BoxType::MoofBox => {
start = size - HEADER_SIZE;
}
_ => {
// Skip over unsupported boxes, but stop if the size is zero,
// meaning the last box has been reached.
if size == 0 {
break;
} else {
start = size - HEADER_SIZE;
}
}
};
BoxType::MoofBox => {}
_ => {}
}
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 + Seek>(reader: &mut BufReader<R>, start: u64) -> Result<BoxHeader> {
// Seek to offset.
let _r = reader.seek(SeekFrom::Current(start as i64));
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)?;