mirror of
https://github.com/alfg/mp4-rust.git
synced 2024-12-21 11:36:28 +00:00
Cargo fmt and clippy (#73)
* Run cargo clippy --fix * Run cargo fmt --all
This commit is contained in:
parent
33959766d4
commit
3ecfd0cc9d
52 changed files with 436 additions and 388 deletions
|
@ -1,22 +1,26 @@
|
|||
use criterion::BenchmarkId;
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use mp4;
|
||||
|
||||
use std::fs::File;
|
||||
|
||||
fn read_mp4(filename: &str) -> u64 {
|
||||
let f = File::open(filename).unwrap();
|
||||
let m = mp4::read_mp4(f).unwrap();
|
||||
let size = m.size();
|
||||
size
|
||||
|
||||
m.size()
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
let filename = "tests/samples/minimal.mp4";
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("input_example", filename), &filename, |b, &s| {
|
||||
b.iter(|| read_mp4(s));
|
||||
});
|
||||
c.bench_with_input(
|
||||
BenchmarkId::new("input_example", filename),
|
||||
&filename,
|
||||
|b, &s| {
|
||||
b.iter(|| read_mp4(s));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
criterion_main!(benches);
|
||||
criterion_main!(benches);
|
||||
|
|
|
@ -5,16 +5,9 @@ use std::io::{self, BufReader, BufWriter};
|
|||
use std::path::Path;
|
||||
|
||||
use mp4::{
|
||||
AacConfig,
|
||||
AvcConfig,
|
||||
HevcConfig,
|
||||
Vp9Config,
|
||||
TtxtConfig,
|
||||
MediaConfig,
|
||||
MediaType,
|
||||
Mp4Config,
|
||||
Result,
|
||||
TrackConfig};
|
||||
AacConfig, AvcConfig, HevcConfig, MediaConfig, MediaType, Mp4Config, Result, TrackConfig,
|
||||
TtxtConfig, Vp9Config,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -41,7 +34,7 @@ fn copy<P: AsRef<Path>>(src_filename: &P, dst_filename: &P) -> Result<()> {
|
|||
let mut mp4_writer = mp4::Mp4Writer::write_start(
|
||||
writer,
|
||||
&Mp4Config {
|
||||
major_brand: mp4_reader.major_brand().clone(),
|
||||
major_brand: *mp4_reader.major_brand(),
|
||||
minor_version: mp4_reader.minor_version(),
|
||||
compatible_brands: mp4_reader.compatible_brands().to_vec(),
|
||||
timescale: mp4_reader.timescale(),
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::io::prelude::*;
|
|||
use std::io::{self, BufReader};
|
||||
use std::path::Path;
|
||||
|
||||
use mp4::{Result, Mp4Box};
|
||||
use mp4::{Mp4Box, Result};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -25,7 +25,7 @@ fn dump<P: AsRef<Path>>(filename: &P) -> Result<()> {
|
|||
|
||||
// print out boxes
|
||||
for b in boxes.iter() {
|
||||
println!("[{}] size={} {}", b.name, b.size, b.summary);
|
||||
println!("[{}] size={} {}", b.name, b.size, b.summary);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -133,11 +133,11 @@ fn get_boxes(file: File) -> Result<Vec<Box>> {
|
|||
Ok(boxes)
|
||||
}
|
||||
|
||||
fn build_box<M: Mp4Box + std::fmt::Debug>(ref m: &M) -> Box {
|
||||
return Box{
|
||||
fn build_box<M: Mp4Box + std::fmt::Debug>(m: &M) -> Box {
|
||||
Box {
|
||||
name: m.box_type().to_string(),
|
||||
size: m.box_size(),
|
||||
summary: m.summary().unwrap(),
|
||||
indent: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ fn info<P: AsRef<Path>>(filename: &P) -> Result<()> {
|
|||
let mut compatible_brands = String::new();
|
||||
for brand in mp4.compatible_brands().iter() {
|
||||
compatible_brands.push_str(&brand.to_string());
|
||||
compatible_brands.push_str(" ");
|
||||
compatible_brands.push(' ');
|
||||
}
|
||||
println!(" compatible_brands: {}\n", compatible_brands);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::io::prelude::*;
|
|||
use std::io::{self, BufReader};
|
||||
use std::path::Path;
|
||||
|
||||
use mp4::{Result};
|
||||
use mp4::Result;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -34,13 +34,14 @@ fn samples<P: AsRef<Path>>(filename: &P) -> Result<()> {
|
|||
let sample = mp4.read_sample(track_id, sample_id);
|
||||
|
||||
if let Some(ref samp) = sample.unwrap() {
|
||||
println!("[{}] start_time={} duration={} rendering_offset={} size={} is_sync={}",
|
||||
sample_id,
|
||||
samp.start_time,
|
||||
samp.duration,
|
||||
samp.rendering_offset,
|
||||
samp.bytes.len(),
|
||||
samp.is_sync,
|
||||
println!(
|
||||
"[{}] start_time={} duration={} rendering_offset={} size={} is_sync={}",
|
||||
sample_id,
|
||||
samp.start_time,
|
||||
samp.duration,
|
||||
samp.rendering_offset,
|
||||
samp.bytes.len(),
|
||||
samp.is_sync,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,4 @@ fn main() -> mp4::Result<()> {
|
|||
let data: Vec<u8> = writer.into_writer().into_inner();
|
||||
println!("{:?}", data);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use mp4;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
|
||||
|
@ -17,11 +16,12 @@ fn main() {
|
|||
println!("Major Brand: {}", mp4.major_brand());
|
||||
|
||||
for track in mp4.tracks().values() {
|
||||
println!("Track: #{}({}) {} {}",
|
||||
println!(
|
||||
"Track: #{}({}) {} {}",
|
||||
track.track_id(),
|
||||
track.language(),
|
||||
track.track_type().unwrap(),
|
||||
track.box_type().unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -1,14 +1,14 @@
|
|||
//! `mp4` is a Rust library to read and write ISO-MP4 files.
|
||||
//!
|
||||
//!
|
||||
//! This package contains MPEG-4 specifications defined in parts:
|
||||
//! * ISO/IEC 14496-12 - ISO Base Media File Format (QuickTime, MPEG-4, etc)
|
||||
//! * ISO/IEC 14496-14 - MP4 file format
|
||||
//! * ISO/IEC 14496-17 - Streaming text format
|
||||
//!
|
||||
//!
|
||||
//! See: [mp4box] for supported MP4 atoms.
|
||||
//!
|
||||
//!
|
||||
//! ### Example
|
||||
//!
|
||||
//!
|
||||
//! ```
|
||||
//! use std::fs::File;
|
||||
//! use std::io::{BufReader};
|
||||
|
@ -49,9 +49,9 @@
|
|||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! See [examples] for more examples.
|
||||
//!
|
||||
//!
|
||||
//! # Installation
|
||||
//!
|
||||
//! Add the following to your `Cargo.toml` file:
|
||||
|
@ -60,14 +60,13 @@
|
|||
//! [dependencies]
|
||||
//! mp4 = "0.7.0"
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [mp4box]: https://github.com/alfg/mp4-rust/blob/master/src/mp4box/mod.rs
|
||||
//! [examples]: https://github.com/alfg/mp4-rust/blob/master/src/examples
|
||||
#![doc(html_root_url = "https://docs.rs/mp4/*")]
|
||||
|
||||
|
||||
use std::io::{BufReader};
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
mod error;
|
||||
pub use error::Error;
|
||||
|
@ -94,4 +93,4 @@ pub fn read_mp4(f: File) -> Result<Mp4Reader<BufReader<File>>> {
|
|||
let reader = BufReader::new(f);
|
||||
let mp4 = reader::Mp4Reader::read_header(reader, size)?;
|
||||
Ok(mp4)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -60,11 +60,11 @@ impl Avc1Box {
|
|||
|
||||
impl Mp4Box for Avc1Box {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -72,8 +72,10 @@ impl Mp4Box for Avc1Box {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("data_reference_index={} width={} height={} frame_count={}",
|
||||
self.data_reference_index, self.width, self.height, self.frame_count);
|
||||
let s = format!(
|
||||
"data_reference_index={} width={} height={} frame_count={}",
|
||||
self.data_reference_index, self.width, self.height, self.frame_count
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -197,8 +199,7 @@ impl Mp4Box for AvcCBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("avc_profile_indication={}",
|
||||
self.avc_profile_indication);
|
||||
let s = format!("avc_profile_indication={}", self.avc_profile_indication);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -25,11 +25,11 @@ impl Co64Box {
|
|||
|
||||
impl Mp4Box for Co64Box {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -31,11 +31,11 @@ pub struct CttsEntry {
|
|||
|
||||
impl Mp4Box for CttsBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -20,11 +20,11 @@ impl DinfBox {
|
|||
|
||||
impl Mp4Box for DinfBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -32,7 +32,7 @@ impl Mp4Box for DinfBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -119,11 +119,11 @@ impl DrefBox {
|
|||
|
||||
impl Mp4Box for DrefBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -131,7 +131,7 @@ impl Mp4Box for DrefBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ impl<R: Read + Seek> ReadBox<&mut R> for DrefBox {
|
|||
|
||||
match name {
|
||||
BoxType::UrlBox => {
|
||||
url = Some(UrlBox::read_box(reader, s)?);
|
||||
url = Some(UrlBox::read_box(reader, s)?);
|
||||
}
|
||||
_ => {
|
||||
skip_box(reader, s)?;
|
||||
|
@ -221,7 +221,7 @@ impl UrlBox {
|
|||
pub fn get_size(&self) -> u64 {
|
||||
let mut size = HEADER_SIZE + HEADER_EXT_SIZE;
|
||||
|
||||
if ! self.location.is_empty() {
|
||||
if !self.location.is_empty() {
|
||||
size += self.location.bytes().len() as u64 + 1;
|
||||
}
|
||||
|
||||
|
@ -231,11 +231,11 @@ impl UrlBox {
|
|||
|
||||
impl Mp4Box for UrlBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -261,7 +261,7 @@ impl<R: Read + Seek> ReadBox<&mut R> for UrlBox {
|
|||
match String::from_utf8(buf) {
|
||||
Ok(t) => {
|
||||
if t.len() != buf_size as usize {
|
||||
return Err(Error::InvalidData("string too small"))
|
||||
return Err(Error::InvalidData("string too small"));
|
||||
}
|
||||
t
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ impl<W: Write> WriteBox<&mut W> for UrlBox {
|
|||
|
||||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
if ! self.location.is_empty() {
|
||||
if !self.location.is_empty() {
|
||||
writer.write(self.location.as_bytes())?;
|
||||
writer.write_u8(0)?;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::elst::ElstBox;
|
||||
use crate::mp4box::*;
|
||||
|
@ -29,11 +29,11 @@ impl EdtsBox {
|
|||
|
||||
impl Mp4Box for EdtsBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -41,7 +41,7 @@ impl Mp4Box for EdtsBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -39,11 +39,11 @@ impl ElstBox {
|
|||
|
||||
impl Mp4Box for ElstBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -33,7 +33,7 @@ impl EmsgBox {
|
|||
match version {
|
||||
0 => 12,
|
||||
1 => 16,
|
||||
_ => panic!("version must be 0 or 1")
|
||||
_ => panic!("version must be 0 or 1"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ impl Mp4Box for EmsgBox {
|
|||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
Self::size_without_message(self.version, &self.scheme_id_uri, &self.value) +
|
||||
self.message_data.len() as u64
|
||||
Self::size_without_message(self.version, &self.scheme_id_uri, &self.value)
|
||||
+ self.message_data.len() as u64
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -64,10 +64,13 @@ impl<R: Read + Seek> ReadBox<&mut R> for EmsgBox {
|
|||
let (version, flags) = read_box_header_ext(reader)?;
|
||||
|
||||
let (
|
||||
timescale, presentation_time, presentation_time_delta, event_duration,
|
||||
timescale,
|
||||
presentation_time,
|
||||
presentation_time_delta,
|
||||
event_duration,
|
||||
id,
|
||||
scheme_id_uri,
|
||||
value
|
||||
value,
|
||||
) = match version {
|
||||
0 => {
|
||||
let scheme_id_uri = read_null_terminated_utf8_string(reader)?;
|
||||
|
@ -79,7 +82,7 @@ impl<R: Read + Seek> ReadBox<&mut R> for EmsgBox {
|
|||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
scheme_id_uri,
|
||||
value
|
||||
value,
|
||||
)
|
||||
}
|
||||
1 => (
|
||||
|
@ -89,9 +92,9 @@ impl<R: Read + Seek> ReadBox<&mut R> for EmsgBox {
|
|||
reader.read_u32::<BigEndian>()?,
|
||||
reader.read_u32::<BigEndian>()?,
|
||||
read_null_terminated_utf8_string(reader)?,
|
||||
read_null_terminated_utf8_string(reader)?
|
||||
read_null_terminated_utf8_string(reader)?,
|
||||
),
|
||||
_ => return Err(Error::InvalidData("version must be 0 or 1"))
|
||||
_ => return Err(Error::InvalidData("version must be 0 or 1")),
|
||||
};
|
||||
|
||||
let message_size = size - Self::size_without_message(version, &scheme_id_uri, &value);
|
||||
|
@ -140,7 +143,7 @@ impl<W: Write> WriteBox<&mut W> for EmsgBox {
|
|||
write_null_terminated_str(writer, &self.scheme_id_uri)?;
|
||||
write_null_terminated_str(writer, &self.value)?;
|
||||
}
|
||||
_ => return Err(Error::InvalidData("version must be 0 or 1"))
|
||||
_ => return Err(Error::InvalidData("version must be 0 or 1")),
|
||||
}
|
||||
|
||||
for &byte in &self.message_data {
|
||||
|
@ -156,7 +159,9 @@ fn read_null_terminated_utf8_string<R: Read + Seek>(reader: &mut R) -> Result<St
|
|||
loop {
|
||||
let byte = reader.read_u8()?;
|
||||
bytes.push(byte);
|
||||
if byte == 0 { break; }
|
||||
if byte == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Ok(str) = unsafe { CStr::from_bytes_with_nul_unchecked(&bytes) }.to_str() {
|
||||
Ok(str.to_string())
|
||||
|
@ -234,4 +239,4 @@ mod tests {
|
|||
let dst_box = EmsgBox::read_box(&mut reader, header.size).unwrap();
|
||||
assert_eq!(src_box, dst_box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -23,11 +23,11 @@ impl FtypBox {
|
|||
|
||||
impl Mp4Box for FtypBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -39,8 +39,12 @@ impl Mp4Box for FtypBox {
|
|||
for brand in self.compatible_brands.iter() {
|
||||
compatible_brands.push(brand.to_string());
|
||||
}
|
||||
let s = format!("major_brand={} minor_version={} compatible_brands={}",
|
||||
self.major_brand, self.minor_version, compatible_brands.join("-"));
|
||||
let s = format!(
|
||||
"major_brand={} minor_version={} compatible_brands={}",
|
||||
self.major_brand,
|
||||
self.minor_version,
|
||||
compatible_brands.join("-")
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -24,11 +24,11 @@ impl HdlrBox {
|
|||
|
||||
impl Mp4Box for HdlrBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -36,7 +36,7 @@ impl Mp4Box for HdlrBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("handler_type={} name={}", self.handler_type.to_string(), self.name);
|
||||
let s = format!("handler_type={} name={}", self.handler_type, self.name);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl<R: Read + Seek> ReadBox<&mut R> for HdlrBox {
|
|||
let handler_string = match String::from_utf8(buf) {
|
||||
Ok(t) => {
|
||||
if t.len() != buf_size as usize {
|
||||
return Err(Error::InvalidData("string too small"))
|
||||
return Err(Error::InvalidData("string too small"));
|
||||
}
|
||||
t
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -60,11 +60,11 @@ impl Hev1Box {
|
|||
|
||||
impl Mp4Box for Hev1Box {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -72,8 +72,10 @@ impl Mp4Box for Hev1Box {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("data_reference_index={} width={} height={} frame_count={}",
|
||||
self.data_reference_index, self.width, self.height, self.frame_count);
|
||||
let s = format!(
|
||||
"data_reference_index={} width={} height={} frame_count={}",
|
||||
self.data_reference_index, self.width, self.height, self.frame_count
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -170,8 +172,7 @@ impl Mp4Box for HvcCBox {
|
|||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
let size = HEADER_SIZE + 1;
|
||||
size
|
||||
HEADER_SIZE + 1
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -179,8 +180,7 @@ impl Mp4Box for HvcCBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("configuration_version={}",
|
||||
self.configuration_version);
|
||||
let s = format!("configuration_version={}", self.configuration_version);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -50,11 +50,11 @@ impl Default for MdhdBox {
|
|||
|
||||
impl Mp4Box for MdhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -62,8 +62,10 @@ impl Mp4Box for MdhdBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("creation_time={} timescale={} duration={} language={}",
|
||||
self.creation_time, self.timescale, self.duration, self.language);
|
||||
let s = format!(
|
||||
"creation_time={} timescale={} duration={} language={}",
|
||||
self.creation_time, self.timescale, self.duration, self.language
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ fn language_string(language: u16) -> String {
|
|||
.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
|
||||
.collect::<String>();
|
||||
|
||||
return lang_str;
|
||||
lang_str
|
||||
}
|
||||
|
||||
fn language_code(language: &str) -> u16 {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{hdlr::HdlrBox, mdhd::MdhdBox, minf::MinfBox};
|
||||
|
@ -23,11 +23,11 @@ impl MdiaBox {
|
|||
|
||||
impl Mp4Box for MdiaBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -35,7 +35,7 @@ impl Mp4Box for MdiaBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -40,11 +40,11 @@ impl Default for MehdBox {
|
|||
|
||||
impl Mp4Box for MehdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -105,7 +105,6 @@ mod tests {
|
|||
use crate::mp4box::BoxHeader;
|
||||
use std::io::Cursor;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_mehd32() {
|
||||
let src_box = MehdBox {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -27,17 +27,17 @@ impl MfhdBox {
|
|||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4
|
||||
HEADER_SIZE + HEADER_EXT_SIZE + 4
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for MfhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{dinf::DinfBox, smhd::SmhdBox, stbl::StblBox, vmhd::VmhdBox};
|
||||
|
@ -37,11 +37,11 @@ impl MinfBox {
|
|||
|
||||
impl Mp4Box for MinfBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -49,7 +49,7 @@ impl Mp4Box for MinfBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! All ISO-MP4 boxes (atoms) and operations.
|
||||
//!
|
||||
//!
|
||||
//! * [ISO/IEC 14496-12](https://en.wikipedia.org/wiki/MPEG-4_Part_14) - ISO Base Media File Format (QuickTime, MPEG-4, etc)
|
||||
//! * [ISO/IEC 14496-14](https://en.wikipedia.org/wiki/MPEG-4_Part_14) - MP4 file format
|
||||
//! * ISO/IEC 14496-17 - Streaming text format
|
||||
//! * [ISO 23009-1](https://www.iso.org/standard/79329.html) -Dynamic adaptive streaming over HTTP (DASH)
|
||||
//!
|
||||
//!
|
||||
//! http://developer.apple.com/documentation/QuickTime/QTFF/index.html
|
||||
//! http://www.adobe.com/devnet/video/articles/mp4_movie_atom.html
|
||||
//! http://mp4ra.org/#/atoms
|
||||
//!
|
||||
//! http://mp4ra.org/#/atoms
|
||||
//!
|
||||
//! Supported Atoms:
|
||||
//! ftyp
|
||||
//! moov
|
||||
|
@ -49,7 +49,7 @@
|
|||
//! trun
|
||||
//! mdat
|
||||
//! free
|
||||
//!
|
||||
//!
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::convert::TryInto;
|
||||
|
@ -63,21 +63,20 @@ pub(crate) mod ctts;
|
|||
pub(crate) mod dinf;
|
||||
pub(crate) mod edts;
|
||||
pub(crate) mod elst;
|
||||
pub(crate) mod emsg;
|
||||
pub(crate) mod ftyp;
|
||||
pub(crate) mod hev1;
|
||||
pub(crate) mod hdlr;
|
||||
pub(crate) mod hev1;
|
||||
pub(crate) mod mdhd;
|
||||
pub(crate) mod mdia;
|
||||
pub(crate) mod minf;
|
||||
pub(crate) mod moov;
|
||||
pub(crate) mod mvex;
|
||||
pub(crate) mod mehd;
|
||||
pub(crate) mod trex;
|
||||
pub(crate) mod emsg;
|
||||
pub(crate) mod moof;
|
||||
pub(crate) mod mp4a;
|
||||
pub(crate) mod mvhd;
|
||||
pub(crate) mod mfhd;
|
||||
pub(crate) mod minf;
|
||||
pub(crate) mod moof;
|
||||
pub(crate) mod moov;
|
||||
pub(crate) mod mp4a;
|
||||
pub(crate) mod mvex;
|
||||
pub(crate) mod mvhd;
|
||||
pub(crate) mod smhd;
|
||||
pub(crate) mod stbl;
|
||||
pub(crate) mod stco;
|
||||
|
@ -86,20 +85,21 @@ pub(crate) mod stsd;
|
|||
pub(crate) mod stss;
|
||||
pub(crate) mod stsz;
|
||||
pub(crate) mod stts;
|
||||
pub(crate) mod tkhd;
|
||||
pub(crate) mod tfhd;
|
||||
pub(crate) mod trak;
|
||||
pub(crate) mod tkhd;
|
||||
pub(crate) mod traf;
|
||||
pub(crate) mod trak;
|
||||
pub(crate) mod trex;
|
||||
pub(crate) mod trun;
|
||||
pub(crate) mod tx3g;
|
||||
pub(crate) mod vmhd;
|
||||
pub(crate) mod vp09;
|
||||
pub(crate) mod vpcc;
|
||||
|
||||
pub use ftyp::FtypBox;
|
||||
pub use moov::MoovBox;
|
||||
pub use moof::MoofBox;
|
||||
pub use emsg::EmsgBox;
|
||||
pub use ftyp::FtypBox;
|
||||
pub use moof::MoofBox;
|
||||
pub use moov::MoovBox;
|
||||
|
||||
pub const HEADER_SIZE: u64 = 8;
|
||||
// const HEADER_LARGE_SIZE: u64 = 16;
|
||||
|
@ -297,48 +297,38 @@ mod value_u32 {
|
|||
use crate::types::FixedPointU16;
|
||||
use serde::{self, Serializer};
|
||||
|
||||
pub fn serialize<S>(
|
||||
fixed: &FixedPointU16,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
pub fn serialize<S>(fixed: &FixedPointU16, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_u16(fixed.value())
|
||||
}
|
||||
{
|
||||
serializer.serialize_u16(fixed.value())
|
||||
}
|
||||
}
|
||||
|
||||
mod value_i16 {
|
||||
use crate::types::FixedPointI8;
|
||||
use serde::{self, Serializer};
|
||||
|
||||
pub fn serialize<S>(
|
||||
fixed: &FixedPointI8,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
pub fn serialize<S>(fixed: &FixedPointI8, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_i8(fixed.value())
|
||||
}
|
||||
{
|
||||
serializer.serialize_i8(fixed.value())
|
||||
}
|
||||
}
|
||||
|
||||
mod value_u8 {
|
||||
use crate::types::FixedPointU8;
|
||||
use serde::{self, Serializer};
|
||||
|
||||
pub fn serialize<S>(
|
||||
fixed: &FixedPointU8,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
pub fn serialize<S>(fixed: &FixedPointU8, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_u8(fixed.value())
|
||||
}
|
||||
{
|
||||
serializer.serialize_u8(fixed.value())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{mfhd::MfhdBox, traf::TrafBox};
|
||||
|
@ -28,11 +28,11 @@ impl MoofBox {
|
|||
|
||||
impl Mp4Box for MoofBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{mvhd::MvhdBox, mvex::MvexBox, trak::TrakBox};
|
||||
use crate::mp4box::{mvex::MvexBox, mvhd::MvhdBox, trak::TrakBox};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
|
||||
pub struct MoovBox {
|
||||
|
@ -31,11 +31,11 @@ impl MoovBox {
|
|||
|
||||
impl Mp4Box for MoovBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -65,8 +65,12 @@ impl Mp4Box for Mp4aBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("channel_count={} sample_size={} sample_rate={}",
|
||||
self.channelcount, self.samplesize, self.samplerate.value());
|
||||
let s = format!(
|
||||
"channel_count={} sample_size={} sample_rate={}",
|
||||
self.channelcount,
|
||||
self.samplesize,
|
||||
self.samplerate.value()
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -150,8 +154,11 @@ impl Mp4Box for EsdsBox {
|
|||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
HEADER_SIZE + HEADER_EXT_SIZE
|
||||
+ 1 + size_of_length(ESDescriptor::desc_size()) as u64 + ESDescriptor::desc_size() as u64
|
||||
HEADER_SIZE
|
||||
+ HEADER_EXT_SIZE
|
||||
+ 1
|
||||
+ size_of_length(ESDescriptor::desc_size()) as u64
|
||||
+ ESDescriptor::desc_size() as u64
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -292,9 +299,12 @@ impl Descriptor for ESDescriptor {
|
|||
}
|
||||
|
||||
fn desc_size() -> u32 {
|
||||
3
|
||||
+ 1 + size_of_length(DecoderConfigDescriptor::desc_size()) + DecoderConfigDescriptor::desc_size()
|
||||
+ 1 + size_of_length(SLConfigDescriptor::desc_size()) + SLConfigDescriptor::desc_size()
|
||||
3 + 1
|
||||
+ size_of_length(DecoderConfigDescriptor::desc_size())
|
||||
+ DecoderConfigDescriptor::desc_size()
|
||||
+ 1
|
||||
+ size_of_length(SLConfigDescriptor::desc_size())
|
||||
+ SLConfigDescriptor::desc_size()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,8 +338,8 @@ impl<R: Read + Seek> ReadDesc<&mut R> for ESDescriptor {
|
|||
|
||||
Ok(ESDescriptor {
|
||||
es_id,
|
||||
dec_config: dec_config.unwrap_or(DecoderConfigDescriptor::default()),
|
||||
sl_config: sl_config.unwrap_or(SLConfigDescriptor::default()),
|
||||
dec_config: dec_config.unwrap_or_default(),
|
||||
sl_config: sl_config.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +391,9 @@ impl Descriptor for DecoderConfigDescriptor {
|
|||
}
|
||||
|
||||
fn desc_size() -> u32 {
|
||||
13 + 1 + size_of_length(DecoderSpecificDescriptor::desc_size()) + DecoderSpecificDescriptor::desc_size()
|
||||
13 + 1
|
||||
+ size_of_length(DecoderSpecificDescriptor::desc_size())
|
||||
+ DecoderSpecificDescriptor::desc_size()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +433,7 @@ impl<R: Read + Seek> ReadDesc<&mut R> for DecoderConfigDescriptor {
|
|||
buffer_size_db,
|
||||
max_bitrate,
|
||||
avg_bitrate,
|
||||
dec_specific: dec_specific.unwrap_or(DecoderSpecificDescriptor::default()),
|
||||
dec_specific: dec_specific.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +491,12 @@ fn get_audio_object_type(byte_a: u8, byte_b: u8) -> u8 {
|
|||
profile
|
||||
}
|
||||
|
||||
fn get_chan_conf<R: Read + Seek>(reader: &mut R, byte_b: u8, freq_index: u8, extended_profile: bool) -> Result<u8> {
|
||||
fn get_chan_conf<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
byte_b: u8,
|
||||
freq_index: u8,
|
||||
extended_profile: bool,
|
||||
) -> Result<u8> {
|
||||
let chan_conf;
|
||||
if freq_index == 15 {
|
||||
// Skip the 24 bit sample rate
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{mehd::MehdBox, trex::TrexBox};
|
||||
|
@ -22,11 +22,11 @@ impl MvexBox {
|
|||
|
||||
impl Mp4Box for MvexBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -34,7 +34,7 @@ impl Mp4Box for MvexBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ impl<W: Write> WriteBox<&mut W> for MvexBox {
|
|||
let size = self.box_size();
|
||||
BoxHeader::new(self.box_type(), size).write(writer)?;
|
||||
|
||||
if let Some(mehd) = &self.mehd{
|
||||
if let Some(mehd) = &self.mehd {
|
||||
mehd.write_box(writer)?;
|
||||
}
|
||||
self.trex.write_box(writer)?;
|
||||
|
|
|
@ -59,11 +59,11 @@ impl Default for MvhdBox {
|
|||
|
||||
impl Mp4Box for MvhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -35,11 +35,11 @@ impl Default for SmhdBox {
|
|||
|
||||
impl Mp4Box for SmhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{
|
||||
co64::Co64Box,
|
||||
ctts::CttsBox,
|
||||
stco::StcoBox,
|
||||
stsc::StscBox,
|
||||
stsd::StsdBox,
|
||||
stss::StssBox,
|
||||
stsz::StszBox,
|
||||
stts::SttsBox,
|
||||
co64::Co64Box, ctts::CttsBox, stco::StcoBox, stsc::StscBox, stsd::StsdBox, stss::StssBox,
|
||||
stsz::StszBox, stts::SttsBox,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
|
||||
|
@ -62,11 +56,11 @@ impl StblBox {
|
|||
|
||||
impl Mp4Box for StblBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -74,7 +68,7 @@ impl Mp4Box for StblBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -153,12 +147,12 @@ impl<R: Read + Seek> ReadBox<&mut R> for StblBox {
|
|||
Ok(StblBox {
|
||||
stsd: stsd.unwrap(),
|
||||
stts: stts.unwrap(),
|
||||
ctts: ctts,
|
||||
stss: stss,
|
||||
ctts,
|
||||
stss,
|
||||
stsc: stsc.unwrap(),
|
||||
stsz: stsz.unwrap(),
|
||||
stco: stco,
|
||||
co64: co64,
|
||||
stco,
|
||||
co64,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ impl StcoBox {
|
|||
|
||||
impl Mp4Box for StcoBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -89,7 +89,7 @@ impl std::convert::TryFrom<&co64::Co64Box> for StcoBox {
|
|||
.entries
|
||||
.iter()
|
||||
.copied()
|
||||
.map(|x| u32::try_from(x))
|
||||
.map(u32::try_from)
|
||||
.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||
Ok(Self {
|
||||
version: 0,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -33,11 +33,11 @@ pub struct StscEntry {
|
|||
|
||||
impl Mp4Box for StscBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::vp09::Vp09Box;
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{avc1::Avc1Box, hev1::Hev1Box, mp4a::Mp4aBox, tx3g::Tx3gBox};
|
||||
use crate::mp4box::vp09::Vp09Box;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
|
||||
pub struct StsdBox {
|
||||
|
@ -16,7 +16,7 @@ pub struct StsdBox {
|
|||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hev1: Option<Hev1Box>,
|
||||
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub vp09: Option<Vp09Box>,
|
||||
|
||||
|
@ -51,11 +51,11 @@ impl StsdBox {
|
|||
|
||||
impl Mp4Box for StsdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -63,7 +63,7 @@ impl Mp4Box for StsdBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -25,11 +25,11 @@ impl StssBox {
|
|||
|
||||
impl Mp4Box for StssBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -27,11 +27,11 @@ impl StszBox {
|
|||
|
||||
impl Mp4Box for StszBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -39,8 +39,12 @@ impl Mp4Box for StszBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("sample_size={} sample_count={} sample_sizes={}",
|
||||
self.sample_size, self.sample_count, self.sample_sizes.len());
|
||||
let s = format!(
|
||||
"sample_size={} sample_count={} sample_sizes={}",
|
||||
self.sample_size,
|
||||
self.sample_count,
|
||||
self.sample_sizes.len()
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -31,11 +31,11 @@ pub struct SttsEntry {
|
|||
|
||||
impl Mp4Box for SttsBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -35,11 +35,11 @@ impl TfhdBox {
|
|||
|
||||
impl Mp4Box for TfhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -118,11 +118,11 @@ impl TkhdBox {
|
|||
|
||||
impl Mp4Box for TkhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{tfhd::TfhdBox, trun::TrunBox};
|
||||
|
@ -27,11 +27,11 @@ impl TrafBox {
|
|||
|
||||
impl Mp4Box for TrafBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -39,7 +39,7 @@ impl Mp4Box for TrafBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::mp4box::{edts::EdtsBox, mdia::MdiaBox, tkhd::TkhdBox};
|
||||
|
@ -32,11 +32,11 @@ impl TrakBox {
|
|||
|
||||
impl Mp4Box for TrakBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -44,7 +44,7 @@ impl Mp4Box for TrakBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("");
|
||||
let s = String::new();
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -9,10 +9,10 @@ pub struct TrexBox {
|
|||
pub version: u8,
|
||||
pub flags: u32,
|
||||
pub track_id: u32,
|
||||
pub default_sample_description_index: u32,
|
||||
pub default_sample_duration: u32,
|
||||
pub default_sample_size: u32,
|
||||
pub default_sample_flags: u32,
|
||||
pub default_sample_description_index: u32,
|
||||
pub default_sample_duration: u32,
|
||||
pub default_sample_size: u32,
|
||||
pub default_sample_flags: u32,
|
||||
}
|
||||
|
||||
impl TrexBox {
|
||||
|
@ -27,11 +27,11 @@ impl TrexBox {
|
|||
|
||||
impl Mp4Box for TrexBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -39,8 +39,10 @@ impl Mp4Box for TrexBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("track_id={} default_sample_duration={}",
|
||||
self.track_id, self.default_sample_duration);
|
||||
let s = format!(
|
||||
"track_id={} default_sample_duration={}",
|
||||
self.track_id, self.default_sample_duration
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -60,11 +60,11 @@ impl TrunBox {
|
|||
|
||||
impl Mp4Box for TrunBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -72,8 +72,7 @@ impl Mp4Box for TrunBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("sample_size={}",
|
||||
self.sample_count);
|
||||
let s = format!("sample_size={}", self.sample_count);
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +147,7 @@ impl<W: Write> WriteBox<&mut W> for TrunBox {
|
|||
write_box_header_ext(writer, self.version, self.flags)?;
|
||||
|
||||
writer.write_u32::<BigEndian>(self.sample_count)?;
|
||||
if let Some(v) = self.data_offset{
|
||||
if let Some(v) = self.data_offset {
|
||||
writer.write_i32::<BigEndian>(v)?;
|
||||
}
|
||||
if let Some(v) = self.first_sample_flags {
|
||||
|
@ -212,7 +211,10 @@ mod tests {
|
|||
fn test_trun_many_sizes() {
|
||||
let src_box = TrunBox {
|
||||
version: 0,
|
||||
flags: TrunBox::FLAG_SAMPLE_DURATION | TrunBox::FLAG_SAMPLE_SIZE | TrunBox::FLAG_SAMPLE_FLAGS | TrunBox::FLAG_SAMPLE_CTS,
|
||||
flags: TrunBox::FLAG_SAMPLE_DURATION
|
||||
| TrunBox::FLAG_SAMPLE_SIZE
|
||||
| TrunBox::FLAG_SAMPLE_FLAGS
|
||||
| TrunBox::FLAG_SAMPLE_CTS,
|
||||
data_offset: None,
|
||||
sample_count: 9,
|
||||
sample_sizes: vec![1165, 11, 11, 8545, 10126, 10866, 9643, 9351, 7730],
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -20,7 +20,7 @@ pub struct RgbaColor {
|
|||
pub red: u8,
|
||||
pub green: u8,
|
||||
pub blue: u8,
|
||||
pub alpha: u8
|
||||
pub alpha: u8,
|
||||
}
|
||||
|
||||
impl Default for Tx3gBox {
|
||||
|
@ -30,7 +30,7 @@ impl Default for Tx3gBox {
|
|||
display_flags: 0,
|
||||
horizontal_justification: 1,
|
||||
vertical_justification: -1,
|
||||
bg_color_rgba: RgbaColor{
|
||||
bg_color_rgba: RgbaColor {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
|
@ -48,17 +48,17 @@ impl Tx3gBox {
|
|||
}
|
||||
|
||||
pub fn get_size(&self) -> u64 {
|
||||
HEADER_SIZE + 6 + 32
|
||||
HEADER_SIZE + 6 + 32
|
||||
}
|
||||
}
|
||||
|
||||
impl Mp4Box for Tx3gBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -165,7 +165,7 @@ mod tests {
|
|||
display_flags: 0,
|
||||
horizontal_justification: 1,
|
||||
vertical_justification: -1,
|
||||
bg_color_rgba: RgbaColor{
|
||||
bg_color_rgba: RgbaColor {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use serde::Serialize;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
|
||||
|
@ -31,11 +31,11 @@ impl VmhdBox {
|
|||
|
||||
impl Mp4Box for VmhdBox {
|
||||
fn box_type(&self) -> BoxType {
|
||||
return self.get_type();
|
||||
self.get_type()
|
||||
}
|
||||
|
||||
fn box_size(&self) -> u64 {
|
||||
return self.get_size();
|
||||
self.get_size()
|
||||
}
|
||||
|
||||
fn to_json(&self) -> Result<String> {
|
||||
|
@ -43,11 +43,9 @@ impl Mp4Box for VmhdBox {
|
|||
}
|
||||
|
||||
fn summary(&self) -> Result<String> {
|
||||
let s = format!("graphics_mode={} op_color={}{}{}",
|
||||
self.graphics_mode,
|
||||
self.op_color.red,
|
||||
self.op_color.green,
|
||||
self.op_color.blue
|
||||
let s = format!(
|
||||
"graphics_mode={} op_color={}{}{}",
|
||||
self.graphics_mode, self.op_color.red, self.op_color.green, self.op_color.blue
|
||||
);
|
||||
Ok(s)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::Mp4Box;
|
||||
use crate::mp4box::*;
|
||||
use serde::{Serialize};
|
||||
use crate::mp4box::vpcc::VpccBox;
|
||||
use crate::mp4box::*;
|
||||
use crate::Mp4Box;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
|
||||
pub struct Vp09Box {
|
||||
|
@ -97,8 +97,14 @@ impl<R: Read + Seek> ReadBox<&mut R> for Vp09Box {
|
|||
};
|
||||
let width: u16 = reader.read_u16::<BigEndian>()?;
|
||||
let height: u16 = reader.read_u16::<BigEndian>()?;
|
||||
let horizresolution: (u16, u16) = (reader.read_u16::<BigEndian>()?, reader.read_u16::<BigEndian>()?);
|
||||
let vertresolution: (u16, u16) = (reader.read_u16::<BigEndian>()?, reader.read_u16::<BigEndian>()?);
|
||||
let horizresolution: (u16, u16) = (
|
||||
reader.read_u16::<BigEndian>()?,
|
||||
reader.read_u16::<BigEndian>()?,
|
||||
);
|
||||
let vertresolution: (u16, u16) = (
|
||||
reader.read_u16::<BigEndian>()?,
|
||||
reader.read_u16::<BigEndian>()?,
|
||||
);
|
||||
let reserved1: [u8; 4] = {
|
||||
let mut buf = [0u8; 4];
|
||||
reader.read_exact(&mut buf)?;
|
||||
|
@ -175,7 +181,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_vpcc() {
|
||||
let src_box = Vp09Box::new(&Vp9Config{ width: 1920, height: 1080 });
|
||||
let src_box = Vp09Box::new(&Vp9Config {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
});
|
||||
let mut buf = Vec::new();
|
||||
src_box.write_box(&mut buf).unwrap();
|
||||
assert_eq!(buf.len(), src_box.box_size() as usize);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Mp4Box;
|
||||
use crate::mp4box::*;
|
||||
use serde::{Serialize};
|
||||
use crate::Mp4Box;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize)]
|
||||
pub struct VpccBox {
|
||||
|
@ -82,7 +82,11 @@ impl<W: Write> WriteBox<&mut W> for VpccBox {
|
|||
|
||||
writer.write_u8(self.profile)?;
|
||||
writer.write_u8(self.level)?;
|
||||
writer.write_u8((self.bit_depth << 4) | (self.chroma_subsampling << 1) | (self.video_full_range_flag as u8))?;
|
||||
writer.write_u8(
|
||||
(self.bit_depth << 4)
|
||||
| (self.chroma_subsampling << 1)
|
||||
| (self.video_full_range_flag as u8),
|
||||
)?;
|
||||
writer.write_u8(self.color_primaries)?;
|
||||
writer.write_u8(self.transfer_characteristics)?;
|
||||
writer.write_u8(self.matrix_coefficients)?;
|
||||
|
@ -125,4 +129,4 @@ mod tests {
|
|||
let dst_box = VpccBox::read_box(&mut reader, header.size).unwrap();
|
||||
assert_eq!(src_box, dst_box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ impl<R: Read + Seek> Mp4Reader<R> {
|
|||
if moov.traks.iter().any(|trak| trak.tkhd.track_id == 0) {
|
||||
return Err(Error::InvalidData("illegal track id 0"));
|
||||
}
|
||||
moov.traks.iter()
|
||||
moov.traks
|
||||
.iter()
|
||||
.map(|trak| (trak.tkhd.track_id, Mp4Track::from(trak)))
|
||||
.collect()
|
||||
} else {
|
||||
|
@ -86,7 +87,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
|
|||
};
|
||||
|
||||
// Update tracks if any fragmented (moof) boxes are found.
|
||||
if moofs.len() > 0 {
|
||||
if !moofs.is_empty() {
|
||||
let mut default_sample_duration = 0;
|
||||
if let Some(ref moov) = moov {
|
||||
if let Some(ref mvex) = &moov.mvex {
|
||||
|
@ -143,7 +144,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
|
|||
}
|
||||
|
||||
pub fn is_fragmented(&self) -> bool {
|
||||
self.moofs.len() != 0
|
||||
!self.moofs.is_empty()
|
||||
}
|
||||
|
||||
pub fn tracks(&self) -> &HashMap<u32, Mp4Track> {
|
||||
|
|
68
src/track.rs
68
src/track.rs
|
@ -230,7 +230,7 @@ impl Mp4Track {
|
|||
}
|
||||
|
||||
pub fn sample_count(&self) -> u32 {
|
||||
if self.trafs.len() > 0 {
|
||||
if !self.trafs.is_empty() {
|
||||
let mut sample_count = 0u32;
|
||||
for traf in self.trafs.iter() {
|
||||
if let Some(ref trun) = traf.trun {
|
||||
|
@ -257,7 +257,7 @@ impl Mp4Track {
|
|||
pub fn sequence_parameter_set(&self) -> Result<&[u8]> {
|
||||
if let Some(ref avc1) = self.trak.mdia.minf.stbl.stsd.avc1 {
|
||||
match avc1.avcc.sequence_parameter_sets.get(0) {
|
||||
Some(ref nal) => Ok(nal.bytes.as_ref()),
|
||||
Some(nal) => Ok(nal.bytes.as_ref()),
|
||||
None => Err(Error::EntryInStblNotFound(
|
||||
self.track_id(),
|
||||
BoxType::AvcCBox,
|
||||
|
@ -272,7 +272,7 @@ impl Mp4Track {
|
|||
pub fn picture_parameter_set(&self) -> Result<&[u8]> {
|
||||
if let Some(ref avc1) = self.trak.mdia.minf.stbl.stsd.avc1 {
|
||||
match avc1.avcc.picture_parameter_sets.get(0) {
|
||||
Some(ref nal) => Ok(nal.bytes.as_ref()),
|
||||
Some(nal) => Ok(nal.bytes.as_ref()),
|
||||
None => Err(Error::EntryInStblNotFound(
|
||||
self.track_id(),
|
||||
BoxType::AvcCBox,
|
||||
|
@ -337,24 +337,24 @@ impl Mp4Track {
|
|||
));
|
||||
}
|
||||
}
|
||||
return Err(Error::Box2NotFound(BoxType::StcoBox, BoxType::Co64Box));
|
||||
Err(Error::Box2NotFound(BoxType::StcoBox, BoxType::Co64Box))
|
||||
}
|
||||
|
||||
fn ctts_index(&self, sample_id: u32) -> Result<(usize, u32)> {
|
||||
let ctts = self.trak.mdia.minf.stbl.ctts.as_ref().unwrap();
|
||||
let mut sample_count = 1;
|
||||
for (i, entry) in ctts.entries.iter().enumerate() {
|
||||
if sample_id <= sample_count + entry.sample_count - 1 {
|
||||
if sample_id < sample_count + entry.sample_count {
|
||||
return Ok((i, sample_count));
|
||||
}
|
||||
sample_count += entry.sample_count;
|
||||
}
|
||||
|
||||
return Err(Error::EntryInStblNotFound(
|
||||
Err(Error::EntryInStblNotFound(
|
||||
self.track_id(),
|
||||
BoxType::CttsBox,
|
||||
sample_id,
|
||||
));
|
||||
))
|
||||
}
|
||||
|
||||
/// return `(traf_idx, sample_idx_in_trun)`
|
||||
|
@ -374,7 +374,7 @@ impl Mp4Track {
|
|||
}
|
||||
|
||||
fn sample_size(&self, sample_id: u32) -> Result<u32> {
|
||||
if self.trafs.len() > 0 {
|
||||
if !self.trafs.is_empty() {
|
||||
if let Some((traf_idx, sample_idx)) = self.find_traf_idx_and_sample_idx(sample_id) {
|
||||
if let Some(size) = self.trafs[traf_idx]
|
||||
.trun
|
||||
|
@ -402,11 +402,11 @@ impl Mp4Track {
|
|||
if let Some(size) = stsz.sample_sizes.get(sample_id as usize - 1) {
|
||||
Ok(*size)
|
||||
} else {
|
||||
return Err(Error::EntryInStblNotFound(
|
||||
Err(Error::EntryInStblNotFound(
|
||||
self.track_id(),
|
||||
BoxType::StszBox,
|
||||
sample_id,
|
||||
));
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ impl Mp4Track {
|
|||
}
|
||||
|
||||
fn sample_offset(&self, sample_id: u32) -> Result<u64> {
|
||||
if self.trafs.len() > 0 {
|
||||
if !self.trafs.is_empty() {
|
||||
if let Some((traf_idx, _sample_idx)) = self.find_traf_idx_and_sample_idx(sample_id) {
|
||||
Ok(self.trafs[traf_idx].tfhd.base_data_offset as u64)
|
||||
} else {
|
||||
|
@ -462,12 +462,12 @@ impl Mp4Track {
|
|||
let mut sample_count = 1;
|
||||
let mut elapsed = 0;
|
||||
|
||||
if self.trafs.len() > 0 {
|
||||
if !self.trafs.is_empty() {
|
||||
let start_time = ((sample_id - 1) * self.default_sample_duration) as u64;
|
||||
return Ok((start_time, self.default_sample_duration));
|
||||
Ok((start_time, self.default_sample_duration))
|
||||
} else {
|
||||
for entry in stts.entries.iter() {
|
||||
if sample_id <= sample_count + entry.sample_count - 1 {
|
||||
if sample_id < sample_count + entry.sample_count {
|
||||
let start_time =
|
||||
(sample_id - sample_count) as u64 * entry.sample_delta as u64 + elapsed;
|
||||
return Ok((start_time, entry.sample_delta));
|
||||
|
@ -477,11 +477,11 @@ impl Mp4Track {
|
|||
elapsed += entry.sample_count as u64 * entry.sample_delta as u64;
|
||||
}
|
||||
|
||||
return Err(Error::EntryInStblNotFound(
|
||||
Err(Error::EntryInStblNotFound(
|
||||
self.track_id(),
|
||||
BoxType::SttsBox,
|
||||
sample_id,
|
||||
));
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ impl Mp4Track {
|
|||
}
|
||||
|
||||
fn is_sync_sample(&self, sample_id: u32) -> bool {
|
||||
if self.trafs.len() > 0 {
|
||||
if !self.trafs.is_empty() {
|
||||
let sample_sizes_count = self.sample_count() / self.trafs.len() as u32;
|
||||
return sample_id == 1 || sample_id % sample_sizes_count == 0;
|
||||
}
|
||||
|
@ -624,27 +624,25 @@ impl Mp4TrackWriter {
|
|||
self.fixed_sample_size = size;
|
||||
self.is_fixed_sample_size = true;
|
||||
}
|
||||
} else {
|
||||
if self.is_fixed_sample_size {
|
||||
if self.fixed_sample_size != size {
|
||||
self.is_fixed_sample_size = false;
|
||||
if self.trak.mdia.minf.stbl.stsz.sample_size > 0 {
|
||||
self.trak.mdia.minf.stbl.stsz.sample_size = 0;
|
||||
for _ in 0..self.trak.mdia.minf.stbl.stsz.sample_count {
|
||||
self.trak
|
||||
.mdia
|
||||
.minf
|
||||
.stbl
|
||||
.stsz
|
||||
.sample_sizes
|
||||
.push(self.fixed_sample_size);
|
||||
}
|
||||
} else if self.is_fixed_sample_size {
|
||||
if self.fixed_sample_size != size {
|
||||
self.is_fixed_sample_size = false;
|
||||
if self.trak.mdia.minf.stbl.stsz.sample_size > 0 {
|
||||
self.trak.mdia.minf.stbl.stsz.sample_size = 0;
|
||||
for _ in 0..self.trak.mdia.minf.stbl.stsz.sample_count {
|
||||
self.trak
|
||||
.mdia
|
||||
.minf
|
||||
.stbl
|
||||
.stsz
|
||||
.sample_sizes
|
||||
.push(self.fixed_sample_size);
|
||||
}
|
||||
self.trak.mdia.minf.stbl.stsz.sample_sizes.push(size);
|
||||
}
|
||||
} else {
|
||||
self.trak.mdia.minf.stbl.stsz.sample_sizes.push(size);
|
||||
}
|
||||
} else {
|
||||
self.trak.mdia.minf.stbl.stsz.sample_sizes.push(size);
|
||||
}
|
||||
self.trak.mdia.minf.stbl.stsz.sample_count += 1;
|
||||
}
|
||||
|
@ -759,7 +757,7 @@ impl Mp4TrackWriter {
|
|||
}
|
||||
|
||||
fn update_sample_to_chunk(&mut self, chunk_id: u32) {
|
||||
if let Some(ref entry) = self.trak.mdia.minf.stbl.stsc.entries.last() {
|
||||
if let Some(entry) = self.trak.mdia.minf.stbl.stsc.entries.last() {
|
||||
if entry.samples_per_chunk == self.chunk_samples {
|
||||
return;
|
||||
}
|
||||
|
|
98
src/types.rs
98
src/types.rs
|
@ -1,6 +1,6 @@
|
|||
use serde::Serialize;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use serde::{Serialize};
|
||||
|
||||
use crate::mp4box::*;
|
||||
use crate::*;
|
||||
|
@ -73,14 +73,14 @@ impl FixedPointU16 {
|
|||
|
||||
impl fmt::Debug for BoxType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let fourcc: FourCC = From::from(self.clone());
|
||||
let fourcc: FourCC = From::from(*self);
|
||||
write!(f, "{}", fourcc)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BoxType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let fourcc: FourCC = From::from(self.clone());
|
||||
let fourcc: FourCC = From::from(*self);
|
||||
write!(f, "{}", fourcc)
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,9 @@ impl std::str::FromStr for FourCC {
|
|||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
if let [a, b, c, d] = s.as_bytes() {
|
||||
Ok(Self { value: [*a, *b, *c, *d] })
|
||||
Ok(Self {
|
||||
value: [*a, *b, *c, *d],
|
||||
})
|
||||
} else {
|
||||
Err(Error::InvalidData("expected exactly four bytes in string"))
|
||||
}
|
||||
|
@ -104,7 +106,9 @@ impl std::str::FromStr for FourCC {
|
|||
|
||||
impl From<u32> for FourCC {
|
||||
fn from(number: u32) -> Self {
|
||||
FourCC { value: number.to_be_bytes() }
|
||||
FourCC {
|
||||
value: number.to_be_bytes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,48 +317,48 @@ impl fmt::Display for AvcProfile {
|
|||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum AudioObjectType {
|
||||
AacMain = 1, // AAC Main Profile
|
||||
AacLowComplexity = 2, // AAC Low Complexity
|
||||
AacScalableSampleRate = 3, // AAC Scalable Sample Rate
|
||||
AacLongTermPrediction = 4, // AAC Long Term Predictor
|
||||
SpectralBandReplication = 5, // Spectral band Replication
|
||||
AACScalable = 6, // AAC Scalable
|
||||
TwinVQ = 7, // Twin VQ
|
||||
CodeExcitedLinearPrediction = 8, // CELP
|
||||
HarmonicVectorExcitationCoding = 9, // HVXC
|
||||
TextToSpeechtInterface = 12, // TTSI
|
||||
MainSynthetic = 13, // Main Synthetic
|
||||
WavetableSynthesis = 14, // Wavetable Synthesis
|
||||
GeneralMIDI = 15, // General MIDI
|
||||
AlgorithmicSynthesis = 16, // Algorithmic Synthesis
|
||||
ErrorResilientAacLowComplexity = 17, // ER AAC LC
|
||||
ErrorResilientAacLongTermPrediction = 19, // ER AAC LTP
|
||||
ErrorResilientAacScalable = 20, // ER AAC Scalable
|
||||
ErrorResilientAacTwinVQ = 21, // ER AAC TwinVQ
|
||||
ErrorResilientAacBitSlicedArithmeticCoding = 22, // ER Bit Sliced Arithmetic Coding
|
||||
ErrorResilientAacLowDelay = 23, // ER AAC Low Delay
|
||||
ErrorResilientCodeExcitedLinearPrediction = 24, // ER CELP
|
||||
ErrorResilientHarmonicVectorExcitationCoding = 25, // ER HVXC
|
||||
ErrorResilientHarmonicIndividualLinesNoise = 26, // ER HILN
|
||||
ErrorResilientParametric = 27, // ER Parametric
|
||||
SinuSoidalCoding = 28, // SSC
|
||||
ParametricStereo = 29, // PS
|
||||
MpegSurround = 30, // MPEG Surround
|
||||
MpegLayer1 = 32, // MPEG Layer 1
|
||||
MpegLayer2 = 33, // MPEG Layer 2
|
||||
MpegLayer3 = 34, // MPEG Layer 3
|
||||
DirectStreamTransfer = 35, // DST Direct Stream Transfer
|
||||
AudioLosslessCoding = 36, // ALS Audio Lossless Coding
|
||||
ScalableLosslessCoding = 37, // SLC Scalable Lossless Coding
|
||||
ScalableLosslessCodingNoneCore = 38, // SLC non-core
|
||||
ErrorResilientAacEnhancedLowDelay = 39, // ER AAC ELD
|
||||
SymbolicMusicRepresentationSimple = 40, // SMR Simple
|
||||
SymbolicMusicRepresentationMain = 41, // SMR Main
|
||||
UnifiedSpeechAudioCoding = 42, // USAC
|
||||
SpatialAudioObjectCoding = 43, // SAOC
|
||||
LowDelayMpegSurround = 44, // LD MPEG Surround
|
||||
SpatialAudioObjectCodingDialogueEnhancement = 45, // SAOC-DE
|
||||
AudioSync = 46, // Audio Sync
|
||||
AacMain = 1, // AAC Main Profile
|
||||
AacLowComplexity = 2, // AAC Low Complexity
|
||||
AacScalableSampleRate = 3, // AAC Scalable Sample Rate
|
||||
AacLongTermPrediction = 4, // AAC Long Term Predictor
|
||||
SpectralBandReplication = 5, // Spectral band Replication
|
||||
AACScalable = 6, // AAC Scalable
|
||||
TwinVQ = 7, // Twin VQ
|
||||
CodeExcitedLinearPrediction = 8, // CELP
|
||||
HarmonicVectorExcitationCoding = 9, // HVXC
|
||||
TextToSpeechtInterface = 12, // TTSI
|
||||
MainSynthetic = 13, // Main Synthetic
|
||||
WavetableSynthesis = 14, // Wavetable Synthesis
|
||||
GeneralMIDI = 15, // General MIDI
|
||||
AlgorithmicSynthesis = 16, // Algorithmic Synthesis
|
||||
ErrorResilientAacLowComplexity = 17, // ER AAC LC
|
||||
ErrorResilientAacLongTermPrediction = 19, // ER AAC LTP
|
||||
ErrorResilientAacScalable = 20, // ER AAC Scalable
|
||||
ErrorResilientAacTwinVQ = 21, // ER AAC TwinVQ
|
||||
ErrorResilientAacBitSlicedArithmeticCoding = 22, // ER Bit Sliced Arithmetic Coding
|
||||
ErrorResilientAacLowDelay = 23, // ER AAC Low Delay
|
||||
ErrorResilientCodeExcitedLinearPrediction = 24, // ER CELP
|
||||
ErrorResilientHarmonicVectorExcitationCoding = 25, // ER HVXC
|
||||
ErrorResilientHarmonicIndividualLinesNoise = 26, // ER HILN
|
||||
ErrorResilientParametric = 27, // ER Parametric
|
||||
SinuSoidalCoding = 28, // SSC
|
||||
ParametricStereo = 29, // PS
|
||||
MpegSurround = 30, // MPEG Surround
|
||||
MpegLayer1 = 32, // MPEG Layer 1
|
||||
MpegLayer2 = 33, // MPEG Layer 2
|
||||
MpegLayer3 = 34, // MPEG Layer 3
|
||||
DirectStreamTransfer = 35, // DST Direct Stream Transfer
|
||||
AudioLosslessCoding = 36, // ALS Audio Lossless Coding
|
||||
ScalableLosslessCoding = 37, // SLC Scalable Lossless Coding
|
||||
ScalableLosslessCodingNoneCore = 38, // SLC non-core
|
||||
ErrorResilientAacEnhancedLowDelay = 39, // ER AAC ELD
|
||||
SymbolicMusicRepresentationSimple = 40, // SMR Simple
|
||||
SymbolicMusicRepresentationMain = 41, // SMR Main
|
||||
UnifiedSpeechAudioCoding = 42, // USAC
|
||||
SpatialAudioObjectCoding = 43, // SAOC
|
||||
LowDelayMpegSurround = 44, // LD MPEG Surround
|
||||
SpatialAudioObjectCodingDialogueEnhancement = 45, // SAOC-DE
|
||||
AudioSync = 46, // Audio Sync
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for AudioObjectType {
|
||||
|
|
|
@ -27,9 +27,9 @@ impl<W> Mp4Writer<W> {
|
|||
///
|
||||
/// This can be useful to recover the inner writer after completion in case
|
||||
/// it's owned by the [Mp4Writer] instance.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// use mp4::{Mp4Writer, Mp4Config};
|
||||
/// use std::io::Cursor;
|
||||
|
@ -62,8 +62,8 @@ impl<W> Mp4Writer<W> {
|
|||
impl<W: Write + Seek> Mp4Writer<W> {
|
||||
pub fn write_start(mut writer: W, config: &Mp4Config) -> Result<Self> {
|
||||
let ftyp = FtypBox {
|
||||
major_brand: config.major_brand.clone(),
|
||||
minor_version: config.minor_version.clone(),
|
||||
major_brand: config.major_brand,
|
||||
minor_version: config.minor_version,
|
||||
compatible_brands: config.compatible_brands.clone(),
|
||||
};
|
||||
ftyp.write_box(&mut writer)?;
|
||||
|
|
23
tests/lib.rs
23
tests/lib.rs
|
@ -1,4 +1,6 @@
|
|||
use mp4::{AudioObjectType, AvcProfile, ChannelConfig, MediaType, Mp4Reader, SampleFreqIndex, TrackType};
|
||||
use mp4::{
|
||||
AudioObjectType, AvcProfile, ChannelConfig, MediaType, Mp4Reader, SampleFreqIndex, TrackType,
|
||||
};
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::time::Duration;
|
||||
|
@ -128,7 +130,22 @@ fn test_read_extended_audio_object_type() {
|
|||
AudioObjectType::AudioLosslessCoding
|
||||
);
|
||||
assert_eq!(
|
||||
track.trak.mdia.minf.stbl.stsd.mp4a.as_ref().unwrap().esds.as_ref().unwrap().es_desc.dec_config.dec_specific.freq_index,
|
||||
track
|
||||
.trak
|
||||
.mdia
|
||||
.minf
|
||||
.stbl
|
||||
.stsd
|
||||
.mp4a
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.esds
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.es_desc
|
||||
.dec_config
|
||||
.dec_specific
|
||||
.freq_index,
|
||||
15
|
||||
);
|
||||
assert_eq!(track.channel_config().unwrap(), ChannelConfig::Stereo);
|
||||
|
@ -141,4 +158,4 @@ fn get_reader(path: &str) -> Mp4Reader<BufReader<File>> {
|
|||
let reader = BufReader::new(f);
|
||||
|
||||
mp4::Mp4Reader::read_header(reader, f_size).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue