2020-07-31 17:12:26 +00:00
|
|
|
use std::io::{Seek, SeekFrom, Read, Write};
|
2020-07-28 16:36:17 +00:00
|
|
|
|
|
|
|
use crate::*;
|
2020-07-31 17:12:26 +00:00
|
|
|
use crate::atoms::*;
|
|
|
|
use crate::atoms::{
|
|
|
|
stsd::StsdBox,
|
|
|
|
stts::SttsBox,
|
|
|
|
ctts::CttsBox,
|
|
|
|
stss::StssBox,
|
|
|
|
stsc::StscBox,
|
|
|
|
stsz::StszBox,
|
|
|
|
stco::StcoBox,
|
|
|
|
co64::Co64Box,
|
|
|
|
};
|
2020-07-28 16:36:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct StblBox {
|
|
|
|
pub stsd: Option<StsdBox>,
|
2020-07-31 17:12:26 +00:00
|
|
|
pub stts: Option<SttsBox>,
|
|
|
|
pub ctts: Option<CttsBox>,
|
|
|
|
pub stss: Option<StssBox>,
|
|
|
|
pub stsc: Option<StscBox>,
|
|
|
|
pub stsz: Option<StszBox>,
|
|
|
|
pub stco: Option<StcoBox>,
|
|
|
|
pub co64: Option<Co64Box>,
|
2020-07-28 16:36:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl StblBox {
|
|
|
|
pub(crate) fn new() -> StblBox {
|
|
|
|
Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Mp4Box for StblBox {
|
2020-07-31 17:12:26 +00:00
|
|
|
fn box_type() -> BoxType {
|
2020-07-28 16:36:17 +00:00
|
|
|
BoxType::StblBox
|
|
|
|
}
|
|
|
|
|
|
|
|
fn box_size(&self) -> u64 {
|
|
|
|
let mut size = HEADER_SIZE;
|
2020-07-31 17:12:26 +00:00
|
|
|
if let Some(ref stsd) = self.stsd {
|
|
|
|
size += stsd.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref stts) = self.stts {
|
2020-07-28 16:36:17 +00:00
|
|
|
size += stts.box_size();
|
|
|
|
}
|
2020-07-31 17:12:26 +00:00
|
|
|
if let Some(ref ctts) = self.ctts {
|
|
|
|
size += ctts.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref stss) = self.stss {
|
|
|
|
size += stss.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref stsc) = self.stsc {
|
|
|
|
size += stsc.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref stsz) = self.stsz {
|
|
|
|
size += stsz.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref stco) = self.stco {
|
|
|
|
size += stco.box_size();
|
|
|
|
}
|
|
|
|
if let Some(ref co64) = self.co64 {
|
|
|
|
size += co64.box_size();
|
2020-07-28 16:36:17 +00:00
|
|
|
}
|
|
|
|
size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-31 17:12:26 +00:00
|
|
|
impl<R: Read + Seek> ReadBox<&mut R> for StblBox {
|
|
|
|
fn read_box(reader: &mut R, size: u64) -> Result<Self> {
|
|
|
|
let start = get_box_start(reader)?;
|
|
|
|
|
2020-07-28 16:36:17 +00:00
|
|
|
let mut stbl = StblBox::new();
|
|
|
|
|
2020-07-31 17:12:26 +00:00
|
|
|
let mut current = reader.seek(SeekFrom::Current(0))?;
|
|
|
|
let end = start + size;
|
|
|
|
while current < end {
|
2020-07-28 16:36:17 +00:00
|
|
|
// Get box header.
|
2020-07-31 17:12:26 +00:00
|
|
|
let header = BoxHeader::read(reader)?;
|
2020-07-28 16:36:17 +00:00
|
|
|
let BoxHeader{ name, size: s } = header;
|
|
|
|
|
|
|
|
match name {
|
2020-07-31 17:12:26 +00:00
|
|
|
BoxType::StsdBox => {
|
|
|
|
let stsd = StsdBox::read_box(reader, s)?;
|
|
|
|
stbl.stsd = Some(stsd);
|
|
|
|
}
|
2020-07-28 16:36:17 +00:00
|
|
|
BoxType::SttsBox => {
|
|
|
|
let stts = SttsBox::read_box(reader, s)?;
|
|
|
|
stbl.stts = Some(stts);
|
|
|
|
}
|
2020-07-31 17:12:26 +00:00
|
|
|
BoxType::CttsBox => {
|
|
|
|
let ctts = CttsBox::read_box(reader, s)?;
|
|
|
|
stbl.ctts = Some(ctts);
|
|
|
|
}
|
|
|
|
BoxType::StssBox => {
|
|
|
|
let stss = StssBox::read_box(reader, s)?;
|
|
|
|
stbl.stss = Some(stss);
|
|
|
|
}
|
|
|
|
BoxType::StscBox => {
|
|
|
|
let stsc = StscBox::read_box(reader, s)?;
|
|
|
|
stbl.stsc = Some(stsc);
|
|
|
|
}
|
|
|
|
BoxType::StszBox => {
|
|
|
|
let stsz = StszBox::read_box(reader, s)?;
|
|
|
|
stbl.stsz = Some(stsz);
|
|
|
|
}
|
|
|
|
BoxType::StcoBox => {
|
|
|
|
let stco = StcoBox::read_box(reader, s)?;
|
|
|
|
stbl.stco = Some(stco);
|
|
|
|
}
|
|
|
|
BoxType::Co64Box => {
|
|
|
|
let co64 = Co64Box::read_box(reader, s)?;
|
|
|
|
stbl.co64 = Some(co64);
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// XXX warn!()
|
|
|
|
skip_box(reader, s)?;
|
2020-07-28 16:36:17 +00:00
|
|
|
}
|
|
|
|
}
|
2020-07-31 17:12:26 +00:00
|
|
|
current = reader.seek(SeekFrom::Current(0))?;
|
2020-07-28 16:36:17 +00:00
|
|
|
}
|
2020-07-31 17:12:26 +00:00
|
|
|
|
|
|
|
skip_read_to(reader, start + size)?;
|
|
|
|
|
2020-07-28 16:36:17 +00:00
|
|
|
Ok(stbl)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-31 17:12:26 +00:00
|
|
|
impl<W: Write> WriteBox<&mut W> for StblBox {
|
|
|
|
fn write_box(&self, writer: &mut W) -> Result<u64> {
|
2020-07-28 16:36:17 +00:00
|
|
|
let size = self.box_size();
|
2020-07-31 17:12:26 +00:00
|
|
|
BoxHeader::new(Self::box_type(), size).write(writer)?;
|
2020-07-28 16:36:17 +00:00
|
|
|
|
2020-07-31 17:12:26 +00:00
|
|
|
if let Some(ref stsd) = self.stsd {
|
|
|
|
stsd.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref stts) = self.stts {
|
2020-07-28 16:36:17 +00:00
|
|
|
stts.write_box(writer)?;
|
|
|
|
}
|
2020-07-31 17:12:26 +00:00
|
|
|
if let Some(ref ctts) = self.ctts {
|
|
|
|
ctts.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref stss) = self.stss {
|
|
|
|
stss.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref stsc) = self.stsc {
|
|
|
|
stsc.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref stsz) = self.stsz {
|
|
|
|
stsz.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref stco) = self.stco {
|
|
|
|
stco.write_box(writer)?;
|
|
|
|
}
|
|
|
|
if let Some(ref co64) = self.co64 {
|
|
|
|
co64.write_box(writer)?;
|
2020-07-28 16:36:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(size)
|
|
|
|
}
|
|
|
|
}
|