Created
February 28, 2019 21:01
-
-
Save shssoichiro/b031c3ae78d2717b8d2f786fe908d7d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use bitstream_io::{BigEndian, BitWriter}; | |
use std::io; | |
use std::mem::size_of; | |
use uuid::Uuid; | |
use std::io::Write; | |
/// Boxes start with a header which gives both size and type. | |
/// The header permits compact or extended size (32 or 64 bits) | |
/// and compact or extended types (32 bits or full UUIDs). | |
/// The standard boxes all use compact types (32-bit) | |
/// and most boxes will use the compact (32-bit) size. | |
/// Typically only the Media Data Box(es) need the 64-bit size. | |
struct BoxAtom { | |
/// `box_type` identifies the box type; | |
/// standard boxes use a compact type, | |
/// which is normally four printable characters, | |
/// to permit ease of identification, | |
/// and is shown so in the boxes below. | |
/// User extensions use an extended type, | |
/// which are identified via a UUID.e | |
box_type: BoxType, | |
full_box_info: Option<FullBoxInfo>, | |
data: Box<dyn BoxData>, | |
} | |
#[derive(Debug, Clone, Copy)] | |
enum BoxType { | |
Compact([u8; 4]), | |
Extended(Uuid), | |
} | |
#[derive(Debug, Clone, Copy)] | |
/// Many objects also contain a version number and flags field. | |
struct FullBoxInfo { | |
/// `version` is an integer that specifies the version of this format of the box. | |
version: u8, | |
/// `flags` is a map of flags. | |
flags: [u8; 3], | |
} | |
trait BoxData { | |
fn size(&self) -> u64; | |
fn write<W: Write>(&self, writer: &mut BitWriter<W, BigEndian>) -> io::Result<()>; | |
} | |
#[derive(Debug, Clone)] | |
struct FileTypeData { | |
/// A brand identifier. | |
/// | |
/// Each brand is a printable four-character code, registered with ISO, that identifies a precise specification. | |
major_brand: [u8; 4], | |
/// An informative integer for the minor version of the major brand. | |
minor_version: u32, | |
/// A list, to the end of the box, of brands. | |
/// | |
/// Each brand is a printable four-character code, registered with ISO, that identifies a precise specification. | |
compatible_brands: Vec<[u8; 4]>, | |
} | |
impl BoxData for FileTypeData { | |
fn size(&self) -> u64 { | |
(size_of::<u8>() * 4 + size_of::<u32>() + size_of::<u8>() * self.compatible_brands.len()) | |
as u64 | |
} | |
fn write<W: Write>(&self, writer: &mut BitWriter<W, BigEndian>) -> io::Result<()> { | |
writer.write_bytes(&self.major_brand)?; | |
writer.write(32, self.minor_version)?; | |
for brand in &self.compatible_brands { | |
writer.write_bytes(brand)?; | |
} | |
Ok(()) | |
} | |
} | |
impl BoxAtom { | |
fn file_type_box( | |
major_brand: [u8; 4], | |
minor_version: u32, | |
compatible_brands: Vec<[u8; 4]>, | |
) -> Self { | |
Self { | |
box_type: BoxType::Compact(*b"ftyp"), | |
full_box_info: None, | |
data: Box::new(FileTypeData { | |
major_brand, | |
minor_version, | |
compatible_brands, | |
}), | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment