mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-06-11 01:19:21 +00:00
Refator Error
This commit is contained in:
parent
1d9d637241
commit
e88214606b
56
Cargo.lock
generated
56
Cargo.lock
generated
|
@ -10,7 +10,63 @@ name = "mp4"
|
|||
version = "0.4.3"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
|
||||
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
"checksum syn 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250"
|
||||
"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
||||
"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
|
|
@ -18,4 +18,5 @@ keywords = ["mp4", "isobmff"]
|
|||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
thiserror = "^1.0"
|
||||
byteorder = "1"
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header, skip_read};
|
||||
use crate::*;
|
||||
use crate::atoms::elst::ElstBox;
|
||||
|
||||
|
||||
|
@ -34,24 +31,24 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
let mut edts = EdtsBox::new();
|
||||
|
||||
let start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::ElstBox => {
|
||||
let elst = ElstBox::read_box(reader, s).unwrap();
|
||||
let elst = ElstBox::read_box(reader, s)?;
|
||||
edts.elst = Some(elst);
|
||||
}
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(edts)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -43,35 +39,35 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let entry_count = reader.read_u32::<BigEndian>().unwrap();
|
||||
let entry_count = reader.read_u32::<BigEndian>()?;
|
||||
let mut entries = Vec::with_capacity(entry_count as usize);
|
||||
for _ in 0..entry_count {
|
||||
let (segment_duration, media_time)
|
||||
= if version == 1 {
|
||||
(
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
)
|
||||
};
|
||||
|
||||
let entry = ElstEntry{
|
||||
segment_duration,
|
||||
media_time,
|
||||
media_rate: reader.read_u16::<BigEndian>().unwrap(),
|
||||
media_rate_fraction: reader.read_u16::<BigEndian>().unwrap(),
|
||||
media_rate: reader.read_u16::<BigEndian>()?,
|
||||
media_rate_fraction: reader.read_u16::<BigEndian>()?,
|
||||
};
|
||||
entries.push(entry);
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(ElstBox {
|
||||
version,
|
||||
|
@ -90,17 +86,17 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for ElstBox {
|
|||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
assert_eq!(self.entry_count as usize, self.entries.len());
|
||||
writer.write_u32::<BigEndian>(self.entry_count).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.entry_count)?;
|
||||
for entry in self.entries.iter() {
|
||||
if self.version == 1 {
|
||||
writer.write_u64::<BigEndian>(entry.segment_duration).unwrap();
|
||||
writer.write_u64::<BigEndian>(entry.media_time).unwrap();
|
||||
writer.write_u64::<BigEndian>(entry.segment_duration)?;
|
||||
writer.write_u64::<BigEndian>(entry.media_time)?;
|
||||
} else {
|
||||
writer.write_u32::<BigEndian>(entry.segment_duration as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(entry.media_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(entry.segment_duration as u32)?;
|
||||
writer.write_u32::<BigEndian>(entry.media_time as u32)?;
|
||||
}
|
||||
writer.write_u16::<BigEndian>(entry.media_rate).unwrap();
|
||||
writer.write_u16::<BigEndian>(entry.media_rate_fraction).unwrap();
|
||||
writer.write_u16::<BigEndian>(entry.media_rate)?;
|
||||
writer.write_u16::<BigEndian>(entry.media_rate_fraction)?;
|
||||
}
|
||||
|
||||
Ok(size)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use std::io::{BufReader, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result, Error, FourCC};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
|
@ -26,8 +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 major = reader.read_u32::<BigEndian>().unwrap();
|
||||
let minor = reader.read_u32::<BigEndian>().unwrap();
|
||||
let major = reader.read_u32::<BigEndian>()?;
|
||||
let minor = reader.read_u32::<BigEndian>()?;
|
||||
if size % 4 != 0 {
|
||||
return Err(Error::InvalidData("invalid ftyp size"));
|
||||
}
|
||||
|
@ -35,7 +32,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
|
|||
|
||||
let mut brands = Vec::new();
|
||||
for _ in 0..brand_count {
|
||||
let b = reader.read_u32::<BigEndian>().unwrap();
|
||||
let b = reader.read_u32::<BigEndian>()?;
|
||||
brands.push(From::from(b));
|
||||
}
|
||||
|
||||
|
@ -52,10 +49,10 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for FtypBox {
|
|||
let size = self.box_size();
|
||||
BoxHeader::new(self.box_type(), size).write_box(writer)?;
|
||||
|
||||
writer.write_u32::<BigEndian>((&self.major_brand).into()).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.minor_version).unwrap();
|
||||
writer.write_u32::<BigEndian>((&self.major_brand).into())?;
|
||||
writer.write_u32::<BigEndian>(self.minor_version)?;
|
||||
for b in self.compatible_brands.iter() {
|
||||
writer.write_u32::<BigEndian>(b.into()).unwrap();
|
||||
writer.write_u32::<BigEndian>(b.into())?;
|
||||
}
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{FourCC, BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -28,18 +24,18 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
reader.read_u32::<BigEndian>().unwrap(); // pre-defined
|
||||
let handler = reader.read_u32::<BigEndian>().unwrap();
|
||||
reader.read_u32::<BigEndian>()?; // pre-defined
|
||||
let handler = reader.read_u32::<BigEndian>()?;
|
||||
|
||||
let n = reader.seek(SeekFrom::Current(12)).unwrap(); // 12 bytes reserved.
|
||||
let n = reader.seek(SeekFrom::Current(12))?; // 12 bytes reserved.
|
||||
|
||||
let buf_size = (size - (n - current)) - HEADER_SIZE;
|
||||
let mut buf = vec![0u8; buf_size as usize];
|
||||
reader.read_exact(&mut buf).unwrap();
|
||||
reader.read_exact(&mut buf)?;
|
||||
|
||||
let handler_string = match String::from_utf8(buf) {
|
||||
Ok(t) => {
|
||||
|
@ -49,7 +45,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
|
|||
_ => String::from("null"),
|
||||
};
|
||||
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(HdlrBox {
|
||||
version,
|
||||
|
@ -67,16 +63,16 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for HdlrBox {
|
|||
|
||||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
writer.write_u32::<BigEndian>(0).unwrap(); // pre-defined
|
||||
writer.write_u32::<BigEndian>((&self.handler_type).into()).unwrap();
|
||||
writer.write_u32::<BigEndian>(0)?; // pre-defined
|
||||
writer.write_u32::<BigEndian>((&self.handler_type).into())?;
|
||||
|
||||
// 12 bytes reserved
|
||||
for _ in 0..3 {
|
||||
writer.write_u32::<BigEndian>(0).unwrap();
|
||||
writer.write_u32::<BigEndian>(0)?;
|
||||
}
|
||||
|
||||
writer.write(self.name.as_bytes()).unwrap();
|
||||
writer.write_u8(0).unwrap();
|
||||
writer.write(self.name.as_bytes())?;
|
||||
writer.write_u8(0)?;
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -42,30 +38,30 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let (creation_time, modification_time, timescale, duration)
|
||||
= if version == 1 {
|
||||
(
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
)
|
||||
} else {
|
||||
assert_eq!(version, 0);
|
||||
(
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
)
|
||||
};
|
||||
let language = reader.read_u16::<BigEndian>().unwrap();
|
||||
let language = reader.read_u16::<BigEndian>()?;
|
||||
let language_string = get_language_string(language);
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(MdhdBox {
|
||||
version,
|
||||
|
@ -88,20 +84,20 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for MdhdBox {
|
|||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
if self.version == 1 {
|
||||
writer.write_u64::<BigEndian>(self.creation_time).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.modification_time).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.timescale).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.duration).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.creation_time)?;
|
||||
writer.write_u64::<BigEndian>(self.modification_time)?;
|
||||
writer.write_u32::<BigEndian>(self.timescale)?;
|
||||
writer.write_u64::<BigEndian>(self.duration)?;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.timescale).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.duration as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.timescale)?;
|
||||
writer.write_u32::<BigEndian>(self.duration as u32)?;
|
||||
}
|
||||
|
||||
writer.write_u16::<BigEndian>(self.language).unwrap();
|
||||
writer.write_u16::<BigEndian>(0).unwrap(); // pre-defined
|
||||
writer.write_u16::<BigEndian>(self.language)?;
|
||||
writer.write_u16::<BigEndian>(0)?; // pre-defined
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header, skip_read};
|
||||
use crate::*;
|
||||
use crate::atoms::{mdhd::MdhdBox, hdlr::HdlrBox, minf::MinfBox};
|
||||
|
||||
|
||||
|
@ -42,32 +39,32 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
let mut mdia = MdiaBox::new();
|
||||
|
||||
let start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::MdhdBox => {
|
||||
let mdhd = MdhdBox::read_box(reader, s).unwrap();
|
||||
let mdhd = MdhdBox::read_box(reader, s)?;
|
||||
mdia.mdhd = Some(mdhd);
|
||||
}
|
||||
BoxType::HdlrBox => {
|
||||
let hdlr = HdlrBox::read_box(reader, s).unwrap();
|
||||
let hdlr = HdlrBox::read_box(reader, s)?;
|
||||
mdia.hdlr = Some(hdlr);
|
||||
}
|
||||
BoxType::MinfBox => {
|
||||
let minf = MinfBox::read_box(reader, s).unwrap();
|
||||
let minf = MinfBox::read_box(reader, s)?;
|
||||
mdia.minf = Some(minf);
|
||||
}
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(mdia)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header, skip_read};
|
||||
use crate::*;
|
||||
use crate::atoms::{vmhd::VmhdBox, stbl::StblBox};
|
||||
|
||||
|
||||
|
@ -38,18 +35,18 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
let mut minf = MinfBox::new();
|
||||
|
||||
let mut start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::VmhdBox => {
|
||||
let vmhd = VmhdBox::read_box(reader, s).unwrap();
|
||||
let vmhd = VmhdBox::read_box(reader, s)?;
|
||||
minf.vmhd = Some(vmhd);
|
||||
}
|
||||
BoxType::SmhdBox => {
|
||||
|
@ -59,13 +56,13 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
|||
start = s - HEADER_SIZE;
|
||||
}
|
||||
BoxType::StblBox => {
|
||||
let stbl = StblBox::read_box(reader, s).unwrap();
|
||||
let stbl = StblBox::read_box(reader, s)?;
|
||||
minf.stbl = Some(stbl);
|
||||
}
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(minf)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use std::fmt;
|
||||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Error, BoxHeader, HEADER_SIZE};
|
||||
use crate::*;
|
||||
|
||||
mod ftyp;
|
||||
mod moov;
|
||||
|
@ -26,8 +25,6 @@ pub use moov::MoovBox;
|
|||
|
||||
pub const HEADER_EXT_SIZE: u64 = 4;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
macro_rules! boxtype {
|
||||
($( $name:ident => $value:expr ),*) => {
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
|
@ -161,45 +158,48 @@ pub trait WriteBox<T>: Sized {
|
|||
}
|
||||
|
||||
pub fn read_box_header_ext<R: Read>(reader: &mut BufReader<R>) -> Result<(u8, u32)> {
|
||||
let version = reader.read_u8().unwrap();
|
||||
let flags_a = reader.read_u8().unwrap();
|
||||
let flags_b = reader.read_u8().unwrap();
|
||||
let flags_c = reader.read_u8().unwrap();
|
||||
let version = reader.read_u8()?;
|
||||
let flags_a = reader.read_u8()?;
|
||||
let flags_b = reader.read_u8()?;
|
||||
let flags_c = reader.read_u8()?;
|
||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
||||
Ok((version, flags))
|
||||
}
|
||||
|
||||
pub fn write_box_header_ext<W: Write>(w: &mut BufWriter<W>, v: u8, f: u32) -> Result<u64> {
|
||||
let d = u32::from(v) << 24 | f;
|
||||
w.write_u32::<BigEndian>(d).unwrap();
|
||||
w.write_u32::<BigEndian>(d)?;
|
||||
Ok(4)
|
||||
}
|
||||
|
||||
impl<W: Write> WriteBox<&mut BufWriter<W>> for BoxHeader {
|
||||
fn write_box(&self, writer: &mut BufWriter<W>) -> Result<u64> {
|
||||
if self.size > u32::MAX as u64 {
|
||||
writer.write_u32::<BigEndian>(1).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.name.into()).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.size).unwrap();
|
||||
writer.write_u32::<BigEndian>(1)?;
|
||||
writer.write_u32::<BigEndian>(self.name.into())?;
|
||||
writer.write_u64::<BigEndian>(self.size)?;
|
||||
Ok(16)
|
||||
} else {
|
||||
writer.write_u32::<BigEndian>(self.size as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.name.into()).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.size as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.name.into())?;
|
||||
Ok(8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_read<R: Read + Seek>(reader: &mut BufReader<R>, current: u64, size: u64) {
|
||||
let after = reader.seek(SeekFrom::Current(0)).unwrap();
|
||||
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;
|
||||
reader.seek(SeekFrom::Current(remaining_bytes - HEADER_SIZE as i64)).unwrap();
|
||||
let size = remaining_bytes - HEADER_SIZE as i64;
|
||||
reader.seek(SeekFrom::Current(size))?;
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
pub fn skip_write<W: Write>(writer: &mut BufWriter<W>, size: u64) {
|
||||
pub fn skip_write<W: Write>(writer: &mut BufWriter<W>, size: u64) -> Result<u64> {
|
||||
for _ in 0..size {
|
||||
writer.write_u8(0).unwrap();
|
||||
writer.write_u8(0)?;
|
||||
}
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header};
|
||||
use crate::*;
|
||||
use crate::atoms::{mvhd::MvhdBox, trak::TrakBox};
|
||||
|
||||
|
||||
|
@ -41,15 +38,15 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
|
|||
while start < size {
|
||||
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::MvhdBox => {
|
||||
moov.mvhd = MvhdBox::read_box(reader, s).unwrap();
|
||||
moov.mvhd = MvhdBox::read_box(reader, s)?;
|
||||
}
|
||||
BoxType::TrakBox => {
|
||||
let trak = TrakBox::read_box(reader, s).unwrap();
|
||||
let trak = TrakBox::read_box(reader, s)?;
|
||||
moov.traks.push(trak);
|
||||
}
|
||||
BoxType::UdtaBox => {
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read, skip_write};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
|
@ -39,29 +35,29 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let (creation_time, modification_time, timescale, duration)
|
||||
= if version == 1 {
|
||||
(
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
)
|
||||
} else {
|
||||
assert_eq!(version, 0);
|
||||
(
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
)
|
||||
};
|
||||
let rate = reader.read_u32::<BigEndian>().unwrap();
|
||||
skip_read(reader, current, size);
|
||||
let rate = reader.read_u32::<BigEndian>()?;
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(MvhdBox{
|
||||
version,
|
||||
|
@ -83,21 +79,21 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for MvhdBox {
|
|||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
if self.version == 1 {
|
||||
writer.write_u64::<BigEndian>(self.creation_time).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.modification_time).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.timescale).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.duration).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.creation_time)?;
|
||||
writer.write_u64::<BigEndian>(self.modification_time)?;
|
||||
writer.write_u32::<BigEndian>(self.timescale)?;
|
||||
writer.write_u64::<BigEndian>(self.duration)?;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.timescale).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.duration as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.timescale)?;
|
||||
writer.write_u32::<BigEndian>(self.duration as u32)?;
|
||||
}
|
||||
writer.write_u32::<BigEndian>(self.rate).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.rate)?;
|
||||
|
||||
// XXX volume, ...
|
||||
skip_write(writer, 76);
|
||||
skip_write(writer, 76)?;
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header};
|
||||
use crate::*;
|
||||
use crate::atoms::{stts::SttsBox, stsd::StsdBox};
|
||||
|
||||
|
||||
|
@ -43,16 +40,16 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
|
|||
let start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::SttsBox => {
|
||||
let stts = SttsBox::read_box(reader, s).unwrap();
|
||||
let stts = SttsBox::read_box(reader, s)?;
|
||||
stbl.stts = Some(stts);
|
||||
}
|
||||
BoxType::StsdBox => {
|
||||
let stsd = StsdBox::read_box(reader, s).unwrap();
|
||||
let stsd = StsdBox::read_box(reader, s)?;
|
||||
stbl.stsd = Some(stsd);
|
||||
}
|
||||
_ => break
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header, read_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -28,16 +24,16 @@ impl Mp4Box for StsdBox {
|
|||
|
||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
|
||||
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
|
||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let entry_count = reader.read_u32::<BigEndian>().unwrap();
|
||||
let entry_count = reader.read_u32::<BigEndian>()?;
|
||||
|
||||
let mut start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
|
@ -47,7 +43,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
|
|||
}
|
||||
start += s - HEADER_SIZE;
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(StsdBox {
|
||||
version,
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -34,20 +30,20 @@ impl Mp4Box for SttsBox {
|
|||
|
||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SttsBox {
|
||||
fn read_box(reader: &mut BufReader<R>, size: u64) -> Result<Self> {
|
||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let entry_count = reader.read_u32::<BigEndian>().unwrap();
|
||||
let entry_count = reader.read_u32::<BigEndian>()?;
|
||||
let mut entries = Vec::with_capacity(entry_count as usize);
|
||||
for _i in 0..entry_count {
|
||||
let entry = SttsEntry {
|
||||
sample_count: reader.read_u32::<BigEndian>().unwrap(),
|
||||
sample_delta: reader.read_u32::<BigEndian>().unwrap(),
|
||||
sample_count: reader.read_u32::<BigEndian>()?,
|
||||
sample_delta: reader.read_u32::<BigEndian>()?,
|
||||
};
|
||||
entries.push(entry);
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(SttsBox {
|
||||
version,
|
||||
|
@ -65,10 +61,10 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for SttsBox {
|
|||
|
||||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
writer.write_u32::<BigEndian>(self.entry_count).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.entry_count)?;
|
||||
for entry in self.entries.iter() {
|
||||
writer.write_u32::<BigEndian>(entry.sample_count).unwrap();
|
||||
writer.write_u32::<BigEndian>(entry.sample_delta).unwrap();
|
||||
writer.write_u32::<BigEndian>(entry.sample_count)?;
|
||||
writer.write_u32::<BigEndian>(entry.sample_delta)?;
|
||||
}
|
||||
|
||||
Ok(size)
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, Seek, SeekFrom, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
|
@ -57,51 +53,51 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let (creation_time, modification_time, track_id, _, duration)
|
||||
= if version == 1 {
|
||||
(
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>().unwrap(),
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u64::<BigEndian>()?,
|
||||
)
|
||||
} else {
|
||||
assert_eq!(version, 0);
|
||||
(
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap(),
|
||||
reader.read_u32::<BigEndian>().unwrap() as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()? as u64,
|
||||
)
|
||||
};
|
||||
reader.read_u64::<BigEndian>().unwrap(); // reserved
|
||||
let layer = reader.read_u16::<BigEndian>().unwrap();
|
||||
let alternate_group = reader.read_u16::<BigEndian>().unwrap();
|
||||
let volume = reader.read_u16::<BigEndian>().unwrap();
|
||||
reader.read_u64::<BigEndian>()?; // reserved
|
||||
let layer = reader.read_u16::<BigEndian>()?;
|
||||
let alternate_group = reader.read_u16::<BigEndian>()?;
|
||||
let volume = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
reader.read_u16::<BigEndian>().unwrap(); // reserved
|
||||
reader.read_u16::<BigEndian>()?; // reserved
|
||||
let matrix = Matrix{
|
||||
a: reader.read_i32::<byteorder::LittleEndian>().unwrap(),
|
||||
b: reader.read_i32::<BigEndian>().unwrap(),
|
||||
u: reader.read_i32::<BigEndian>().unwrap(),
|
||||
c: reader.read_i32::<BigEndian>().unwrap(),
|
||||
d: reader.read_i32::<BigEndian>().unwrap(),
|
||||
v: reader.read_i32::<BigEndian>().unwrap(),
|
||||
x: reader.read_i32::<BigEndian>().unwrap(),
|
||||
y: reader.read_i32::<BigEndian>().unwrap(),
|
||||
w: reader.read_i32::<BigEndian>().unwrap(),
|
||||
a: reader.read_i32::<byteorder::LittleEndian>()?,
|
||||
b: reader.read_i32::<BigEndian>()?,
|
||||
u: reader.read_i32::<BigEndian>()?,
|
||||
c: reader.read_i32::<BigEndian>()?,
|
||||
d: reader.read_i32::<BigEndian>()?,
|
||||
v: reader.read_i32::<BigEndian>()?,
|
||||
x: reader.read_i32::<BigEndian>()?,
|
||||
y: reader.read_i32::<BigEndian>()?,
|
||||
w: reader.read_i32::<BigEndian>()?,
|
||||
};
|
||||
|
||||
let width = reader.read_u32::<BigEndian>().unwrap() >> 16;
|
||||
let height = reader.read_u32::<BigEndian>().unwrap() >> 16;
|
||||
let width = reader.read_u32::<BigEndian>()? >> 16;
|
||||
let height = reader.read_u32::<BigEndian>()? >> 16;
|
||||
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(TkhdBox {
|
||||
version,
|
||||
|
@ -128,39 +124,39 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for TkhdBox {
|
|||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
if self.version == 1 {
|
||||
writer.write_u64::<BigEndian>(self.creation_time).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.modification_time).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.track_id).unwrap();
|
||||
writer.write_u32::<BigEndian>(0).unwrap(); // reserved
|
||||
writer.write_u64::<BigEndian>(self.duration).unwrap();
|
||||
writer.write_u64::<BigEndian>(self.creation_time)?;
|
||||
writer.write_u64::<BigEndian>(self.modification_time)?;
|
||||
writer.write_u32::<BigEndian>(self.track_id)?;
|
||||
writer.write_u32::<BigEndian>(0)?; // reserved
|
||||
writer.write_u64::<BigEndian>(self.duration)?;
|
||||
} else {
|
||||
assert_eq!(self.version, 0);
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.track_id).unwrap();
|
||||
writer.write_u32::<BigEndian>(0).unwrap(); // reserved
|
||||
writer.write_u32::<BigEndian>(self.duration as u32).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.creation_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.modification_time as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.track_id)?;
|
||||
writer.write_u32::<BigEndian>(0)?; // reserved
|
||||
writer.write_u32::<BigEndian>(self.duration as u32)?;
|
||||
}
|
||||
|
||||
writer.write_u64::<BigEndian>(0).unwrap(); // reserved
|
||||
writer.write_u16::<BigEndian>(self.layer).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.alternate_group).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.volume).unwrap();
|
||||
writer.write_u64::<BigEndian>(0)?; // reserved
|
||||
writer.write_u16::<BigEndian>(self.layer)?;
|
||||
writer.write_u16::<BigEndian>(self.alternate_group)?;
|
||||
writer.write_u16::<BigEndian>(self.volume)?;
|
||||
|
||||
writer.write_u16::<BigEndian>(0).unwrap(); // reserved
|
||||
writer.write_u16::<BigEndian>(0)?; // reserved
|
||||
|
||||
writer.write_i32::<byteorder::LittleEndian>(self.matrix.a).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.b).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.u).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.c).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.d).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.v).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.x).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.y).unwrap();
|
||||
writer.write_i32::<BigEndian>(self.matrix.w).unwrap();
|
||||
writer.write_i32::<byteorder::LittleEndian>(self.matrix.a)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.b)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.u)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.c)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.d)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.v)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.x)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.y)?;
|
||||
writer.write_i32::<BigEndian>(self.matrix.w)?;
|
||||
|
||||
writer.write_u32::<BigEndian>(self.width << 16).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.height << 16).unwrap();
|
||||
writer.write_u32::<BigEndian>(self.width << 16)?;
|
||||
writer.write_u32::<BigEndian>(self.height << 16)?;
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE};
|
||||
use crate::{read_box_header, skip_read};
|
||||
use crate::*;
|
||||
use crate::atoms::{tkhd::TkhdBox, edts::EdtsBox, mdia::MdiaBox};
|
||||
|
||||
|
||||
|
@ -42,32 +39,32 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
let mut trak = TrakBox::new();
|
||||
|
||||
let start = 0u64;
|
||||
while start < size {
|
||||
// Get box header.
|
||||
let header = read_box_header(reader, start).unwrap();
|
||||
let header = read_box_header(reader, start)?;
|
||||
let BoxHeader{ name, size: s } = header;
|
||||
|
||||
match name {
|
||||
BoxType::TkhdBox => {
|
||||
let tkhd = TkhdBox::read_box(reader, s).unwrap();
|
||||
let tkhd = TkhdBox::read_box(reader, s)?;
|
||||
trak.tkhd = Some(tkhd);
|
||||
}
|
||||
BoxType::EdtsBox => {
|
||||
let edts = EdtsBox::read_box(reader, s).unwrap();
|
||||
let edts = EdtsBox::read_box(reader, s)?;
|
||||
trak.edts = Some(edts);
|
||||
}
|
||||
BoxType::MdiaBox => {
|
||||
let mdia = MdiaBox::read_box(reader, s).unwrap();
|
||||
let mdia = MdiaBox::read_box(reader, s)?;
|
||||
trak.mdia = Some(mdia);
|
||||
}
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(trak)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::io::{BufReader, SeekFrom, Seek, Read, BufWriter, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::{Result};
|
||||
use crate::{BoxType, BoxHeader, Mp4Box, ReadBox, WriteBox};
|
||||
use crate::{HEADER_SIZE, HEADER_EXT_SIZE};
|
||||
use crate::{read_box_header_ext, write_box_header_ext, skip_read};
|
||||
use crate::*;
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -35,17 +31,17 @@ 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)).unwrap(); // Current cursor position.
|
||||
let current = reader.seek(SeekFrom::Current(0))?; // Current cursor position.
|
||||
|
||||
let (version, flags) = read_box_header_ext(reader).unwrap();
|
||||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let graphics_mode = reader.read_u16::<BigEndian>().unwrap();
|
||||
let graphics_mode = reader.read_u16::<BigEndian>()?;
|
||||
let op_color = RgbColor {
|
||||
red: reader.read_u16::<BigEndian>().unwrap(),
|
||||
green: reader.read_u16::<BigEndian>().unwrap(),
|
||||
blue: reader.read_u16::<BigEndian>().unwrap(),
|
||||
red: reader.read_u16::<BigEndian>()?,
|
||||
green: reader.read_u16::<BigEndian>()?,
|
||||
blue: reader.read_u16::<BigEndian>()?,
|
||||
};
|
||||
skip_read(reader, current, size);
|
||||
skip_read(reader, current, size)?;
|
||||
|
||||
Ok(VmhdBox {
|
||||
version,
|
||||
|
@ -63,10 +59,10 @@ impl<W: Write> WriteBox<&mut BufWriter<W>> for VmhdBox {
|
|||
|
||||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
writer.write_u16::<BigEndian>(self.graphics_mode).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.op_color.red).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.op_color.green).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.op_color.blue).unwrap();
|
||||
writer.write_u16::<BigEndian>(self.graphics_mode)?;
|
||||
writer.write_u16::<BigEndian>(self.op_color.red)?;
|
||||
writer.write_u16::<BigEndian>(self.op_color.green)?;
|
||||
writer.write_u16::<BigEndian>(self.op_color.blue)?;
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
|
9
src/error.rs
Normal file
9
src/error.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("{0}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error("{0}")]
|
||||
InvalidData(&'static str),
|
||||
}
|
27
src/lib.rs
27
src/lib.rs
|
@ -1,19 +1,18 @@
|
|||
use std::io::prelude::*;
|
||||
use std::io::{BufReader, Read, SeekFrom};
|
||||
use std::io::{BufReader, Read, SeekFrom, Seek};
|
||||
use std::fs::File;
|
||||
use std::convert::TryInto;
|
||||
|
||||
mod atoms;
|
||||
use crate::atoms::*;
|
||||
|
||||
mod error;
|
||||
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)]
|
||||
pub enum Error {
|
||||
InvalidData(&'static str),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TrackType {
|
||||
Audio,
|
||||
|
@ -50,13 +49,13 @@ impl BoxHeader {
|
|||
pub fn read_mp4(f: File) -> Result<BMFF> {
|
||||
|
||||
// Open file and read boxes.
|
||||
let bmff = read_boxes(f).unwrap();
|
||||
let bmff = read_boxes(f)?;
|
||||
|
||||
Ok(bmff)
|
||||
}
|
||||
|
||||
fn read_boxes(f: File) -> Result<BMFF> {
|
||||
let filesize = f.metadata().unwrap().len();
|
||||
let filesize = f.metadata()?.len();
|
||||
let mut reader = BufReader::new(f);
|
||||
let mut bmff = BMFF::new();
|
||||
bmff.size = filesize;
|
||||
|
@ -65,13 +64,13 @@ fn read_boxes(f: File) -> Result<BMFF> {
|
|||
while start < filesize {
|
||||
|
||||
// Get box header.
|
||||
let header = read_box_header(&mut reader, start).unwrap();
|
||||
let header = read_box_header(&mut reader, start)?;
|
||||
let BoxHeader{ name, size } = header;
|
||||
|
||||
// Match and parse the atom boxes.
|
||||
match name {
|
||||
BoxType::FtypBox => {
|
||||
let ftyp = FtypBox::read_box(&mut reader, size).unwrap();
|
||||
let ftyp = FtypBox::read_box(&mut reader, size)?;
|
||||
bmff.ftyp = ftyp;
|
||||
}
|
||||
BoxType::FreeBox => {
|
||||
|
@ -81,7 +80,7 @@ fn read_boxes(f: File) -> Result<BMFF> {
|
|||
start = size - HEADER_SIZE;
|
||||
}
|
||||
BoxType::MoovBox => {
|
||||
let moov = MoovBox::read_box(&mut reader, size).unwrap();
|
||||
let moov = MoovBox::read_box(&mut reader, size)?;
|
||||
bmff.moov = Some(moov);
|
||||
}
|
||||
BoxType::MoofBox => {
|
||||
|
@ -108,7 +107,7 @@ fn read_box_header<R: Read + Seek>(reader: &mut BufReader<R>, start: u64) -> Res
|
|||
|
||||
// Create and read to buf.
|
||||
let mut buf = [0u8;8]; // 8 bytes for box header.
|
||||
reader.read(&mut buf).unwrap();
|
||||
reader.read(&mut buf)?;
|
||||
|
||||
// Get size.
|
||||
let s = buf[0..4].try_into().unwrap();
|
||||
|
@ -120,7 +119,7 @@ fn read_box_header<R: Read + Seek>(reader: &mut BufReader<R>, start: u64) -> Res
|
|||
|
||||
// Get largesize if size is 1
|
||||
if size == 1 {
|
||||
reader.read(&mut buf).unwrap();
|
||||
reader.read(&mut buf)?;
|
||||
let s = buf.try_into().unwrap();
|
||||
let largesize = u64::from_be_bytes(s);
|
||||
|
||||
|
|
Loading…
Reference in a new issue