mirror of
https://github.com/alfg/mp4-rust.git
synced 2025-01-03 08:58:40 +00:00
Remove deprecated codes (#9)
* Add ReadBox trait * Add boxtype macro * Remove offset in BoxHeader * Fix parsing error when box has largesize * Remove duplicated codes reading version and flags Co-authored-by: Byungwan Jun <unipro.kr@gmail.com>
This commit is contained in:
parent
a4fd45b3e8
commit
1e86e4edab
2 changed files with 125 additions and 172 deletions
262
src/atoms.rs
262
src/atoms.rs
|
@ -6,99 +6,70 @@ use crate::{Error, read_box_header, BoxHeader, HEADER_SIZE};
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
macro_rules! boxtype {
|
||||||
pub enum BoxType {
|
($( $name:ident => $value:expr ),*) => {
|
||||||
FtypBox,
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
MvhdBox,
|
pub enum BoxType {
|
||||||
FreeBox,
|
$( $name, )*
|
||||||
MdatBox,
|
UnknownBox(u32),
|
||||||
MoovBox,
|
}
|
||||||
MoofBox,
|
|
||||||
TkhdBox,
|
|
||||||
EdtsBox,
|
|
||||||
MdiaBox,
|
|
||||||
ElstBox,
|
|
||||||
MdhdBox,
|
|
||||||
HdlrBox,
|
|
||||||
MinfBox,
|
|
||||||
VmhdBox,
|
|
||||||
StblBox,
|
|
||||||
StsdBox,
|
|
||||||
SttsBox,
|
|
||||||
TrakBox,
|
|
||||||
UdtaBox,
|
|
||||||
DinfBox,
|
|
||||||
SmhdBox,
|
|
||||||
Avc1Box,
|
|
||||||
Mp4aBox,
|
|
||||||
UnknownBox(u32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u32> for BoxType {
|
impl From<u32> for BoxType {
|
||||||
fn from(t: u32) -> BoxType {
|
fn from(t: u32) -> BoxType {
|
||||||
use self::BoxType::*;
|
match t {
|
||||||
match t {
|
$( $value => BoxType::$name, )*
|
||||||
0x66747970 => FtypBox,
|
_ => BoxType::UnknownBox(t),
|
||||||
0x6d766864 => MvhdBox,
|
}
|
||||||
0x66726565 => FreeBox,
|
}
|
||||||
0x6d646174 => MdatBox,
|
}
|
||||||
0x6d6f6f76 => MoovBox,
|
|
||||||
0x6d6f6f66 => MoofBox ,
|
impl Into<u32> for BoxType {
|
||||||
0x746b6864 => TkhdBox,
|
fn into(self) -> u32 {
|
||||||
0x65647473 => EdtsBox,
|
match self {
|
||||||
0x6d646961 => MdiaBox,
|
$( BoxType::$name => $value, )*
|
||||||
0x656c7374 => ElstBox,
|
BoxType::UnknownBox(t) => t,
|
||||||
0x6d646864 => MdhdBox,
|
}
|
||||||
0x68646c72 => HdlrBox,
|
}
|
||||||
0x6d696e66 => MinfBox,
|
|
||||||
0x766d6864 => VmhdBox,
|
|
||||||
0x7374626c => StblBox,
|
|
||||||
0x73747364 => StsdBox,
|
|
||||||
0x73747473 => SttsBox,
|
|
||||||
0x7472616b => TrakBox,
|
|
||||||
0x75647461 => UdtaBox,
|
|
||||||
0x64696e66 => DinfBox,
|
|
||||||
0x736d6864 => SmhdBox,
|
|
||||||
0x61766331 => Avc1Box,
|
|
||||||
0x6d703461 => Mp4aBox,
|
|
||||||
_ => UnknownBox(t),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<u32> for BoxType {
|
macro_rules! read_box_header_ext {
|
||||||
fn into(self) -> u32 {
|
($r:ident, $v:ident, $ f:ident) => {
|
||||||
use self::BoxType::*;
|
let $v = $r.read_u8().unwrap();
|
||||||
match self {
|
let flags_a = $r.read_u8().unwrap();
|
||||||
FtypBox => 0x66747970,
|
let flags_b = $r.read_u8().unwrap();
|
||||||
MvhdBox => 0x6d766864,
|
let flags_c = $r.read_u8().unwrap();
|
||||||
FreeBox => 0x66726565,
|
let $f = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
||||||
MdatBox => 0x6d646174,
|
|
||||||
MoovBox => 0x6d6f6f76,
|
|
||||||
MoofBox => 0x6d6f6f66,
|
|
||||||
TkhdBox => 0x746b6864,
|
|
||||||
EdtsBox => 0x65647473,
|
|
||||||
MdiaBox => 0x6d646961,
|
|
||||||
ElstBox => 0x656c7374,
|
|
||||||
MdhdBox => 0x6d646864,
|
|
||||||
HdlrBox => 0x68646c72,
|
|
||||||
MinfBox => 0x6d696e66,
|
|
||||||
VmhdBox => 0x766d6864,
|
|
||||||
StblBox => 0x7374626c,
|
|
||||||
StsdBox => 0x73747364,
|
|
||||||
SttsBox => 0x73747473,
|
|
||||||
TrakBox => 0x7472616b,
|
|
||||||
UdtaBox => 0x75647461,
|
|
||||||
DinfBox => 0x64696e66,
|
|
||||||
SmhdBox => 0x736d6864,
|
|
||||||
Avc1Box => 0x61766331,
|
|
||||||
Mp4aBox => 0x6d703461,
|
|
||||||
|
|
||||||
UnknownBox(t) => t,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxtype!{
|
||||||
|
FtypBox => 0x66747970,
|
||||||
|
MvhdBox => 0x6d766864,
|
||||||
|
FreeBox => 0x66726565,
|
||||||
|
MdatBox => 0x6d646174,
|
||||||
|
MoovBox => 0x6d6f6f76,
|
||||||
|
MoofBox => 0x6d6f6f66,
|
||||||
|
TkhdBox => 0x746b6864,
|
||||||
|
EdtsBox => 0x65647473,
|
||||||
|
MdiaBox => 0x6d646961,
|
||||||
|
ElstBox => 0x656c7374,
|
||||||
|
MdhdBox => 0x6d646864,
|
||||||
|
HdlrBox => 0x68646c72,
|
||||||
|
MinfBox => 0x6d696e66,
|
||||||
|
VmhdBox => 0x766d6864,
|
||||||
|
StblBox => 0x7374626c,
|
||||||
|
StsdBox => 0x73747364,
|
||||||
|
SttsBox => 0x73747473,
|
||||||
|
TrakBox => 0x7472616b,
|
||||||
|
UdtaBox => 0x75647461,
|
||||||
|
DinfBox => 0x64696e66,
|
||||||
|
SmhdBox => 0x736d6864,
|
||||||
|
Avc1Box => 0x61766331,
|
||||||
|
Mp4aBox => 0x6d703461
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for BoxType {
|
impl fmt::Debug for BoxType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let fourcc: FourCC = From::from(self.clone());
|
let fourcc: FourCC = From::from(self.clone());
|
||||||
|
@ -151,7 +122,7 @@ impl fmt::Display for FourCC {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReadBox<T>: Sized {
|
pub trait ReadBox<T>: Sized {
|
||||||
fn read_box(_: T, offset: u64, size: u32) -> Result<Self>;
|
fn read_box(_: T, size: u32) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -333,7 +304,7 @@ pub struct StsdBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let major = reader.read_u32::<BigEndian>().unwrap();
|
let major = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let minor = reader.read_u32::<BigEndian>().unwrap();
|
let minor = reader.read_u32::<BigEndian>().unwrap();
|
||||||
if size % 4 != 0 {
|
if size % 4 != 0 {
|
||||||
|
@ -356,7 +327,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for FtypBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let mut moov = MoovBox::new();
|
let mut moov = MoovBox::new();
|
||||||
|
|
||||||
let mut start = 0u64;
|
let mut start = 0u64;
|
||||||
|
@ -364,14 +335,14 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
|
||||||
|
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::MvhdBox => {
|
BoxType::MvhdBox => {
|
||||||
moov.mvhd = MvhdBox::read_box(reader, 0, s as u32).unwrap();
|
moov.mvhd = MvhdBox::read_box(reader, s as u32).unwrap();
|
||||||
}
|
}
|
||||||
BoxType::TrakBox => {
|
BoxType::TrakBox => {
|
||||||
let trak = TrakBox::read_box(reader, 0, s as u32).unwrap();
|
let trak = TrakBox::read_box(reader, s as u32).unwrap();
|
||||||
moov.traks.push(trak);
|
moov.traks.push(trak);
|
||||||
}
|
}
|
||||||
BoxType::UdtaBox => {
|
BoxType::UdtaBox => {
|
||||||
|
@ -385,14 +356,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MoovBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let timescale = reader.read_u32::<BigEndian>().unwrap();
|
let timescale = reader.read_u32::<BigEndian>().unwrap();
|
||||||
|
@ -413,7 +381,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MvhdBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
let mut trak = TrakBox::new();
|
let mut trak = TrakBox::new();
|
||||||
|
|
||||||
|
@ -421,19 +389,19 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::TkhdBox => {
|
BoxType::TkhdBox => {
|
||||||
let tkhd = TkhdBox::read_box(reader, 0, s as u32).unwrap();
|
let tkhd = TkhdBox::read_box(reader, s as u32).unwrap();
|
||||||
trak.tkhd = Some(tkhd);
|
trak.tkhd = Some(tkhd);
|
||||||
}
|
}
|
||||||
BoxType::EdtsBox => {
|
BoxType::EdtsBox => {
|
||||||
let edts = EdtsBox::read_box(reader, 0, s as u32).unwrap();
|
let edts = EdtsBox::read_box(reader, s as u32).unwrap();
|
||||||
trak.edts = Some(edts);
|
trak.edts = Some(edts);
|
||||||
}
|
}
|
||||||
BoxType::MdiaBox => {
|
BoxType::MdiaBox => {
|
||||||
let mdia = MdiaBox::read_box(reader, 0, s as u32).unwrap();
|
let mdia = MdiaBox::read_box(reader, s as u32).unwrap();
|
||||||
trak.mdia = Some(mdia);
|
trak.mdia = Some(mdia);
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -446,14 +414,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TrakBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let track_id = reader.read_u32::<BigEndian>().unwrap();
|
let track_id = reader.read_u32::<BigEndian>().unwrap();
|
||||||
|
@ -498,7 +463,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for TkhdBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
let mut edts = EdtsBox::new();
|
let mut edts = EdtsBox::new();
|
||||||
|
|
||||||
|
@ -506,11 +471,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::ElstBox => {
|
BoxType::ElstBox => {
|
||||||
let elst = ElstBox::read_box(reader, 0, s as u32).unwrap();
|
let elst = ElstBox::read_box(reader, s as u32).unwrap();
|
||||||
edts.elst = Some(elst);
|
edts.elst = Some(elst);
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -523,7 +488,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for EdtsBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u32::<BigEndian>().unwrap();
|
let version = reader.read_u32::<BigEndian>().unwrap();
|
||||||
|
@ -551,7 +516,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for ElstBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
let mut mdia = MdiaBox::new();
|
let mut mdia = MdiaBox::new();
|
||||||
|
|
||||||
|
@ -559,19 +524,19 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::MdhdBox => {
|
BoxType::MdhdBox => {
|
||||||
let mdhd = MdhdBox::read_box(reader, 0, s as u32).unwrap();
|
let mdhd = MdhdBox::read_box(reader, s as u32).unwrap();
|
||||||
mdia.mdhd = Some(mdhd);
|
mdia.mdhd = Some(mdhd);
|
||||||
}
|
}
|
||||||
BoxType::HdlrBox => {
|
BoxType::HdlrBox => {
|
||||||
let hdlr = HdlrBox::read_box(reader, 0, s as u32).unwrap();
|
let hdlr = HdlrBox::read_box(reader, s as u32).unwrap();
|
||||||
mdia.hdlr = Some(hdlr);
|
mdia.hdlr = Some(hdlr);
|
||||||
}
|
}
|
||||||
BoxType::MinfBox => {
|
BoxType::MinfBox => {
|
||||||
let minf = MinfBox::read_box(reader, 0, s as u32).unwrap();
|
let minf = MinfBox::read_box(reader, s as u32).unwrap();
|
||||||
mdia.minf = Some(minf);
|
mdia.minf = Some(minf);
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -584,14 +549,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdiaBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdhdBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MdhdBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
let creation_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
let modification_time = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let timescale = reader.read_u32::<BigEndian>().unwrap();
|
let timescale = reader.read_u32::<BigEndian>().unwrap();
|
||||||
|
@ -629,14 +591,11 @@ fn get_language_string(language: u16) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
reader.read_u32::<BigEndian>().unwrap(); // skip.
|
reader.read_u32::<BigEndian>().unwrap(); // skip.
|
||||||
let handler = reader.read_u32::<BigEndian>().unwrap();
|
let handler = reader.read_u32::<BigEndian>().unwrap();
|
||||||
|
|
||||||
|
@ -661,7 +620,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for HdlrBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
let mut minf = MinfBox::new();
|
let mut minf = MinfBox::new();
|
||||||
|
|
||||||
|
@ -669,11 +628,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::VmhdBox => {
|
BoxType::VmhdBox => {
|
||||||
let vmhd = VmhdBox::read_box(reader, 0, s as u32).unwrap();
|
let vmhd = VmhdBox::read_box(reader, s as u32).unwrap();
|
||||||
minf.vmhd = Some(vmhd);
|
minf.vmhd = Some(vmhd);
|
||||||
}
|
}
|
||||||
BoxType::SmhdBox => {
|
BoxType::SmhdBox => {
|
||||||
|
@ -683,7 +642,7 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
||||||
start = (s as u32 - HEADER_SIZE) as u64;
|
start = (s as u32 - HEADER_SIZE) as u64;
|
||||||
}
|
}
|
||||||
BoxType::StblBox => {
|
BoxType::StblBox => {
|
||||||
let stbl = StblBox::read_box(reader, 0, s as u32).unwrap();
|
let stbl = StblBox::read_box(reader, s as u32).unwrap();
|
||||||
minf.stbl = Some(stbl);
|
minf.stbl = Some(stbl);
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -696,14 +655,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for MinfBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
let graphics_mode = reader.read_u16::<BigEndian>().unwrap();
|
let graphics_mode = reader.read_u16::<BigEndian>().unwrap();
|
||||||
let op_color = reader.read_u16::<BigEndian>().unwrap();
|
let op_color = reader.read_u16::<BigEndian>().unwrap();
|
||||||
skip(reader, current, size);
|
skip(reader, current, size);
|
||||||
|
@ -718,22 +674,22 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for VmhdBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let mut stbl = StblBox::new();
|
let mut stbl = StblBox::new();
|
||||||
|
|
||||||
let start = 0u64;
|
let start = 0u64;
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::StsdBox => {
|
BoxType::StsdBox => {
|
||||||
let stsd = StsdBox::read_box(reader, 0, s as u32).unwrap();
|
let stsd = StsdBox::read_box(reader, s as u32).unwrap();
|
||||||
stbl.stsd = Some(stsd);
|
stbl.stsd = Some(stsd);
|
||||||
}
|
}
|
||||||
BoxType::SttsBox => {
|
BoxType::SttsBox => {
|
||||||
let stts = SttsBox::read_box(reader, 0, s as u32).unwrap();
|
let stts = SttsBox::read_box(reader, s as u32).unwrap();
|
||||||
stbl.stts = Some(stts);
|
stbl.stts = Some(stts);
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -744,14 +700,11 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StblBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SttsBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SttsBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
let entry_count = reader.read_u32::<BigEndian>().unwrap();
|
let entry_count = reader.read_u32::<BigEndian>().unwrap();
|
||||||
let mut sample_counts = Vec::new();
|
let mut sample_counts = Vec::new();
|
||||||
let mut sample_deltas = Vec::new();
|
let mut sample_deltas = Vec::new();
|
||||||
|
@ -775,21 +728,18 @@ impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for SttsBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
|
impl<R: Read + Seek> ReadBox<&mut BufReader<R>> for StsdBox {
|
||||||
fn read_box(reader: &mut BufReader<R>, _offset: u64, size: u32) -> Result<Self> {
|
fn read_box(reader: &mut BufReader<R>, size: u32) -> Result<Self> {
|
||||||
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
let current = reader.seek(SeekFrom::Current(0)).unwrap(); // Current cursor position.
|
||||||
|
|
||||||
let version = reader.read_u8().unwrap();
|
read_box_header_ext!(reader, version, flags);
|
||||||
let flags_a = reader.read_u8().unwrap();
|
|
||||||
let flags_b = reader.read_u8().unwrap();
|
|
||||||
let flags_c = reader.read_u8().unwrap();
|
|
||||||
let flags = u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c);
|
|
||||||
reader.read_u32::<BigEndian>().unwrap(); // skip.
|
reader.read_u32::<BigEndian>().unwrap(); // skip.
|
||||||
|
|
||||||
let mut start = 0u64;
|
let mut start = 0u64;
|
||||||
while start < size as u64 {
|
while start < size as u64 {
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(reader, start).unwrap();
|
let header = read_box_header(reader, start).unwrap();
|
||||||
let BoxHeader{ name, size: s, offset: _ } = header;
|
let BoxHeader{ name, size: s } = header;
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
BoxType::Avc1Box => {
|
BoxType::Avc1Box => {
|
||||||
|
|
35
src/lib.rs
35
src/lib.rs
|
@ -40,7 +40,6 @@ impl BMFF {
|
||||||
struct BoxHeader {
|
struct BoxHeader {
|
||||||
name: BoxType,
|
name: BoxType,
|
||||||
size: u64,
|
size: u64,
|
||||||
offset: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_mp4(f: File) -> Result<BMFF> {
|
pub fn read_mp4(f: File) -> Result<BMFF> {
|
||||||
|
@ -62,12 +61,12 @@ fn read_boxes(f: File) -> Result<BMFF> {
|
||||||
|
|
||||||
// Get box header.
|
// Get box header.
|
||||||
let header = read_box_header(&mut reader, start).unwrap();
|
let header = read_box_header(&mut reader, start).unwrap();
|
||||||
let BoxHeader{ name, size, offset: _ } = header;
|
let BoxHeader{ name, size } = header;
|
||||||
|
|
||||||
// Match and parse the atom boxes.
|
// Match and parse the atom boxes.
|
||||||
match name {
|
match name {
|
||||||
BoxType::FtypBox => {
|
BoxType::FtypBox => {
|
||||||
let ftyp = FtypBox::read_box(&mut reader, 0, size as u32).unwrap();
|
let ftyp = FtypBox::read_box(&mut reader, size as u32).unwrap();
|
||||||
bmff.ftyp = ftyp;
|
bmff.ftyp = ftyp;
|
||||||
}
|
}
|
||||||
BoxType::FreeBox => {
|
BoxType::FreeBox => {
|
||||||
|
@ -77,7 +76,7 @@ fn read_boxes(f: File) -> Result<BMFF> {
|
||||||
start = (size as u32 - HEADER_SIZE) as u64;
|
start = (size as u32 - HEADER_SIZE) as u64;
|
||||||
}
|
}
|
||||||
BoxType::MoovBox => {
|
BoxType::MoovBox => {
|
||||||
let moov = MoovBox::read_box(&mut reader, 0, size as u32).unwrap();
|
let moov = MoovBox::read_box(&mut reader, size as u32).unwrap();
|
||||||
bmff.moov = Some(moov);
|
bmff.moov = Some(moov);
|
||||||
}
|
}
|
||||||
BoxType::MoofBox => {
|
BoxType::MoofBox => {
|
||||||
|
@ -97,6 +96,7 @@ fn read_boxes(f: File) -> Result<BMFF> {
|
||||||
Ok(bmff)
|
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> {
|
fn read_box_header<R: Read + Seek>(reader: &mut BufReader<R>, start: u64) -> Result<BoxHeader> {
|
||||||
// Seek to offset.
|
// Seek to offset.
|
||||||
let _r = reader.seek(SeekFrom::Current(start as i64));
|
let _r = reader.seek(SeekFrom::Current(start as i64));
|
||||||
|
@ -108,24 +108,27 @@ fn read_box_header<R: Read + Seek>(reader: &mut BufReader<R>, start: u64) -> Res
|
||||||
// Get size.
|
// Get size.
|
||||||
let s = buf[0..4].try_into().unwrap();
|
let s = buf[0..4].try_into().unwrap();
|
||||||
let size = u32::from_be_bytes(s);
|
let size = u32::from_be_bytes(s);
|
||||||
|
|
||||||
// TODO: Err if size is 0.
|
|
||||||
// if size == 0 { break; }
|
|
||||||
|
|
||||||
// Get box type string.
|
// Get box type string.
|
||||||
let t = buf[4..8].try_into().unwrap();
|
let t = buf[4..8].try_into().unwrap();
|
||||||
let typ = u32::from_be_bytes(t);
|
let typ = u32::from_be_bytes(t);
|
||||||
|
|
||||||
let offset = match size {
|
// Get largesize if size is 1
|
||||||
1 => 4 + 4 + 8,
|
if size == 1 {
|
||||||
_ => 4 + 4,
|
reader.read(&mut buf).unwrap();
|
||||||
};
|
let s = buf.try_into().unwrap();
|
||||||
|
let largesize = u64::from_be_bytes(s);
|
||||||
|
|
||||||
Ok(BoxHeader {
|
Ok(BoxHeader {
|
||||||
name: BoxType::from(typ),
|
name: BoxType::from(typ),
|
||||||
size: size as u64,
|
size: largesize,
|
||||||
offset: offset as u64,
|
})
|
||||||
})
|
} else {
|
||||||
|
Ok(BoxHeader {
|
||||||
|
name: BoxType::from(typ),
|
||||||
|
size: size as u64,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue