From e0066079df535c1c95326a4e076e28153dcc3246 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 10 Mar 2020 12:55:07 +1300 Subject: [PATCH] Reformat the code using rustfmt Using rustfmt 1.4.11-stable (1838235 2019-12-03) --- mp4parse/src/boxes.rs | 8 +- mp4parse/src/lib.rs | 761 ++++++++++------- mp4parse/src/macros.rs | 2 +- mp4parse/src/tests.rs | 791 ++++++++---------- mp4parse/tests/public.rs | 288 ++++--- mp4parse_capi/build.rs | 16 +- mp4parse_capi/examples/dump.rs | 74 +- mp4parse_capi/src/lib.rs | 626 ++++++++------ .../tests/test_chunk_out_of_range.rs | 6 +- mp4parse_capi/tests/test_encryption.rs | 49 +- mp4parse_capi/tests/test_fragment.rs | 11 +- mp4parse_capi/tests/test_rotation.rs | 6 +- mp4parse_capi/tests/test_sample_table.rs | 130 ++- mp4parse_capi/tests/test_workaround_stsc.rs | 6 +- 14 files changed, 1579 insertions(+), 1195 deletions(-) diff --git a/mp4parse/src/boxes.rs b/mp4parse/src/boxes.rs index 7e8e528b..6efd83d4 100644 --- a/mp4parse/src/boxes.rs +++ b/mp4parse/src/boxes.rs @@ -42,7 +42,7 @@ macro_rules! box_database { #[derive(Default, PartialEq, Clone)] pub struct FourCC { - pub value: String + pub value: String, } impl From for FourCC { @@ -59,9 +59,7 @@ impl From for FourCC { _ => String::from("null"), // error to retrieve fourcc }; - FourCC { - value: box_string - } + FourCC { value: box_string } } } @@ -75,7 +73,7 @@ impl From for FourCC { impl<'a> From<&'a str> for FourCC { fn from(v: &'a str) -> FourCC { FourCC { - value: v.to_owned() + value: v.to_owned(), } } } diff --git a/mp4parse/src/lib.rs b/mp4parse/src/lib.rs index d3742a54..de9650c7 100644 --- a/mp4parse/src/lib.rs +++ b/mp4parse/src/lib.rs @@ -7,16 +7,16 @@ #[macro_use] extern crate log; -extern crate byteorder; extern crate bitreader; +extern crate byteorder; extern crate num_traits; -use byteorder::{ReadBytesExt, WriteBytesExt}; use bitreader::{BitReader, ReadInto}; +use byteorder::{ReadBytesExt, WriteBytesExt}; +use num_traits::Num; use std::convert::{TryFrom, TryInto as _}; -use std::io::{Read, Take}; use std::io::Cursor; +use std::io::{Read, Take}; use std::ops::{Range, RangeFrom}; -use num_traits::Num; #[cfg(feature = "mp4parse_fallible")] extern crate mp4parse_fallible; @@ -52,7 +52,9 @@ trait ToU64 { /// which can fail TryInto is used, it may panic. impl ToU64 for usize { fn to_u64(self) -> u64 { - static_assertions::const_assert!(std::mem::size_of::() <= std::mem::size_of::()); + static_assertions::const_assert!( + std::mem::size_of::() <= std::mem::size_of::() + ); self.try_into().expect("usize -> u64 conversion failed") } } @@ -70,11 +72,16 @@ macro_rules! impl_to_usize_from { ( $from_type:ty ) => { impl ToUsize for $from_type { fn to_usize(self) -> usize { - static_assertions::const_assert!(std::mem::size_of::<$from_type>() <= std::mem::size_of::()); - self.try_into().expect(concat!(stringify!($from_type), " -> usize conversion failed")) + static_assertions::const_assert!( + std::mem::size_of::<$from_type>() <= std::mem::size_of::() + ); + self.try_into().expect(concat!( + stringify!($from_type), + " -> usize conversion failed" + )) } } - } + }; } impl_to_usize_from!(u8); @@ -107,7 +114,10 @@ impl<'a, T> Offset for OffsetReader<'a, T> { impl<'a, T: Read> Read for OffsetReader<'a, T> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let bytes_read = self.reader.read(buf)?; - self.offset = self.offset.checked_add(bytes_read.to_u64()).expect("total bytes read too large for offset type"); + self.offset = self + .offset + .checked_add(bytes_read.to_u64()) + .expect("total bytes read too large for offset type"); Ok(bytes_read) } } @@ -575,7 +585,7 @@ pub struct ProtectionSchemeInfoBox { /// is parsed. #[derive(Debug, Default, Clone)] pub struct UserdataBox { - pub meta: Option + pub meta: Option, } /// Represents possible contents of the @@ -814,22 +824,27 @@ impl MediaDataBox { /// Copy the range specified by `extent` to the end of `buf` or return an error if the range /// is not fully contained within `MediaDataBox`. fn read_extent(&mut self, extent: &ExtentRange, buf: &mut Vec) -> Result<()> { - let start_offset = extent.start().checked_sub(self.offset).expect("mdat does not contain extent"); + let start_offset = extent + .start() + .checked_sub(self.offset) + .expect("mdat does not contain extent"); let slice = match extent { ExtentRange::WithLength(range) => { - let range_len = range.end.checked_sub(range.start).expect("range start > end"); - let end = start_offset.checked_add(range_len).expect("extent end overflow"); + let range_len = range + .end + .checked_sub(range.start) + .expect("range start > end"); + let end = start_offset + .checked_add(range_len) + .expect("extent end overflow"); self.data.get(start_offset.try_into()?..end.try_into()?) } - ExtentRange::ToEnd(_) => { - self.data.get(start_offset.try_into()?..) - } + ExtentRange::ToEnd(_) => self.data.get(start_offset.try_into()?..), }; let slice = slice.ok_or(Error::InvalidData("extent crosses box boundary"))?; extend_from_slice(buf, slice)?; Ok(()) } - } /// Used for 'infe' boxes within 'iinf' boxes @@ -929,7 +944,7 @@ impl ExtentRange { fn start(&self) -> u64 { match self { Self::WithLength(r) => r.start, - Self::ToEnd(r) => r.start + Self::ToEnd(r) => r.start, } } } @@ -943,7 +958,9 @@ pub enum TrackType { } impl Default for TrackType { - fn default() -> Self { TrackType::Unknown } + fn default() -> Self { + TrackType::Unknown + } } #[derive(Debug, Clone, Copy, PartialEq)] @@ -953,19 +970,21 @@ pub enum CodecType { AAC, FLAC, Opus, - H264, // 14496-10 - MP4V, // 14496-2 + H264, // 14496-10 + MP4V, // 14496-2 AV1, VP9, VP8, EncryptedVideo, EncryptedAudio, - LPCM, // QT + LPCM, // QT ALAC, } impl Default for CodecType { - fn default() -> Self { CodecType::Unknown } + fn default() -> Self { + CodecType::Unknown + } } /// The media's global (mvhd) timescale in units per second. @@ -986,7 +1005,10 @@ pub struct TrackTimeScale(pub T, pub usize); #[derive(Debug, Copy, Clone, PartialEq)] pub struct TrackScaledTime(pub T, pub usize); -impl std::ops::Add for TrackScaledTime where T: Num { +impl std::ops::Add for TrackScaledTime +where + T: Num, +{ type Output = TrackScaledTime; fn add(self, other: TrackScaledTime) -> TrackScaledTime { @@ -1008,14 +1030,17 @@ pub struct Track { pub stts: Option, pub stsc: Option, pub stsz: Option, - pub stco: Option, // It is for stco or co64. + pub stco: Option, // It is for stco or co64. pub stss: Option, pub ctts: Option, } impl Track { fn new(id: usize) -> Track { - Track { id, ..Default::default() } + Track { + id, + ..Default::default() + } } } @@ -1088,11 +1113,17 @@ impl<'a, T: Read + Offset> BMFFBox<'a, T> { /// Read the range specified by `extent` into `buf` or return an error if the range is not /// fully contained within the `BMFFBox`. fn read_extent(&mut self, extent: &ExtentRange, buf: &mut Vec) -> Result<()> { - let start_offset = extent.start().checked_sub(self.offset()).expect("box does not contain extent"); + let start_offset = extent + .start() + .checked_sub(self.offset()) + .expect("box does not contain extent"); skip(self, start_offset)?; match extent { ExtentRange::WithLength(range) => { - let len = range.end.checked_sub(range.start).expect("range start > end"); + let len = range + .end + .checked_sub(range.start) + .expect("range start > end"); if len > self.bytes_left() { return Err(Error::InvalidData("extent crosses box boundary")); } @@ -1134,7 +1165,7 @@ fn read_box_header(src: &mut T) -> Result { } size64 } - 2 ..= 7 => return Err(Error::InvalidData("malformed size")), + 2..=7 => return Err(Error::InvalidData("malformed size")), _ => u64::from(size32), }; let mut offset = match size32 { @@ -1174,8 +1205,10 @@ fn read_fullbox_extra(src: &mut T) -> Result<(u8, u32)> { let flags_a = src.read_u8()?; let flags_b = src.read_u8()?; let flags_c = src.read_u8()?; - Ok((version, - u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c))) + Ok(( + version, + u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c), + )) } // Parse the extra fields for a full box whose flag fields must be zero. @@ -1195,7 +1228,10 @@ fn skip_box_content(src: &mut BMFFBox) -> Result<()> { let to_skip = { let header = src.get_header(); debug!("{:?} (skipped)", header); - header.size.checked_sub(header.offset).expect("header offset > size") + header + .size + .checked_sub(header.offset) + .expect("header offset > size") }; assert_eq!(to_skip, src.bytes_left()); skip(src, to_skip) @@ -1229,7 +1265,7 @@ pub fn read_avif(f: &mut T, context: &mut AvifContext) -> Result<()> { return Err(Error::InvalidData("compatible_brands must contain 'mif1'")); } } else { - return Err(Error::InvalidData("'ftyp' box must occur first")) + return Err(Error::InvalidData("'ftyp' box must occur first")); } } @@ -1242,19 +1278,23 @@ pub fn read_avif(f: &mut T, context: &mut AvifContext) -> Result<()> { match b.head.name { BoxType::MetadataBox => { if read_meta { - return Err(Error::InvalidData("There should be zero or one meta boxes per ISO 14496-12:2015 § 8.11.1.1")); + return Err(Error::InvalidData( + "There should be zero or one meta boxes per ISO 14496-12:2015 § 8.11.1.1", + )); } read_meta = true; let primary_item_loc = read_avif_meta(&mut b)?; match primary_item_loc.construction_method { ConstructionMethod::File => { primary_item_extents = Some(primary_item_loc.extents); - primary_item_extents_data = primary_item_extents.iter().map(|_| vec![]).collect(); + primary_item_extents_data = + primary_item_extents.iter().map(|_| vec![]).collect(); } _ => return Err(Error::Unsupported("unsupported construction_method")), } } - BoxType::MediaDataBox => { // See ISO 14496-12:2015 § 8.1.1 + BoxType::MediaDataBox => { + // See ISO 14496-12:2015 § 8.1.1 // If we know our primary item location by this point, try to read it out of this // mdat directly and avoid a copy if let Some(extents) = &primary_item_extents { @@ -1280,9 +1320,13 @@ pub fn read_avif(f: &mut T, context: &mut AvifContext) -> Result<()> { } // If the `mdat` box came before the `meta` box, we need to fill in our primary item data - let primary_item_extents = primary_item_extents.ok_or(Error::InvalidData("primary item extents missing"))?; - for (extent, data) in primary_item_extents.iter().zip(primary_item_extents_data.iter_mut()) { - if data.is_empty() { + let primary_item_extents = + primary_item_extents.ok_or(Error::InvalidData("primary item extents missing"))?; + for (extent, data) in primary_item_extents + .iter() + .zip(primary_item_extents_data.iter_mut()) + { + if data.is_empty() { // try to find an overlapping mdat for mdat in &mut mdats { if mdat.matches_extent(&extent.extent_range) { @@ -1307,7 +1351,7 @@ fn read_avif_meta(src: &mut BMFFBox) -> Result(src: &mut BMFFBox) -> Result { if item_infos.is_some() { - return Err(Error::InvalidData("There should be zero or one iinf boxes per ISO 14496-12:2015 § 8.11.6.1")); + return Err(Error::InvalidData( + "There should be zero or one iinf boxes per ISO 14496-12:2015 § 8.11.6.1", + )); } item_infos = Some(read_iinf(&mut b)?); } BoxType::ItemLocationBox => { if iloc_items.is_some() { - return Err(Error::InvalidData("There should be zero or one iloc boxes per ISO 14496-12:2015 § 8.11.3.1")); + return Err(Error::InvalidData( + "There should be zero or one iloc boxes per ISO 14496-12:2015 § 8.11.3.1", + )); } iloc_items = Some(read_iloc(&mut b)?); } BoxType::PrimaryItemBox => { if primary_item_id.is_some() { - return Err(Error::InvalidData("There should be zero or one iloc boxes per ISO 14496-12:2015 § 8.11.4.1")); + return Err(Error::InvalidData( + "There should be zero or one iloc boxes per ISO 14496-12:2015 § 8.11.4.1", + )); } primary_item_id = Some(read_pitm(&mut b)?); } @@ -1341,21 +1391,38 @@ fn read_avif_meta(src: &mut BMFFBox) -> Result(src: &mut BMFFBox) -> Result> { let mut iter = src.box_iter(); while let Some(mut b) = iter.next_box()? { if b.head.name != BoxType::ItemInfoEntry { - return Err(Error::InvalidData("iinf box should contain only infe boxes")); + return Err(Error::InvalidData( + "iinf box should contain only infe boxes", + )); } vec_push(&mut item_infos, read_infe(&mut b)?)?; @@ -1419,17 +1488,23 @@ fn read_infe(src: &mut BMFFBox) -> Result { let item_id = match version { 2 => be_u16(src)?.into(), 3 => be_u32(src)?, - _ => return Err(Error::Unsupported("unsupported version in 'infe' box")) + _ => return Err(Error::Unsupported("unsupported version in 'infe' box")), }; let item_protection_index = be_u16(src)?; if item_protection_index != 0 { - return Err(Error::Unsupported("protected items (infe.item_protection_index != 0) are not supported")); + return Err(Error::Unsupported( + "protected items (infe.item_protection_index != 0) are not supported", + )); } let item_type = be_u32(src)?; - debug!("infe item_id {} item_type: {}", item_id, be_u32_to_string(item_type)); + debug!( + "infe item_id {} item_type: {}", + item_id, + be_u32_to_string(item_type) + ); // There are some additional fields here, but they're not of interest to us skip_box_remain(src)?; @@ -1492,14 +1567,18 @@ fn read_iloc(src: &mut BMFFBox) -> Result> let data_reference_index = iloc.read_u16(16)?; if data_reference_index != 0 { - return Err(Error::Unsupported("external file references (iloc.data_reference_index != 0) are not supported")); + return Err(Error::Unsupported( + "external file references (iloc.data_reference_index != 0) are not supported", + )); } let base_offset = iloc.read_u64(base_offset_size.to_bits())?; let extent_count = iloc.read_u16(16)?; if extent_count < 1 { - return Err(Error::InvalidData("extent_count must have a value 1 or greater per ISO 14496-12:2015 § 8.11.3.3")); + return Err(Error::InvalidData( + "extent_count must have a value 1 or greater per ISO 14496-12:2015 § 8.11.3.3", + )); } let mut extents = vec_with_capacity(extent_count.to_usize())?; @@ -1523,22 +1602,29 @@ fn read_iloc(src: &mut BMFFBox) -> Result> // "If the length is not specified, or specified as zero, then the entire length of // the source is implied" (ibid) - let start = base_offset.checked_add(extent_offset).ok_or(Error::InvalidData("offset calculation overflow"))?; + let start = base_offset + .checked_add(extent_offset) + .ok_or(Error::InvalidData("offset calculation overflow"))?; let extent_range = if extent_length == 0 { ExtentRange::ToEnd(RangeFrom { start }) } else { - let end = start.checked_add(extent_length).ok_or(Error::InvalidData("end calculation overflow"))?; + let end = start + .checked_add(extent_length) + .ok_or(Error::InvalidData("end calculation overflow"))?; ExtentRange::WithLength(Range { start, end }) }; vec_push(&mut extents, ItemLocationBoxExtent { extent_range })?; } - vec_push(&mut items, ItemLocationBoxItem { - item_id, - construction_method, - extents - })?; + vec_push( + &mut items, + ItemLocationBoxItem { + item_id, + construction_method, + extents, + }, + )?; } debug_assert_eq!(iloc.remaining(), 0); @@ -1586,11 +1672,14 @@ pub fn read_mp4(f: &mut T, context: &mut MediaContext) -> Result<()> { }; check_parser_state!(b.content); if found_moov { - debug!("found moov {}, could stop pure 'moov' parser now", if found_ftyp { - "and ftyp" - } else { - "but no ftyp" - }); + debug!( + "found moov {}, could stop pure 'moov' parser now", + if found_ftyp { + "and ftyp" + } else { + "but no ftyp" + } + ); } } @@ -1695,13 +1784,11 @@ fn read_mvex(src: &mut BMFFBox) -> Result { BoxType::MovieExtendsHeaderBox => { let duration = read_mehd(&mut b)?; fragment_duration = Some(duration); - }, + } _ => skip_box_content(&mut b)?, } } - Ok(MovieExtendsBox { - fragment_duration, - }) + Ok(MovieExtendsBox { fragment_duration }) } fn read_mehd(src: &mut BMFFBox) -> Result { @@ -1758,8 +1845,10 @@ fn read_edts(f: &mut BMFFBox, track: &mut Track) -> Result<()> { if media_time < 0 { debug!("unexpected negative media time in edit"); } - track.media_time = Some(TrackScaledTime::(std::cmp::max(0, media_time) as u64, - track.id)); + track.media_time = Some(TrackScaledTime::( + std::cmp::max(0, media_time) as u64, + track.id, + )); if elst.edits.len() > 2 { debug!("ignoring edit list with {} entries", elst.edits.len()); } @@ -1773,7 +1862,14 @@ fn read_edts(f: &mut BMFFBox, track: &mut Track) -> Result<()> { } #[allow(clippy::type_complexity)] // Allow the complex return, maybe rework in future -fn parse_mdhd(f: &mut BMFFBox, track: &mut Track) -> Result<(MediaHeaderBox, Option>, Option>)> { +fn parse_mdhd( + f: &mut BMFFBox, + track: &mut Track, +) -> Result<( + MediaHeaderBox, + Option>, + Option>, +)> { let mdhd = read_mdhd(f)?; let duration = match mdhd.duration { std::u64::MAX => None, @@ -1959,10 +2055,16 @@ fn read_tkhd(src: &mut BMFFBox) -> Result { // Skip uninteresting fields. skip(src, 16)?; - let matrix = Matrix{ - a: be_i32(src)?, b: be_i32(src)?, u: be_i32(src)?, - c: be_i32(src)?, d: be_i32(src)?, v: be_i32(src)?, - x: be_i32(src)?, y: be_i32(src)?, w: be_i32(src)?, + let matrix = Matrix { + a: be_i32(src)?, + b: be_i32(src)?, + u: be_i32(src)?, + c: be_i32(src)?, + d: be_i32(src)?, + v: be_i32(src)?, + x: be_i32(src)?, + y: be_i32(src)?, + w: be_i32(src)?, }; let width = be_u32(src)?; @@ -1996,20 +2098,21 @@ fn read_elst(src: &mut BMFFBox) -> Result { }; let media_rate_integer = be_i16(src)?; let media_rate_fraction = be_i16(src)?; - vec_push(&mut edits, Edit { - segment_duration, - media_time, - media_rate_integer, - media_rate_fraction, - })?; + vec_push( + &mut edits, + Edit { + segment_duration, + media_time, + media_rate_integer, + media_rate_fraction, + }, + )?; } // Padding could be added in some contents. skip_box_remain(src)?; - Ok(EditListBox { - edits, - }) + Ok(EditListBox { edits }) } /// Parse a mdhd box. @@ -2066,9 +2169,7 @@ fn read_stco(src: &mut BMFFBox) -> Result { // Padding could be added in some contents. skip_box_remain(src)?; - Ok(ChunkOffsetBox { - offsets, - }) + Ok(ChunkOffsetBox { offsets }) } /// Parse a co64 box. @@ -2083,9 +2184,7 @@ fn read_co64(src: &mut BMFFBox) -> Result { // Padding could be added in some contents. skip_box_remain(src)?; - Ok(ChunkOffsetBox { - offsets, - }) + Ok(ChunkOffsetBox { offsets }) } /// Parse a stss box. @@ -2100,9 +2199,7 @@ fn read_stss(src: &mut BMFFBox) -> Result { // Padding could be added in some contents. skip_box_remain(src)?; - Ok(SyncSampleBox { - samples, - }) + Ok(SyncSampleBox { samples }) } /// Parse a stsc box. @@ -2114,19 +2211,20 @@ fn read_stsc(src: &mut BMFFBox) -> Result { let first_chunk = be_u32(src)?; let samples_per_chunk = be_u32_with_limit(src)?; let sample_description_index = be_u32(src)?; - vec_push(&mut samples, SampleToChunk { - first_chunk, - samples_per_chunk, - sample_description_index, - })?; + vec_push( + &mut samples, + SampleToChunk { + first_chunk, + samples_per_chunk, + sample_description_index, + }, + )?; } // Padding could be added in some contents. skip_box_remain(src)?; - Ok(SampleToChunkBox { - samples, - }) + Ok(SampleToChunkBox { samples }) } fn read_ctts(src: &mut BMFFBox) -> Result { @@ -2144,26 +2242,27 @@ fn read_ctts(src: &mut BMFFBox) -> Result { // According to spec, Version0 shoule be used when version == 0; // however, some buggy contents have negative value when version == 0. // So we always use Version1 here. - 0 ..= 1 => { + 0..=1 => { let count = be_u32_with_limit(src)?; let offset = TimeOffsetVersion::Version1(be_i32(src)?); (count, offset) - }, + } _ => { return Err(Error::InvalidData("unsupported version in 'ctts' box")); } }; - vec_push(&mut offsets, TimeOffset { - sample_count, - time_offset, - })?; + vec_push( + &mut offsets, + TimeOffset { + sample_count, + time_offset, + }, + )?; } skip_box_remain(src)?; - Ok(CompositionOffsetBox { - samples: offsets, - }) + Ok(CompositionOffsetBox { samples: offsets }) } /// Parse a stsz box. @@ -2195,25 +2294,26 @@ fn read_stts(src: &mut BMFFBox) -> Result { for _ in 0..sample_count { let sample_count = be_u32_with_limit(src)?; let sample_delta = be_u32(src)?; - vec_push(&mut samples, Sample { - sample_count, - sample_delta, - })?; + vec_push( + &mut samples, + Sample { + sample_count, + sample_delta, + }, + )?; } // Padding could be added in some contents. skip_box_remain(src)?; - Ok(TimeToSampleBox { - samples, - }) + Ok(TimeToSampleBox { samples }) } /// Parse a VPx Config Box. fn read_vpcc(src: &mut BMFFBox) -> Result { let (version, _) = read_fullbox_extra(src)?; let supported_versions = [0, 1]; - if ! supported_versions.contains(&version) { + if !supported_versions.contains(&version) { return Err(Error::Unsupported("unknown vpcC version")); } @@ -2225,7 +2325,7 @@ fn read_vpcc(src: &mut BMFFBox) -> Result { chroma_subsampling, transfer_characteristics, matrix_coefficients, - video_full_range_flag + video_full_range_flag, ) = if version == 0 { let (bit_depth, colour_primaries) = { let byte = src.read_u8()?; @@ -2242,7 +2342,7 @@ fn read_vpcc(src: &mut BMFFBox) -> Result { chroma_subsampling, transfer_characteristics, None, - video_full_range_flag + video_full_range_flag, ) } else { let (bit_depth, chroma_subsampling, video_full_range_flag) = { @@ -2259,7 +2359,7 @@ fn read_vpcc(src: &mut BMFFBox) -> Result { chroma_subsampling, transfer_characteristics, Some(matrix_coefficients), - video_full_range_flag + video_full_range_flag, ) }; @@ -2296,7 +2396,7 @@ fn read_av1c(src: &mut BMFFBox) -> Result { let bit_depth = match flags_byte & 0x60 { 0x60 => 12, 0x40 => 10, - _ => 8 + _ => 8, }; let monochrome = flags_byte & 0x10 == 0x10; let chroma_subsampling_x = (flags_byte & 0x08) >> 3; @@ -2304,12 +2404,11 @@ fn read_av1c(src: &mut BMFFBox) -> Result { let chroma_sample_position = flags_byte & 0x03; let delay_byte = src.read_u8()?; let initial_presentation_delay_present = (delay_byte & 0x10) == 0x10; - let initial_presentation_delay_minus_one = - if initial_presentation_delay_present { - delay_byte & 0x0f - } else { - 0 - }; + let initial_presentation_delay_minus_one = if initial_presentation_delay_present { + delay_byte & 0x0f + } else { + 0 + }; let config_obus_size = src.bytes_left(); let config_obus = read_buf(src, config_obus_size)?; @@ -2325,7 +2424,7 @@ fn read_av1c(src: &mut BMFFBox) -> Result { chroma_sample_position, initial_presentation_delay_present, initial_presentation_delay_minus_one, - config_obus + config_obus, }) } @@ -2335,19 +2434,17 @@ fn read_flac_metadata(src: &mut BMFFBox) -> Result src.bytes_left() { return Err(Error::InvalidData( - "FLACMetadataBlock larger than parent box")); + "FLACMetadataBlock larger than parent box", + )); } let data = read_buf(src, length)?; - Ok(FLACMetadataBlock { - block_type, - data, - }) + Ok(FLACMetadataBlock { block_type, data }) } fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { // Tags for elementary stream description - const ESDESCR_TAG: u8 = 0x03; - const DECODER_CONFIG_TAG: u8 = 0x04; + const ESDESCR_TAG: u8 = 0x03; + const DECODER_CONFIG_TAG: u8 = 0x04; const DECODER_SPECIFIC_TAG: u8 = 0x05; let mut remains = data; @@ -2357,8 +2454,8 @@ fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { let des = &mut Cursor::new(remains); let tag = des.read_u8()?; - let mut end: u32 = 0; // It's u8 without declaration type that is incorrect. - // MSB of extend_or_len indicates more bytes, up to 4 bytes. + let mut end: u32 = 0; // It's u8 without declaration type that is incorrect. + // MSB of extend_or_len indicates more bytes, up to 4 bytes. for _ in 0..4 { if des.position() == remains.len().to_u64() { // There's nothing more to read, the 0x80 was actually part of @@ -2372,30 +2469,30 @@ fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { end += des.position() as u32; break; } - }; + } if end.to_usize() > remains.len() || u64::from(end) < des.position() { return Err(Error::InvalidData("Invalid descriptor.")); } - let descriptor = &remains[des.position().try_into()? .. end.to_usize()]; + let descriptor = &remains[des.position().try_into()?..end.to_usize()]; match tag { ESDESCR_TAG => { read_es_descriptor(descriptor, esds)?; - }, + } DECODER_CONFIG_TAG => { read_dc_descriptor(descriptor, esds)?; - }, + } DECODER_SPECIFIC_TAG => { read_ds_descriptor(descriptor, esds)?; - }, + } _ => { debug!("Unsupported descriptor, tag {}", tag); - }, + } } - remains = &remains[end.to_usize() .. remains.len()]; + remains = &remains[end.to_usize()..remains.len()]; } Ok(()) @@ -2413,11 +2510,21 @@ fn get_audio_object_type(bit_reader: &mut BitReader) -> Result { } fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { - let frequency_table = - vec![(0x0, 96000), (0x1, 88200), (0x2, 64000), (0x3, 48000), - (0x4, 44100), (0x5, 32000), (0x6, 24000), (0x7, 22050), - (0x8, 16000), (0x9, 12000), (0xa, 11025), (0xb, 8000), - (0xc, 7350)]; + let frequency_table = vec![ + (0x0, 96000), + (0x1, 88200), + (0x2, 64000), + (0x3, 48000), + (0x4, 44100), + (0x5, 32000), + (0x6, 24000), + (0x7, 22050), + (0x8, 16000), + (0x9, 12000), + (0xa, 11025), + (0xb, 8000), + (0xc, 7350), + ]; let bit_reader = &mut BitReader::new(data); @@ -2428,12 +2535,11 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { // Sample frequency could be from table, or retrieved from stream directly // if index is 0x0f. let sample_frequency = match sample_index { - 0x0F => { - Some(ReadInto::read(bit_reader, 24)?) - }, - _ => { - frequency_table.iter().find(|item| item.0 == sample_index).map(|x| x.1) - }, + 0x0F => Some(ReadInto::read(bit_reader, 24)?), + _ => frequency_table + .iter() + .find(|item| item.0 == sample_index) + .map(|x| x.1), }; let channel_configuration: u16 = ReadInto::read(bit_reader, 4)?; @@ -2450,17 +2556,20 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { let _extended_sample_index = ReadInto::read(bit_reader, 4)?; let _extended_sample_frequency: Option = match _extended_sample_index { 0x0F => Some(ReadInto::read(bit_reader, 24)?), - _ => frequency_table.iter().find(|item| item.0 == sample_index).map(|x| x.1) + _ => frequency_table + .iter() + .find(|item| item.0 == sample_index) + .map(|x| x.1), }; audio_object_type = get_audio_object_type(bit_reader)?; let _extended_channel_configuration = match audio_object_type { 22 => ReadInto::read(bit_reader, 4)?, - _ => channel_configuration + _ => channel_configuration, }; }; match audio_object_type { - 1 ..= 4 | 6 | 7 | 17 | 19 ..= 23 => { + 1..=4 | 6 | 7 | 17 | 19..=23 => { if sample_frequency.is_none() { return Err(Error::Unsupported("unknown frequency")); } @@ -2477,55 +2586,55 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { // to associate an implied sampling frequency with the desired // sampling frequency dependent tables. let sample_frequency_value = match sample_frequency.unwrap() { - 0 ..= 9390 => 8000, - 9391 ..= 11501 => 11025, - 11502 ..= 13855 => 12000, - 13856 ..= 18782 => 16000, - 18783 ..= 23003 => 22050, - 23004 ..= 27712 => 24000, - 27713 ..= 37565 => 32000, - 37566 ..= 46008 => 44100, - 46009 ..= 55425 => 48000, - 55426 ..= 75131 => 64000, - 75132 ..= 92016 => 88200, - _ => 96000 + 0..=9390 => 8000, + 9391..=11501 => 11025, + 11502..=13855 => 12000, + 13856..=18782 => 16000, + 18783..=23003 => 22050, + 23004..=27712 => 24000, + 27713..=37565 => 32000, + 37566..=46008 => 44100, + 46009..=55425 => 48000, + 55426..=75131 => 64000, + 75132..=92016 => 88200, + _ => 96000, }; - bit_reader.skip(1)?; // frameLengthFlag + bit_reader.skip(1)?; // frameLengthFlag let depend_on_core_order: u8 = ReadInto::read(bit_reader, 1)?; if depend_on_core_order > 0 { - bit_reader.skip(14)?; // codeCoderDelay + bit_reader.skip(14)?; // codeCoderDelay } - bit_reader.skip(1)?; // extensionFlag + bit_reader.skip(1)?; // extensionFlag let channel_counts = match channel_configuration { 0 => { debug!("Parsing program_config_element for channel counts"); - bit_reader.skip(4)?; // element_instance_tag - bit_reader.skip(2)?; // object_type - bit_reader.skip(4)?; // sampling_frequency_index + bit_reader.skip(4)?; // element_instance_tag + bit_reader.skip(2)?; // object_type + bit_reader.skip(4)?; // sampling_frequency_index let num_front_channel: u8 = ReadInto::read(bit_reader, 4)?; let num_side_channel: u8 = ReadInto::read(bit_reader, 4)?; - let num_back_channel:u8 = ReadInto::read(bit_reader, 4)?; + let num_back_channel: u8 = ReadInto::read(bit_reader, 4)?; let num_lfe_channel: u8 = ReadInto::read(bit_reader, 2)?; - bit_reader.skip(3)?; // num_assoc_data - bit_reader.skip(4)?; // num_valid_cc + bit_reader.skip(3)?; // num_assoc_data + bit_reader.skip(4)?; // num_valid_cc let mono_mixdown_present: bool = ReadInto::read(bit_reader, 1)?; if mono_mixdown_present { - bit_reader.skip(4)?; // mono_mixdown_element_number + bit_reader.skip(4)?; // mono_mixdown_element_number } let stereo_mixdown_present: bool = ReadInto::read(bit_reader, 1)?; if stereo_mixdown_present { - bit_reader.skip(4)?; // stereo_mixdown_element_number + bit_reader.skip(4)?; // stereo_mixdown_element_number } let matrix_mixdown_idx_present: bool = ReadInto::read(bit_reader, 1)?; if matrix_mixdown_idx_present { - bit_reader.skip(2)?; // matrix_mixdown_idx - bit_reader.skip(1)?; // pseudo_surround_enable + bit_reader.skip(2)?; // matrix_mixdown_idx + bit_reader.skip(1)?; // pseudo_surround_enable } let mut _channel_counts = 0; _channel_counts += read_surround_channel_count(bit_reader, num_front_channel)?; @@ -2533,10 +2642,10 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { _channel_counts += read_surround_channel_count(bit_reader, num_back_channel)?; _channel_counts += read_surround_channel_count(bit_reader, num_lfe_channel)?; _channel_counts - }, - 1 ..= 7 => channel_configuration, + } + 1..=7 => channel_configuration, // Amendment 4 of the AAC standard in 2013 below - 11 => 7, // 6.1 Amendment 4 of the AAC standard in 2013 + 11 => 7, // 6.1 Amendment 4 of the AAC standard in 2013 12 | 14 => 8, // 7.1 (a/d) of ITU BS.2159 _ => { return Err(Error::Unsupported("invalid channel configuration")); @@ -2551,8 +2660,8 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { esds.decoder_specific_data.extend_from_slice(data); Ok(()) - }, - _ => Err(Error::Unsupported("unknown aac audio object type")) + } + _ => Err(Error::Unsupported("unknown aac audio object type")), } } @@ -2574,7 +2683,7 @@ fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { skip(des, 12)?; if data.len().to_u64() > des.position() { - find_descriptor(&data[des.position().try_into()? .. data.len()], esds)?; + find_descriptor(&data[des.position().try_into()?..data.len()], esds)?; } esds.audio_codec = match object_profile { @@ -2607,7 +2716,7 @@ fn read_es_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> { } if data.len().to_u64() > des.position() { - find_descriptor(&data[des.position().try_into()? .. data.len()], esds)?; + find_descriptor(&data[des.position().try_into()?..data.len()], esds)?; } Ok(()) @@ -2618,7 +2727,11 @@ fn read_esds(src: &mut BMFFBox) -> Result { // Subtract 4 extra to offset the members of fullbox not accounted for in // head.offset - let esds_size = src.head.size.checked_sub(src.head.offset + 4).expect("offset invalid"); + let esds_size = src + .head + .size + .checked_sub(src.head.offset + 4) + .expect("offset invalid"); let esds_array = read_buf(src, esds_size)?; let mut es_data = ES_Descriptor::default(); @@ -2649,15 +2762,14 @@ fn read_dfla(src: &mut BMFFBox) -> Result { return Err(Error::InvalidData("FLACSpecificBox missing metadata")); } else if blocks[0].block_type != 0 { return Err(Error::InvalidData( - "FLACSpecificBox must have STREAMINFO metadata first")); + "FLACSpecificBox must have STREAMINFO metadata first", + )); } else if blocks[0].data.len() != 34 { return Err(Error::InvalidData( - "FLACSpecificBox STREAMINFO block is the wrong size")); + "FLACSpecificBox STREAMINFO block is the wrong size", + )); } - Ok(FLACSpecificBox { - version, - blocks, - }) + Ok(FLACSpecificBox { version, blocks }) } /// Parse `OpusSpecificBox`. @@ -2705,7 +2817,10 @@ fn read_dops(src: &mut BMFFBox) -> Result { /// Ogg and WebM encapsulations. To support this we prepend the `OpusHead` /// tag and byte-swap the data from big- to little-endian relative to the /// dOps box. -pub fn serialize_opus_header(opus: &OpusSpecificBox, dst: &mut W) -> Result<()> { +pub fn serialize_opus_header( + opus: &OpusSpecificBox, + dst: &mut W, +) -> Result<()> { match dst.write(b"OpusHead") { Err(e) => return Err(Error::from(e)), Ok(bytes) => { @@ -2733,7 +2848,9 @@ pub fn serialize_opus_header(opus: Err(e) => return Err(Error::from(e)), Ok(bytes) => { if bytes != table.channel_mapping.len() { - return Err(Error::InvalidData("Couldn't write channel mapping table data.")); + return Err(Error::InvalidData( + "Couldn't write channel mapping table data.", + )); } } } @@ -2754,14 +2871,15 @@ fn read_alac(src: &mut BMFFBox) -> Result { let length = match src.bytes_left() { x @ 24 | x @ 48 => x, - _ => return Err(Error::InvalidData("ALACSpecificBox magic cookie is the wrong size")), + _ => { + return Err(Error::InvalidData( + "ALACSpecificBox magic cookie is the wrong size", + )) + } }; let data = read_buf(src, length)?; - Ok(ALACSpecificBox { - version, - data, - }) + Ok(ALACSpecificBox { version, data }) } /// Parse a hdlr box. @@ -2779,9 +2897,7 @@ fn read_hdlr(src: &mut BMFFBox) -> Result { // Skip name. skip_box_remain(src)?; - Ok(HandlerBox { - handler_type, - }) + Ok(HandlerBox { handler_type }) } /// Parse an video description inside an stsd box. @@ -2821,34 +2937,41 @@ fn read_video_sample_entry(src: &mut BMFFBox) -> Result while let Some(mut b) = iter.next_box()? { match b.head.name { BoxType::AVCConfigurationBox => { - if (name != BoxType::AVCSampleEntry && - name != BoxType::AVC3SampleEntry && - name != BoxType::ProtectedVisualSampleEntry) || - codec_specific.is_some() { - return Err(Error::InvalidData("malformed video sample entry")); - } - let avcc_size = b.head.size.checked_sub(b.head.offset).expect("offset invalid"); + if (name != BoxType::AVCSampleEntry + && name != BoxType::AVC3SampleEntry + && name != BoxType::ProtectedVisualSampleEntry) + || codec_specific.is_some() + { + return Err(Error::InvalidData("malformed video sample entry")); + } + let avcc_size = b + .head + .size + .checked_sub(b.head.offset) + .expect("offset invalid"); let avcc = read_buf(&mut b.content, avcc_size)?; debug!("{:?} (avcc)", avcc); // TODO(kinetik): Parse avcC box? For now we just stash the data. codec_specific = Some(VideoCodecSpecific::AVCConfig(avcc)); } - BoxType::VPCodecConfigurationBox => { // vpcC - if (name != BoxType::VP8SampleEntry && - name != BoxType::VP9SampleEntry && - name != BoxType::ProtectedVisualSampleEntry) || - codec_specific.is_some() { - return Err(Error::InvalidData("malformed video sample entry")); - } + BoxType::VPCodecConfigurationBox => { + // vpcC + if (name != BoxType::VP8SampleEntry + && name != BoxType::VP9SampleEntry + && name != BoxType::ProtectedVisualSampleEntry) + || codec_specific.is_some() + { + return Err(Error::InvalidData("malformed video sample entry")); + } let vpcc = read_vpcc(&mut b)?; codec_specific = Some(VideoCodecSpecific::VPxConfig(vpcc)); } BoxType::AV1CodecConfigurationBox => { - if name != BoxType::AV1SampleEntry { - return Err(Error::InvalidData("malformed video sample entry")); - } - let av1c = read_av1c(&mut b)?; - codec_specific = Some(VideoCodecSpecific::AV1Config(av1c)); + if name != BoxType::AV1SampleEntry { + return Err(Error::InvalidData("malformed video sample entry")); + } + let av1c = read_av1c(&mut b)?; + codec_specific = Some(VideoCodecSpecific::AV1Config(av1c)); } BoxType::ESDBox => { if name != BoxType::MP4VideoSampleEntry || codec_specific.is_some() { @@ -2857,7 +2980,11 @@ fn read_video_sample_entry(src: &mut BMFFBox) -> Result let (_, _) = read_fullbox_extra(&mut b.content)?; // Subtract 4 extra to offset the members of fullbox not // accounted for in head.offset - let esds_size = b.head.size.checked_sub(b.head.offset + 4).expect("offset invalid"); + let esds_size = b + .head + .size + .checked_sub(b.head.offset + 4) + .expect("offset invalid"); let esds = read_buf(&mut b.content, esds_size)?; codec_specific = Some(VideoCodecSpecific::ESDSConfig(esds)); } @@ -2877,15 +3004,17 @@ fn read_video_sample_entry(src: &mut BMFFBox) -> Result check_parser_state!(b.content); } - Ok(codec_specific.map_or(SampleEntry::Unknown, - |codec_specific| SampleEntry::Video(VideoSampleEntry { - codec_type, - data_reference_index, - width, - height, - codec_specific, - protection_info, - })) + Ok( + codec_specific.map_or(SampleEntry::Unknown, |codec_specific| { + SampleEntry::Video(VideoSampleEntry { + codec_type, + data_reference_index, + width, + height, + codec_specific, + protection_info, + }) + }), ) } @@ -2897,7 +3026,7 @@ fn read_qt_wave_atom(src: &mut BMFFBox) -> Result { BoxType::ESDBox => { let esds = read_esds(&mut b)?; codec_specific = Some(esds); - }, + } _ => skip_box_content(&mut b)?, } } @@ -2937,7 +3066,7 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result // Quicktime sound sample description version 1. // Skip uninteresting fields. skip(src, 16)?; - }, + } 2 => { // Quicktime sound sample description version 2. skip(src, 4)?; @@ -2945,7 +3074,11 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result channelcount = be_u32(src)?; skip(src, 20)?; } - _ => return Err(Error::Unsupported("unsupported non-isom audio sample entry")), + _ => { + return Err(Error::Unsupported( + "unsupported non-isom audio sample entry", + )) + } } let (mut codec_type, mut codec_specific) = match name { @@ -2958,9 +3091,10 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result while let Some(mut b) = iter.next_box()? { match b.head.name { BoxType::ESDBox => { - if (name != BoxType::MP4AudioSampleEntry && - name != BoxType::ProtectedAudioSampleEntry) || - codec_specific.is_some() { + if (name != BoxType::MP4AudioSampleEntry + && name != BoxType::ProtectedAudioSampleEntry) + || codec_specific.is_some() + { return Err(Error::InvalidData("malformed audio sample entry")); } let esds = read_esds(&mut b)?; @@ -2968,9 +3102,9 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result codec_specific = Some(AudioCodecSpecific::ES_Descriptor(esds)); } BoxType::FLACSpecificBox => { - if (name != BoxType::FLACSampleEntry && - name != BoxType::ProtectedAudioSampleEntry) || - codec_specific.is_some() { + if (name != BoxType::FLACSampleEntry && name != BoxType::ProtectedAudioSampleEntry) + || codec_specific.is_some() + { return Err(Error::InvalidData("malformed audio sample entry")); } let dfla = read_dfla(&mut b)?; @@ -2978,9 +3112,9 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result codec_specific = Some(AudioCodecSpecific::FLACSpecificBox(dfla)); } BoxType::OpusSpecificBox => { - if (name != BoxType::OpusSampleEntry && - name != BoxType::ProtectedAudioSampleEntry) || - codec_specific.is_some() { + if (name != BoxType::OpusSampleEntry && name != BoxType::ProtectedAudioSampleEntry) + || codec_specific.is_some() + { return Err(Error::InvalidData("malformed audio sample entry")); } let dops = read_dops(&mut b)?; @@ -2988,8 +3122,7 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result codec_specific = Some(AudioCodecSpecific::OpusSpecificBox(dops)); } BoxType::ALACSpecificBox => { - if name != BoxType::ALACSpecificBox || - codec_specific.is_some() { + if name != BoxType::ALACSpecificBox || codec_specific.is_some() { return Err(Error::InvalidData("malformed audio sample entry")); } let alac = read_alac(&mut b)?; @@ -3018,16 +3151,18 @@ fn read_audio_sample_entry(src: &mut BMFFBox) -> Result check_parser_state!(b.content); } - Ok(codec_specific.map_or(SampleEntry::Unknown, - |codec_specific| SampleEntry::Audio(AudioSampleEntry { - codec_type, - data_reference_index, - channelcount, - samplesize, - samplerate, - codec_specific, - protection_info, - })) + Ok( + codec_specific.map_or(SampleEntry::Unknown, |codec_specific| { + SampleEntry::Audio(AudioSampleEntry { + codec_type, + data_reference_index, + channelcount, + samplesize, + samplerate, + codec_specific, + protection_info, + }) + }), ) } @@ -3056,7 +3191,7 @@ fn read_stsd(src: &mut BMFFBox, track: &mut Track) -> Result return Err(e), }; vec_push(&mut descriptions, description)?; @@ -3070,9 +3205,7 @@ fn read_stsd(src: &mut BMFFBox, track: &mut Track) -> Result(src: &mut BMFFBox) -> Result { @@ -3084,14 +3217,14 @@ fn read_sinf(src: &mut BMFFBox) -> Result { BoxType::OriginalFormatBox => { let frma = read_frma(&mut b)?; sinf.code_name = frma; - }, + } BoxType::SchemeTypeBox => { sinf.scheme_type = Some(read_schm(&mut b)?); } BoxType::SchemeInformationBox => { // We only need tenc box in schi box so far. sinf.tenc = read_schi(&mut b)?; - }, + } _ => skip_box_content(&mut b)?, } check_parser_state!(b.content); @@ -3107,10 +3240,12 @@ fn read_schi(src: &mut BMFFBox) -> Result match b.head.name { BoxType::TrackEncryptionBox => { if tenc.is_some() { - return Err(Error::InvalidData("tenc box should be only one at most in sinf box")); + return Err(Error::InvalidData( + "tenc box should be only one at most in sinf box", + )); } tenc = Some(read_tenc(&mut b)?); - }, + } _ => skip_box_content(&mut b)?, } } @@ -3128,7 +3263,7 @@ fn read_tenc(src: &mut BMFFBox) -> Result { 0 => { skip(src, 1)?; (None, None) - }, + } _ => { let pattern_byte = src.read_u8()?; let crypt_bytes = pattern_byte >> 4; @@ -3144,7 +3279,7 @@ fn read_tenc(src: &mut BMFFBox) -> Result { (1, 0) => { let default_constant_iv_size = src.read_u8()?; Some(read_buf(src, default_constant_iv_size.into())?) - }, + } _ => None, }; @@ -3154,7 +3289,7 @@ fn read_tenc(src: &mut BMFFBox) -> Result { kid: default_kid, crypt_byte_block_count: default_crypt_byte_block, skip_byte_block_count: default_skip_byte_block, - constant_iv: default_constant_iv + constant_iv: default_constant_iv, }) } @@ -3167,7 +3302,7 @@ fn read_schm(src: &mut BMFFBox) -> Result { // Flags can be used to signal presence of URI in the box, but we don't // use the URI so don't bother storing the flags. let (_, _) = read_fullbox_extra(src)?; - let scheme_type = FourCC::from(be_u32(src)?); + let scheme_type = FourCC::from(be_u32(src)?); let scheme_version = be_u32(src)?; // Null terminated scheme URI may follow, but we don't use it right now. skip_box_remain(src)?; @@ -3187,7 +3322,7 @@ fn read_udta(src: &mut BMFFBox) -> Result { BoxType::MetadataBox => { let meta = read_meta(&mut b)?; udta.meta = Some(meta); - }, + } _ => skip_box_content(&mut b)?, }; check_parser_state!(b.content); @@ -3203,7 +3338,7 @@ fn read_meta(src: &mut BMFFBox) -> Result { while let Some(mut b) = iter.next_box()? { match b.head.name { BoxType::MetadataItemListEntry => read_ilst(&mut b, &mut meta)?, - _ => skip_box_content(&mut b)? + _ => skip_box_content(&mut b)?, }; check_parser_state!(b.content); } @@ -3216,16 +3351,20 @@ fn read_ilst(src: &mut BMFFBox, meta: &mut MetadataBox) -> Result<() while let Some(mut b) = iter.next_box()? { match b.head.name { BoxType::AlbumEntry => meta.album = read_ilst_string_data(&mut b)?, - BoxType::ArtistEntry | BoxType::ArtistLowercaseEntry => - meta.artist = read_ilst_string_data(&mut b)?, + BoxType::ArtistEntry | BoxType::ArtistLowercaseEntry => { + meta.artist = read_ilst_string_data(&mut b)? + } BoxType::AlbumArtistEntry => meta.album_artist = read_ilst_string_data(&mut b)?, BoxType::CommentEntry => meta.comment = read_ilst_string_data(&mut b)?, BoxType::DateEntry => meta.year = read_ilst_string_data(&mut b)?, BoxType::TitleEntry => meta.title = read_ilst_string_data(&mut b)?, - BoxType::CustomGenreEntry => meta.genre = read_ilst_string_data(&mut b)? - .map(Genre::CustomGenre), - BoxType::StandardGenreEntry => meta.genre = read_ilst_u8_data(&mut b)? - .and_then(|gnre| Some(Genre::StandardGenre(gnre.get(1).copied()?))), + BoxType::CustomGenreEntry => { + meta.genre = read_ilst_string_data(&mut b)?.map(Genre::CustomGenre) + } + BoxType::StandardGenreEntry => { + meta.genre = read_ilst_u8_data(&mut b)? + .and_then(|gnre| Some(Genre::StandardGenre(gnre.get(1).copied()?))) + } BoxType::ComposerEntry => meta.composer = read_ilst_string_data(&mut b)?, BoxType::EncoderEntry => meta.encoder = read_ilst_string_data(&mut b)?, BoxType::EncodedByEntry => meta.encoded_by = read_ilst_string_data(&mut b)?, @@ -3248,33 +3387,38 @@ fn read_ilst(src: &mut BMFFBox, meta: &mut MetadataBox) -> Result<() BoxType::SortNameEntry => meta.sort_name = read_ilst_string_data(&mut b)?, BoxType::SortArtistEntry => meta.sort_artist = read_ilst_string_data(&mut b)?, BoxType::SortAlbumEntry => meta.sort_album = read_ilst_string_data(&mut b)?, - BoxType::SortAlbumArtistEntry => meta.sort_album_artist = read_ilst_string_data(&mut b)?, + BoxType::SortAlbumArtistEntry => { + meta.sort_album_artist = read_ilst_string_data(&mut b)? + } BoxType::SortComposerEntry => meta.sort_composer = read_ilst_string_data(&mut b)?, BoxType::TrackNumberEntry => { if let Some(trkn) = read_ilst_u8_data(&mut b)? { meta.track_number = trkn.get(3).copied(); meta.total_tracks = trkn.get(5).copied(); }; - }, + } BoxType::DiskNumberEntry => { if let Some(disk) = read_ilst_u8_data(&mut b)? { meta.disc_number = disk.get(3).copied(); meta.total_discs = disk.get(5).copied(); }; - }, - BoxType::TempoEntry => meta.beats_per_minute = read_ilst_u8_data(&mut b)? - .and_then(|tmpo| tmpo.get(1).copied()), + } + BoxType::TempoEntry => { + meta.beats_per_minute = + read_ilst_u8_data(&mut b)?.and_then(|tmpo| tmpo.get(1).copied()) + } BoxType::CompilationEntry => meta.compilation = read_ilst_bool_data(&mut b)?, - BoxType::AdvisoryEntry => meta.advisory = read_ilst_u8_data(&mut b)? - .and_then(|rtng| { + BoxType::AdvisoryEntry => { + meta.advisory = read_ilst_u8_data(&mut b)?.and_then(|rtng| { Some(match rtng.get(0)? { 2 => AdvisoryRating::Clean, 0 => AdvisoryRating::Inoffensive, r => AdvisoryRating::Explicit(*r), }) - }), - BoxType::MediaTypeEntry => meta.media_type = read_ilst_u8_data(&mut b)? - .and_then(|stik| { + }) + } + BoxType::MediaTypeEntry => { + meta.media_type = read_ilst_u8_data(&mut b)?.and_then(|stik| { Some(match stik.get(0)? { 0 => MediaType::Movie, 1 => MediaType::Normal, @@ -3284,18 +3428,21 @@ fn read_ilst(src: &mut BMFFBox, meta: &mut MetadataBox) -> Result<() 9 => MediaType::ShortFilm, 10 => MediaType::TVShow, 11 => MediaType::Booklet, - s => MediaType::Unknown(*s) + s => MediaType::Unknown(*s), }) - }), + }) + } BoxType::PodcastEntry => meta.podcast = read_ilst_bool_data(&mut b)?, - BoxType::TVSeasonNumberEntry => meta.tv_season = read_ilst_u8_data(&mut b)? - .and_then(|tvsn| tvsn.get(3).copied()), - BoxType::TVEpisodeNumberEntry => meta.tv_episode_number = read_ilst_u8_data(&mut b)? - .and_then(|tves| tves.get(3).copied()), + BoxType::TVSeasonNumberEntry => { + meta.tv_season = read_ilst_u8_data(&mut b)?.and_then(|tvsn| tvsn.get(3).copied()) + } + BoxType::TVEpisodeNumberEntry => { + meta.tv_episode_number = + read_ilst_u8_data(&mut b)?.and_then(|tves| tves.get(3).copied()) + } BoxType::GaplessPlaybackEntry => meta.gapless_playback = read_ilst_bool_data(&mut b)?, BoxType::CoverArtEntry => meta.cover_art = read_ilst_multiple_u8_data(&mut b).ok(), _ => skip_box_content(&mut b)?, - }; check_parser_state!(b.content); } @@ -3307,12 +3454,9 @@ fn read_ilst_bool_data(src: &mut BMFFBox) -> Result> { } fn read_ilst_string_data(src: &mut BMFFBox) -> Result> { - read_ilst_u8_data(src)? - .map_or(Ok(None), - |d| String::from_utf8(d) - .map_err(From::from) - .map(Some) - ) + read_ilst_u8_data(src)?.map_or(Ok(None), |d| { + String::from_utf8(d).map_err(From::from).map(Some) + }) } fn read_ilst_u8_data(src: &mut BMFFBox) -> Result>> { @@ -3402,5 +3546,6 @@ fn be_u64(src: &mut T) -> Result { } fn write_be_u32(des: &mut T, num: u32) -> Result<()> { - des.write_u32::(num).map_err(From::from) + des.write_u32::(num) + .map_err(From::from) } diff --git a/mp4parse/src/macros.rs b/mp4parse/src/macros.rs index 1486ce8c..a893f7e1 100644 --- a/mp4parse/src/macros.rs +++ b/mp4parse/src/macros.rs @@ -8,5 +8,5 @@ macro_rules! check_parser_state { debug!("bad parser state: {} content bytes left", $src.limit()); return Err(Error::InvalidData("unread box content or bad parser sync")); } - } + }; } diff --git a/mp4parse/src/tests.rs b/mp4parse/src/tests.rs index 0736596b..a49a9c0e 100644 --- a/mp4parse/src/tests.rs +++ b/mp4parse/src/tests.rs @@ -5,13 +5,13 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use std::io::Cursor; -use std::io::Read as _; -#[cfg(feature = "mp4parse_fallible")] -use std::convert::TryInto as _; use super::read_mp4; -use super::MediaContext; use super::Error; +use super::MediaContext; +#[cfg(feature = "mp4parse_fallible")] +use std::convert::TryInto as _; +use std::io::Cursor; +use std::io::Read as _; extern crate test_assembler; use self::test_assembler::*; @@ -27,7 +27,8 @@ enum BoxSize { #[allow(clippy::trivially_copy_pass_by_ref)] // TODO: Consider reworking to a copy fn make_box(size: BoxSize, name: &[u8; 4], func: F) -> Cursor> - where F: Fn(Section) -> Section +where + F: Fn(Section) -> Section, { let mut section = Section::new(); let box_size = Label::new(); @@ -57,8 +58,10 @@ fn make_box(size: BoxSize, name: &[u8; 4], func: F) -> Cursor> } BoxSize::Long(size) => assert_eq!(size, section.size()), BoxSize::Auto => { - assert!(section.size() <= u64::from(u32::max_value()), - "Tried to use a long box with BoxSize::Auto"); + assert!( + section.size() <= u64::from(u32::max_value()), + "Tried to use a long box with BoxSize::Auto" + ); box_size.set_const(section.size()); } // Skip checking BoxSize::Unchecked* cases. @@ -68,7 +71,8 @@ fn make_box(size: BoxSize, name: &[u8; 4], func: F) -> Cursor> } fn make_uuid_box(size: BoxSize, uuid: &[u8; 16], func: F) -> Cursor> - where F: Fn(Section) -> Section +where + F: Fn(Section) -> Section, { make_box(size, b"uuid", |mut s| { for b in uuid { @@ -80,14 +84,10 @@ fn make_uuid_box(size: BoxSize, uuid: &[u8; 16], func: F) -> Cursor> #[allow(clippy::trivially_copy_pass_by_ref)] // TODO: Consider reworking to a copy fn make_fullbox(size: BoxSize, name: &[u8; 4], version: u8, func: F) -> Cursor> - where F: Fn(Section) -> Section +where + F: Fn(Section) -> Section, { - make_box(size, name, |s| { - func(s.B8(version) - .B8(0) - .B8(0) - .B8(0)) - }) + make_box(size, name, |s| func(s.B8(version).B8(0).B8(0).B8(0))) } #[test] @@ -138,11 +138,9 @@ fn read_box_header_long_invalid_size() { #[test] fn read_box_header_uuid() { const HEADER_UUID: [u8; 16] = [ - 0x85, 0xc0, 0xb6,0x87, - 0x82, 0x0f, - 0x11, 0xe0, - 0x81, 0x11, - 0xf4, 0xce, 0x46, 0x2b, 0x6a, 0x48 ]; + 0x85, 0xc0, 0xb6, 0x87, 0x82, 0x0f, 0x11, 0xe0, 0x81, 0x11, 0xf4, 0xce, 0x46, 0x2b, 0x6a, + 0x48, + ]; let mut stream = make_uuid_box(BoxSize::Short(24), &HEADER_UUID, |s| s); let mut iter = super::BoxIter::new(&mut stream); @@ -156,11 +154,9 @@ fn read_box_header_uuid() { #[test] fn read_box_header_truncated_uuid() { const HEADER_UUID: [u8; 16] = [ - 0x85, 0xc0, 0xb6,0x87, - 0x82, 0x0f, - 0x11, 0xe0, - 0x81, 0x11, - 0xf4, 0xce, 0x46, 0x2b, 0x6a, 0x48 ]; + 0x85, 0xc0, 0xb6, 0x87, 0x82, 0x0f, 0x11, 0xe0, 0x81, 0x11, 0xf4, 0xce, 0x46, 0x2b, 0x6a, + 0x48, + ]; let mut stream = make_uuid_box(BoxSize::UncheckedShort(23), &HEADER_UUID, |s| s); let mut iter = super::BoxIter::new(&mut stream); @@ -174,9 +170,9 @@ fn read_box_header_truncated_uuid() { fn read_ftyp() { let mut stream = make_box(BoxSize::Short(24), b"ftyp", |s| { s.append_bytes(b"mp42") - .B32(0) // minor version - .append_bytes(b"isom") - .append_bytes(b"mp42") + .B32(0) // minor version + .append_bytes(b"isom") + .append_bytes(b"mp42") }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -216,9 +212,9 @@ fn read_ftyp_case() { // unlikely given the major_brand behaviour. let mut stream = make_box(BoxSize::Auto, b"ftyp", |s| { s.append_bytes(b"MP42") - .B32(0) // minor version - .append_bytes(b"ISOM") - .append_bytes(b"MP42") + .B32(0) // minor version + .append_bytes(b"ISOM") + .append_bytes(b"MP42") }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -236,11 +232,11 @@ fn read_ftyp_case() { fn read_elst_v0() { let mut stream = make_fullbox(BoxSize::Short(28), b"elst", 0, |s| { s.B32(1) // list count - // first entry - .B32(1234) // duration - .B32(5678) // time - .B16(12) // rate integer - .B16(34) // rate fraction + // first entry + .B32(1234) // duration + .B32(5678) // time + .B16(12) // rate integer + .B16(34) // rate fraction }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -258,16 +254,16 @@ fn read_elst_v0() { fn read_elst_v1() { let mut stream = make_fullbox(BoxSize::Short(56), b"elst", 1, |s| { s.B32(2) // list count - // first entry - .B64(1234) // duration - .B64(5678) // time - .B16(12) // rate integer - .B16(34) // rate fraction - // second entry - .B64(1234) // duration - .B64(5678) // time - .B16(12) // rate integer - .B16(34) // rate fraction + // first entry + .B64(1234) // duration + .B64(5678) // time + .B16(12) // rate integer + .B16(34) // rate fraction + // second entry + .B64(1234) // duration + .B64(5678) // time + .B16(12) // rate integer + .B16(34) // rate fraction }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -285,10 +281,10 @@ fn read_elst_v1() { fn read_mdhd_v0() { let mut stream = make_fullbox(BoxSize::Short(32), b"mdhd", 0, |s| { s.B32(0) - .B32(0) - .B32(1234) // timescale - .B32(5678) // duration - .B32(0) + .B32(0) + .B32(1234) // timescale + .B32(5678) // duration + .B32(0) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -303,10 +299,10 @@ fn read_mdhd_v0() { fn read_mdhd_v1() { let mut stream = make_fullbox(BoxSize::Short(44), b"mdhd", 1, |s| { s.B64(0) - .B64(0) - .B32(1234) // timescale - .B64(5678) // duration - .B32(0) + .B64(0) + .B32(1234) // timescale + .B64(5678) // duration + .B32(0) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -321,10 +317,10 @@ fn read_mdhd_v1() { fn read_mdhd_unknown_duration() { let mut stream = make_fullbox(BoxSize::Short(32), b"mdhd", 0, |s| { s.B32(0) - .B32(0) - .B32(1234) // timescale - .B32(::std::u32::MAX) // duration - .B32(0) + .B32(0) + .B32(1234) // timescale + .B32(::std::u32::MAX) // duration + .B32(0) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -339,10 +335,10 @@ fn read_mdhd_unknown_duration() { fn read_mdhd_invalid_timescale() { let mut stream = make_fullbox(BoxSize::Short(44), b"mdhd", 1, |s| { s.B64(0) - .B64(0) - .B32(0) // timescale - .B64(5678) // duration - .B32(0) + .B64(0) + .B32(0) // timescale + .B64(5678) // duration + .B32(0) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -355,11 +351,7 @@ fn read_mdhd_invalid_timescale() { #[test] fn read_mvhd_v0() { let mut stream = make_fullbox(BoxSize::Short(108), b"mvhd", 0, |s| { - s.B32(0) - .B32(0) - .B32(1234) - .B32(5678) - .append_repeated(0, 80) + s.B32(0).B32(0).B32(1234).B32(5678).append_repeated(0, 80) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -373,11 +365,7 @@ fn read_mvhd_v0() { #[test] fn read_mvhd_v1() { let mut stream = make_fullbox(BoxSize::Short(120), b"mvhd", 1, |s| { - s.B64(0) - .B64(0) - .B32(1234) - .B64(5678) - .append_repeated(0, 80) + s.B64(0).B64(0).B32(1234).B64(5678).append_repeated(0, 80) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -391,11 +379,7 @@ fn read_mvhd_v1() { #[test] fn read_mvhd_invalid_timescale() { let mut stream = make_fullbox(BoxSize::Short(120), b"mvhd", 1, |s| { - s.B64(0) - .B64(0) - .B32(0) - .B64(5678) - .append_repeated(0, 80) + s.B64(0).B64(0).B32(0).B64(5678).append_repeated(0, 80) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -409,10 +393,10 @@ fn read_mvhd_invalid_timescale() { fn read_mvhd_unknown_duration() { let mut stream = make_fullbox(BoxSize::Short(108), b"mvhd", 0, |s| { s.B32(0) - .B32(0) - .B32(1234) - .B32(::std::u32::MAX) - .append_repeated(0, 80) + .B32(0) + .B32(1234) + .B32(::std::u32::MAX) + .append_repeated(0, 80) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -428,11 +412,11 @@ fn read_vpcc_version_0() { let data_length = 12u16; let mut stream = make_fullbox(BoxSize::Auto, b"vpcC", 0, |s| { s.B8(2) - .B8(0) - .B8(0x82) - .B8(0) - .B16(data_length) - .append_repeated(42, data_length as usize) + .B8(0) + .B8(0x82) + .B8(0) + .B16(data_length) + .append_repeated(42, data_length as usize) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -447,14 +431,14 @@ fn read_vpcc_version_0() { fn read_vpcc_version_1() { let data_length = 12u16; let mut stream = make_fullbox(BoxSize::Auto, b"vpcC", 1, |s| { - s.B8(2) // profile - .B8(0) // level - .B8(0b1000_011_0) // bitdepth (4 bits), chroma (3 bits), video full range (1 bit) - .B8(1) // color primaries - .B8(1) // transfer characteristics - .B8(1) // matrix - .B16(data_length) - .append_repeated(42, data_length as usize) + s.B8(2) // profile + .B8(0) // level + .B8(0b1000_011_0) // bitdepth (4 bits), chroma (3 bits), video full range (1 bit) + .B8(1) // color primaries + .B8(1) // transfer characteristics + .B8(1) // matrix + .B16(data_length) + .append_repeated(42, data_length as usize) }); let mut iter = super::BoxIter::new(&mut stream); @@ -467,7 +451,7 @@ fn read_vpcc_version_1() { assert_eq!(vpcc.chroma_subsampling, 3); assert_eq!(vpcc.video_full_range_flag, false); assert_eq!(vpcc.matrix_coefficients.unwrap(), 1); - }, + } _ => panic!("vpcc parsing error"), } } @@ -476,12 +460,12 @@ fn read_vpcc_version_1() { fn read_hdlr() { let mut stream = make_fullbox(BoxSize::Short(45), b"hdlr", 0, |s| { s.B32(0) - .append_bytes(b"vide") - .B32(0) - .B32(0) - .B32(0) - .append_bytes(b"VideoHandler") - .B8(0) // null-terminate string + .append_bytes(b"vide") + .B32(0) + .B32(0) + .B32(0) + .append_bytes(b"VideoHandler") + .B8(0) // null-terminate string }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -494,12 +478,7 @@ fn read_hdlr() { #[test] fn read_hdlr_short_name() { let mut stream = make_fullbox(BoxSize::Short(33), b"hdlr", 0, |s| { - s.B32(0) - .append_bytes(b"vide") - .B32(0) - .B32(0) - .B32(0) - .B8(0) // null-terminate string + s.B32(0).append_bytes(b"vide").B32(0).B32(0).B32(0).B8(0) // null-terminate string }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -512,11 +491,7 @@ fn read_hdlr_short_name() { #[test] fn read_hdlr_zero_length_name() { let mut stream = make_fullbox(BoxSize::Short(32), b"hdlr", 0, |s| { - s.B32(0) - .append_bytes(b"vide") - .B32(0) - .B32(0) - .B32(0) + s.B32(0).append_bytes(b"vide").B32(0).B32(0).B32(0) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -528,11 +503,9 @@ fn read_hdlr_zero_length_name() { fn flac_streaminfo() -> Vec { vec![ - 0x10, 0x00, 0x10, 0x00, 0x00, 0x0a, 0x11, 0x00, - 0x38, 0x32, 0x0a, 0xc4, 0x42, 0xf0, 0x00, 0xc9, - 0xdf, 0xae, 0xb5, 0x66, 0xfc, 0x02, 0x15, 0xa3, - 0xb1, 0x54, 0x61, 0x47, 0x0f, 0xfb, 0x05, 0x00, - 0x33, 0xad, + 0x10, 0x00, 0x10, 0x00, 0x00, 0x0a, 0x11, 0x00, 0x38, 0x32, 0x0a, 0xc4, 0x42, 0xf0, 0x00, + 0xc9, 0xdf, 0xae, 0xb5, 0x66, 0xfc, 0x02, 0x15, 0xa3, 0xb1, 0x54, 0x61, 0x47, 0x0f, 0xfb, + 0x05, 0x00, 0x33, 0xad, ] } @@ -540,17 +513,23 @@ fn flac_streaminfo() -> Vec { fn read_flac() { let mut stream = make_box(BoxSize::Auto, b"fLaC", |s| { s.append_repeated(0, 6) // reserved - .B16(1) // data reference index - .B32(0) // reserved - .B32(0) // reserved - .B16(2) // channel count - .B16(16) // bits per sample - .B16(0) // pre_defined - .B16(0) // reserved - .B32(44100 << 16) // Sample rate - .append_bytes(&make_dfla(FlacBlockType::StreamInfo, true, - &flac_streaminfo(), FlacBlockLength::Correct) - .into_inner()) + .B16(1) // data reference index + .B32(0) // reserved + .B32(0) // reserved + .B16(2) // channel count + .B16(16) // bits per sample + .B16(0) // pre_defined + .B16(0) // reserved + .B32(44100 << 16) // Sample rate + .append_bytes( + &make_dfla( + FlacBlockType::StreamInfo, + true, + &flac_streaminfo(), + FlacBlockLength::Correct, + ) + .into_inner(), + ) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -576,28 +555,36 @@ enum FlacBlockLength { Incorrect(usize), } -fn make_dfla(block_type: FlacBlockType, last: bool, data: &[u8], - data_length: FlacBlockLength) -> Cursor> { - assert!(data.len() < 1<<24); +fn make_dfla( + block_type: FlacBlockType, + last: bool, + data: &[u8], + data_length: FlacBlockLength, +) -> Cursor> { + assert!(data.len() < 1 << 24); make_fullbox(BoxSize::Auto, b"dfLa", 0, |s| { let flag = if last { 1 } else { 0 }; let size = match data_length { FlacBlockLength::Correct => (data.len() as u32) & 0x00ff_ffff, FlacBlockLength::Incorrect(size) => { - assert!(size < 1<<24); + assert!(size < 1 << 24); (size as u32) & 0x00ff_ffff } }; let block_type = (block_type as u32) & 0x7f; s.B32(flag << 31 | block_type << 24 | size) - .append_bytes(data) + .append_bytes(data) }) } #[test] fn read_dfla() { - let mut stream = make_dfla(FlacBlockType::StreamInfo, true, - &flac_streaminfo(), FlacBlockLength::Correct); + let mut stream = make_dfla( + FlacBlockType::StreamInfo, + true, + &flac_streaminfo(), + FlacBlockLength::Correct, + ); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); assert_eq!(stream.head.name, BoxType::FLACSpecificBox); @@ -608,9 +595,12 @@ fn read_dfla() { #[test] fn long_flac_metadata() { let streaminfo = flac_streaminfo(); - let mut stream = make_dfla(FlacBlockType::StreamInfo, true, - &streaminfo, - FlacBlockLength::Incorrect(streaminfo.len() + 4)); + let mut stream = make_dfla( + FlacBlockType::StreamInfo, + true, + &streaminfo, + FlacBlockLength::Incorrect(streaminfo.len() + 4), + ); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); assert_eq!(stream.head.name, BoxType::FLACSpecificBox); @@ -622,15 +612,15 @@ fn long_flac_metadata() { fn read_opus() { let mut stream = make_box(BoxSize::Auto, b"Opus", |s| { s.append_repeated(0, 6) - .B16(1) // data reference index - .B32(0) - .B32(0) - .B16(2) // channel count - .B16(16) // bits per sample - .B16(0) - .B16(0) - .B32(48000 << 16) // Sample rate is always 48 kHz for Opus. - .append_bytes(&make_dops().into_inner()) + .B16(1) // data reference index + .B32(0) + .B32(0) + .B16(2) // channel count + .B16(16) // bits per sample + .B16(0) + .B16(0) + .B32(48000 << 16) // Sample rate is always 48 kHz for Opus. + .append_bytes(&make_dops().into_inner()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -641,11 +631,11 @@ fn read_opus() { fn make_dops() -> Cursor> { make_box(BoxSize::Auto, b"dOps", |s| { s.B8(0) // version - .B8(2) // channel count - .B16(348) // pre-skip - .B32(44100) // original sample rate - .B16(0) // gain - .B8(0) // channel mapping + .B8(2) // channel count + .B16(348) // pre-skip + .B32(44100) // original sample rate + .B16(0) // gain + .B8(0) // channel mapping }) } @@ -673,12 +663,13 @@ fn serialize_opus_header() { let mut v = Vec::::new(); super::serialize_opus_header(&opus, &mut v).unwrap(); assert_eq!(v.len(), 19); - assert_eq!(v, vec![ - 0x4f, 0x70, 0x75, 0x73, 0x48,0x65, 0x61, 0x64, - 0x01, 0x01, 0x56, 0x01, - 0xc0, 0x5d, 0x00, 0x00, - 0x00, 0x00, 0x00, - ]); + assert_eq!( + v, + vec![ + 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x01, 0x56, 0x01, 0xc0, 0x5d, + 0x00, 0x00, 0x00, 0x00, 0x00, + ] + ); let opus = super::OpusSpecificBox { version: 0, output_channel_count: 6, @@ -695,30 +686,31 @@ fn serialize_opus_header() { let mut v = Vec::::new(); super::serialize_opus_header(&opus, &mut v).unwrap(); assert_eq!(v.len(), 27); - assert_eq!(v, vec![ - 0x4f, 0x70, 0x75, 0x73, 0x48,0x65, 0x61, 0x64, - 0x01, 0x06, 0x98, 0x00, - 0x80, 0xbb, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x04, 0x02, - 0x00, 0x04, 0x01, 0x02, 0x03, 0x05, - ]); + assert_eq!( + v, + vec![ + 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x06, 0x98, 0x00, 0x80, 0xbb, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x00, 0x04, 0x01, 0x02, 0x03, 0x05, + ] + ); } #[test] fn read_alac() { let mut stream = make_box(BoxSize::Auto, b"alac", |s| { s.append_repeated(0, 6) // reserved - .B16(1) // data reference index - .B32(0) // reserved - .B32(0) // reserved - .B16(2) // channel count - .B16(16) // bits per sample - .B16(0) // pre_defined - .B16(0) // reserved - .B32(44100 << 16) // Sample rate - .append_bytes(&make_fullbox(BoxSize::Auto, b"alac", 0, |s| { - s.append_bytes(&[0xfa; 24]) - }).into_inner()) + .B16(1) // data reference index + .B32(0) // reserved + .B32(0) // reserved + .B16(2) // channel count + .B16(16) // bits per sample + .B16(0) // pre_defined + .B16(0) // reserved + .B32(44100 << 16) // Sample rate + .append_bytes( + &make_fullbox(BoxSize::Auto, b"alac", 0, |s| s.append_bytes(&[0xfa; 24])) + .into_inner(), + ) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -730,16 +722,16 @@ fn read_alac() { fn avcc_limit() { let mut stream = make_box(BoxSize::Auto, b"avc1", |s| { s.append_repeated(0, 6) - .B16(1) - .append_repeated(0, 16) - .B16(320) - .B16(240) - .append_repeated(0, 14) - .append_repeated(0, 32) - .append_repeated(0, 4) - .B32(0xffff_ffff) - .append_bytes(b"avcC") - .append_repeated(0, 100) + .B16(1) + .append_repeated(0, 16) + .B16(320) + .B16(240) + .append_repeated(0, 14) + .append_repeated(0, 32) + .append_repeated(0, 4) + .B32(0xffff_ffff) + .append_bytes(b"avcC") + .append_repeated(0, 100) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -754,17 +746,17 @@ fn avcc_limit() { fn esds_limit() { let mut stream = make_box(BoxSize::Auto, b"mp4a", |s| { s.append_repeated(0, 6) - .B16(1) - .B32(0) - .B32(0) - .B16(2) - .B16(16) - .B16(0) - .B16(0) - .B32(48000 << 16) - .B32(0xffff_ffff) - .append_bytes(b"esds") - .append_repeated(0, 100) + .B16(1) + .B32(0) + .B32(0) + .B16(2) + .B16(16) + .B16(0) + .B16(0) + .B32(48000 << 16) + .B32(0xffff_ffff) + .append_bytes(b"esds") + .append_repeated(0, 100) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -779,17 +771,17 @@ fn esds_limit() { fn esds_limit_2() { let mut stream = make_box(BoxSize::Auto, b"mp4a", |s| { s.append_repeated(0, 6) - .B16(1) - .B32(0) - .B32(0) - .B16(2) - .B16(16) - .B16(0) - .B16(0) - .B32(48000 << 16) - .B32(8) - .append_bytes(b"esds") - .append_repeated(0, 4) + .B16(1) + .B32(0) + .B32(0) + .B16(2) + .B16(16) + .B16(0) + .B16(0) + .B32(48000 << 16) + .B32(8) + .append_bytes(b"esds") + .append_repeated(0, 4) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -802,11 +794,7 @@ fn esds_limit_2() { #[test] fn read_elst_zero_entries() { - let mut stream = make_fullbox(BoxSize::Auto, b"elst", 0, |s| { - s.B32(0) - .B16(12) - .B16(34) - }); + let mut stream = make_fullbox(BoxSize::Auto, b"elst", 0, |s| s.B32(0).B16(12).B16(34)); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); match super::read_elst(&mut stream) { @@ -818,11 +806,11 @@ fn read_elst_zero_entries() { fn make_elst() -> Cursor> { make_fullbox(BoxSize::Auto, b"elst", 1, |s| { s.B32(1) - // first entry - .B64(1234) // duration - .B64(0xffff_ffff_ffff_ffff) // time - .B16(12) // rate integer - .B16(34) // rate fraction + // first entry + .B64(1234) // duration + .B64(0xffff_ffff_ffff_ffff) // time + .B16(12) // rate integer + .B16(34) // rate fraction }) } @@ -861,22 +849,22 @@ fn skip_padding_in_boxes() { match name { b"stts" => { super::read_stts(&mut stream).expect("fail to skip padding: stts"); - }, + } b"stsc" => { super::read_stsc(&mut stream).expect("fail to skip padding: stsc"); - }, + } b"stsz" => { super::read_stsz(&mut stream).expect("fail to skip padding: stsz"); - }, + } b"stco" => { super::read_stco(&mut stream).expect("fail to skip padding: stco"); - }, + } b"co64" => { super::read_co64(&mut stream).expect("fail to skip padding: co64"); - }, + } b"stss" => { super::read_stss(&mut stream).expect("fail to skip padding: stss"); - }, + } _ => (), } } @@ -888,86 +876,84 @@ fn skip_padding_in_stsd() { // them instead of returning error. let avc = make_box(BoxSize::Auto, b"avc1", |s| { s.append_repeated(0, 6) - .B16(1) - .append_repeated(0, 16) - .B16(320) - .B16(240) - .append_repeated(0, 14) - .append_repeated(0, 32) - .append_repeated(0, 4) - .B32(0xffff_ffff) - .append_bytes(b"avcC") - .append_repeated(0, 100) - }).into_inner(); + .B16(1) + .append_repeated(0, 16) + .B16(320) + .B16(240) + .append_repeated(0, 14) + .append_repeated(0, 32) + .append_repeated(0, 4) + .B32(0xffff_ffff) + .append_bytes(b"avcC") + .append_repeated(0, 100) + }) + .into_inner(); let mut stream = make_fullbox(BoxSize::Auto, b"stsd", 0, |s| { s.B32(1) - .append_bytes(avc.as_slice()) - .append_repeated(0, 100) // add padding data + .append_bytes(avc.as_slice()) + .append_repeated(0, 100) // add padding data }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); - super::read_stsd(&mut stream, &mut super::Track::new(0)) - .expect("fail to skip padding: stsd"); + super::read_stsd(&mut stream, &mut super::Track::new(0)).expect("fail to skip padding: stsd"); } #[test] fn read_qt_wave_atom() { let esds = make_fullbox(BoxSize::Auto, b"esds", 0, |s| { - s.B8(0x03) // elementary stream descriptor tag - .B8(0x12) // esds length - .append_repeated(0, 2) - .B8(0x00) // flags - .B8(0x04) // decoder config descriptor tag - .B8(0x0d) // dcds length - .B8(0x6b) // mp3 - .append_repeated(0, 12) - }).into_inner(); + s.B8(0x03) // elementary stream descriptor tag + .B8(0x12) // esds length + .append_repeated(0, 2) + .B8(0x00) // flags + .B8(0x04) // decoder config descriptor tag + .B8(0x0d) // dcds length + .B8(0x6b) // mp3 + .append_repeated(0, 12) + }) + .into_inner(); let chan = make_box(BoxSize::Auto, b"chan", |s| { - s.append_repeated(0, 10) // we don't care its data. - }).into_inner(); - let wave = make_box(BoxSize::Auto, b"wave", |s| { - s.append_bytes(esds.as_slice()) - }).into_inner(); + s.append_repeated(0, 10) // we don't care its data. + }) + .into_inner(); + let wave = make_box(BoxSize::Auto, b"wave", |s| s.append_bytes(esds.as_slice())).into_inner(); let mut stream = make_box(BoxSize::Auto, b"mp4a", |s| { s.append_repeated(0, 6) - .B16(1) // data_reference_count - .B16(1) // verion: qt -> 1 - .append_repeated(0, 6) - .B16(2) - .B16(16) - .append_repeated(0, 4) - .B32(48000 << 16) - .append_repeated(0, 16) - .append_bytes(wave.as_slice()) - .append_bytes(chan.as_slice()) + .B16(1) // data_reference_count + .B16(1) // verion: qt -> 1 + .append_repeated(0, 6) + .B16(2) + .B16(16) + .append_repeated(0, 4) + .B32(48000 << 16) + .append_repeated(0, 16) + .append_bytes(wave.as_slice()) + .append_bytes(chan.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); - let sample_entry = super::read_audio_sample_entry(&mut stream) - .expect("fail to read qt wave atom"); + let sample_entry = + super::read_audio_sample_entry(&mut stream).expect("fail to read qt wave atom"); match sample_entry { - super::SampleEntry::Audio(sample_entry) => - assert_eq!(sample_entry.codec_type, super::CodecType::MP3), + super::SampleEntry::Audio(sample_entry) => { + assert_eq!(sample_entry.codec_type, super::CodecType::MP3) + } _ => panic!("fail to read audio sample enctry"), } } #[test] fn read_descriptor_80() { - let aac_esds = - vec![ - 0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, - 0x04, 0x80, 0x80, 0x80, 0x17, 0x40, 0x15, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x22, 0xBC, 0x00, 0x01, - 0xF5, 0x83, 0x05, 0x80, 0x80, 0x80, 0x02, 0x11, - 0x90, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02 - ]; - let aac_dc_descriptor = &aac_esds[31 .. 33]; + let aac_esds = vec![ + 0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, 0x04, 0x80, 0x80, 0x80, 0x17, 0x40, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x22, 0xBC, 0x00, 0x01, 0xF5, 0x83, 0x05, 0x80, 0x80, 0x80, + 0x02, 0x11, 0x90, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02, + ]; + let aac_dc_descriptor = &aac_esds[31..33]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(aac_esds.as_slice()) + .append_bytes(aac_esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -985,19 +971,16 @@ fn read_descriptor_80() { #[test] fn read_esds() { - let aac_esds = - vec![ - 0x03, 0x24, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x40, - 0x15, 0x00, 0x12, 0x00, 0x00, 0x01, 0xf4, 0x00, - 0x00, 0x01, 0xf4, 0x00, 0x05, 0x0d, 0x13, 0x00, - 0x05, 0x88, 0x05, 0x00, 0x48, 0x21, 0x10, 0x00, - 0x56, 0xe5, 0x98, 0x06, 0x01, 0x02, - ]; - let aac_dc_descriptor = &aac_esds[22 .. 35]; + let aac_esds = vec![ + 0x03, 0x24, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x40, 0x15, 0x00, 0x12, 0x00, 0x00, 0x01, 0xf4, + 0x00, 0x00, 0x01, 0xf4, 0x00, 0x05, 0x0d, 0x13, 0x00, 0x05, 0x88, 0x05, 0x00, 0x48, 0x21, + 0x10, 0x00, 0x56, 0xe5, 0x98, 0x06, 0x01, 0x02, + ]; + let aac_dc_descriptor = &aac_esds[22..35]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(aac_esds.as_slice()) + .append_bytes(aac_esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1015,22 +998,18 @@ fn read_esds() { #[test] fn read_esds_aac_type5() { - let aac_esds = - vec![ - 0x03, 0x80, 0x80, 0x80, - 0x2F, 0x00, 0x00, 0x00, 0x04, 0x80, 0x80, 0x80, - 0x21, 0x40, 0x15, 0x00, 0x15, 0x00, 0x00, 0x03, - 0xED, 0xAA, 0x00, 0x03, 0x6B, 0x00, 0x05, 0x80, - 0x80, 0x80, 0x0F, 0x2B, 0x01, 0x88, 0x02, 0xC4, - 0x04, 0x90, 0x2C, 0x10, 0x8C, 0x80, 0x00, 0x00, - 0xED, 0x40, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02, - ]; + let aac_esds = vec![ + 0x03, 0x80, 0x80, 0x80, 0x2F, 0x00, 0x00, 0x00, 0x04, 0x80, 0x80, 0x80, 0x21, 0x40, 0x15, + 0x00, 0x15, 0x00, 0x00, 0x03, 0xED, 0xAA, 0x00, 0x03, 0x6B, 0x00, 0x05, 0x80, 0x80, 0x80, + 0x0F, 0x2B, 0x01, 0x88, 0x02, 0xC4, 0x04, 0x90, 0x2C, 0x10, 0x8C, 0x80, 0x00, 0x00, 0xED, + 0x40, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02, + ]; - let aac_dc_descriptor = &aac_esds[31 .. 46]; + let aac_dc_descriptor = &aac_esds[31..46]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(aac_esds.as_slice()) + .append_bytes(aac_esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1048,30 +1027,24 @@ fn read_esds_aac_type5() { #[test] fn read_stsd_mp4v() { - let mp4v = - vec![ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd0, 0x01, 0xe0, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x18, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x4c, 0x65, 0x73, 0x64, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x3e, 0x00, 0x00, 0x1f, 0x04, 0x36, 0x20, 0x11, 0x01, 0x77, 0x00, - 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x05, 0x27, 0x00, 0x00, - 0x01, 0xb0, 0x05, 0x00, 0x00, 0x01, 0xb5, 0x0e, 0xcf, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x86, 0xe0, 0x00, 0x2e, 0xa6, 0x60, - 0x16, 0xf4, 0x01, 0xf4, 0x24, 0xc8, 0x01, 0xe5, 0x16, 0x84, 0x3c, 0x14, - 0x63, 0x06, 0x01, 0x02, - ]; - - let esds_specific_data = &mp4v[90 ..]; + let mp4v = vec![ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd0, 0x01, 0xe0, 0x00, 0x48, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x4c, 0x65, 0x73, 0x64, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x3e, 0x00, 0x00, 0x1f, 0x04, 0x36, 0x20, 0x11, 0x01, 0x77, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x00, 0x03, 0xe8, 0x00, 0x05, 0x27, 0x00, 0x00, 0x01, 0xb0, 0x05, 0x00, 0x00, 0x01, + 0xb5, 0x0e, 0xcf, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x86, 0xe0, 0x00, + 0x2e, 0xa6, 0x60, 0x16, 0xf4, 0x01, 0xf4, 0x24, 0xc8, 0x01, 0xe5, 0x16, 0x84, 0x3c, 0x14, + 0x63, 0x06, 0x01, 0x02, + ]; + + let esds_specific_data = &mp4v[90..]; println!("esds_specific_data {:?}", esds_specific_data); - let mut stream = make_box(BoxSize::Auto, b"mp4v", |s| { - s.append_bytes(mp4v.as_slice()) - }); + let mut stream = make_box(BoxSize::Auto, b"mp4v", |s| s.append_bytes(mp4v.as_slice())); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1085,28 +1058,25 @@ fn read_stsd_mp4v() { match v.codec_specific { super::VideoCodecSpecific::ESDSConfig(esds_data) => { assert_eq!(esds_data, esds_specific_data.to_vec()); - }, + } _ => panic!("it should be ESDSConfig!"), } - }, + } _ => panic!("it should be a video sample entry!"), } - } #[test] fn read_esds_one_byte_extension_descriptor() { - let esds = - vec![ - 0x00, 0x03, 0x80, 0x1b, 0x00, 0x00, 0x00, 0x04, - 0x80, 0x12, 0x40, 0x15, 0x00, 0x06, 0x00, 0x00, - 0x01, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x80, 0x02, 0x11, 0x90, 0x06, 0x01, 0x02, - ]; + let esds = vec![ + 0x00, 0x03, 0x80, 0x1b, 0x00, 0x00, 0x00, 0x04, 0x80, 0x12, 0x40, 0x15, 0x00, 0x06, 0x00, + 0x00, 0x01, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x02, 0x11, 0x90, 0x06, 0x01, + 0x02, + ]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(esds.as_slice()) + .append_bytes(esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1124,9 +1094,9 @@ fn read_esds_one_byte_extension_descriptor() { fn read_esds_byte_extension_descriptor() { let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .B16(0x0003) - .B16(0x8181) // extension byte length 0x81 - .append_repeated(0, 0x81) + .B16(0x0003) + .B16(0x8181) // extension byte length 0x81 + .append_repeated(0, 0x81) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1141,22 +1111,23 @@ fn read_esds_byte_extension_descriptor() { fn read_f4v_stsd() { let mut stream = make_box(BoxSize::Auto, b".mp3", |s| { s.append_repeated(0, 6) - .B16(1) - .B16(0) - .append_repeated(0, 6) - .B16(2) - .B16(16) - .append_repeated(0, 4) - .B32(48000 << 16) + .B16(1) + .B16(0) + .append_repeated(0, 6) + .B16(2) + .B16(16) + .append_repeated(0, 4) + .B32(48000 << 16) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); - let sample_entry = super::read_audio_sample_entry(&mut stream) - .expect("failed to read f4v stsd atom"); + let sample_entry = + super::read_audio_sample_entry(&mut stream).expect("failed to read f4v stsd atom"); match sample_entry { - super::SampleEntry::Audio(sample_entry) => - assert_eq!(sample_entry.codec_type, super::CodecType::MP3), + super::SampleEntry::Audio(sample_entry) => { + assert_eq!(sample_entry.codec_type, super::CodecType::MP3) + } _ => panic!("fail to read audio sample enctry"), } } @@ -1165,10 +1136,9 @@ fn read_f4v_stsd() { fn max_table_limit() { let elst = make_fullbox(BoxSize::Auto, b"elst", 1, |s| { s.B32(super::TABLE_SIZE_LIMIT + 1) - }).into_inner(); - let mut stream = make_box(BoxSize::Auto, b"edts", |s| { - s.append_bytes(elst.as_slice()) - }); + }) + .into_inner(); + let mut stream = make_box(BoxSize::Auto, b"edts", |s| s.append_bytes(elst.as_slice())); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); let mut track = super::Track::new(0); @@ -1181,19 +1151,17 @@ fn max_table_limit() { #[test] fn unknown_video_sample_entry() { - let unknown_codec = make_box(BoxSize::Auto, b"yyyy", |s| { - s.append_repeated(0, 16) - }).into_inner(); + let unknown_codec = make_box(BoxSize::Auto, b"yyyy", |s| s.append_repeated(0, 16)).into_inner(); let mut stream = make_box(BoxSize::Auto, b"xxxx", |s| { s.append_repeated(0, 6) - .B16(1) - .append_repeated(0, 16) - .B16(0) - .B16(0) - .append_repeated(0, 14) - .append_repeated(0, 32) - .append_repeated(0, 4) - .append_bytes(unknown_codec.as_slice()) + .B16(1) + .append_repeated(0, 16) + .B16(0) + .B16(0) + .append_repeated(0, 14) + .append_repeated(0, 32) + .append_repeated(0, 4) + .append_bytes(unknown_codec.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1205,20 +1173,18 @@ fn unknown_video_sample_entry() { #[test] fn unknown_audio_sample_entry() { - let unknown_codec = make_box(BoxSize::Auto, b"yyyy", |s| { - s.append_repeated(0, 16) - }).into_inner(); + let unknown_codec = make_box(BoxSize::Auto, b"yyyy", |s| s.append_repeated(0, 16)).into_inner(); let mut stream = make_box(BoxSize::Auto, b"xxxx", |s| { s.append_repeated(0, 6) - .B16(1) - .B32(0) - .B32(0) - .B16(2) - .B16(16) - .B16(0) - .B16(0) - .B32(48000 << 16) - .append_bytes(unknown_codec.as_slice()) + .B16(1) + .B32(0) + .B32(0) + .B16(2) + .B16(16) + .B16(0) + .B16(0) + .B32(48000 << 16) + .append_bytes(unknown_codec.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1231,18 +1197,15 @@ fn unknown_audio_sample_entry() { #[test] fn read_esds_invalid_descriptor() { // tag 0x06, 0xff, 0x7f is incorrect. - let esds = - vec![ - 0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x00, - 0x00, 0x04, 0x80, 0x80, 0x80, 0x14, 0x40, 0x01, - 0x00, 0x04, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, - 0x00, 0xfa, 0x00, 0x05, 0x80, 0x80, 0x80, 0x02, - 0xe8, 0x35, 0x06, 0xff, 0x7f, 0x00, 0x00, - ]; + let esds = vec![ + 0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x00, 0x00, 0x04, 0x80, 0x80, 0x80, 0x14, 0x40, 0x01, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x80, 0x80, 0x80, + 0x02, 0xe8, 0x35, 0x06, 0xff, 0x7f, 0x00, 0x00, + ]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(esds.as_slice()) + .append_bytes(esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1256,16 +1219,13 @@ fn read_esds_invalid_descriptor() { #[test] fn read_esds_redundant_descriptor() { // the '2' at the end is redundant data. - let esds = - vec![ 3, 25, 0, 1, 0, 4, 19, 64, - 21, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 119, 0, 5, 2, 18, 16, - 6, 1, 2, - ]; + let esds = vec![ + 3, 25, 0, 1, 0, 4, 19, 64, 21, 0, 0, 0, 0, 0, 0, 0, 0, 1, 119, 0, 5, 2, 18, 16, 6, 1, 2, + ]; let mut stream = make_box(BoxSize::Auto, b"esds", |s| { s.B32(0) // reserved - .append_bytes(esds.as_slice()) + .append_bytes(esds.as_slice()) }); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1279,18 +1239,13 @@ fn read_esds_redundant_descriptor() { #[test] fn read_invalid_pssh() { // invalid pssh header length - let pssh = - vec![ - 0x00, 0x00, 0x00, 0x01, 0x70, - 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, - 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, - 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, - 0x00, 0x00, 0x02, 0x7e, 0x57, 0x1d, 0x01, 0x7e, - ]; - - let mut stream = make_box(BoxSize::Auto, b"moov", |s| { - s.append_bytes(pssh.as_slice()) - }); + let pssh = vec![ + 0x00, 0x00, 0x00, 0x01, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, + 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, + 0x00, 0x02, 0x7e, 0x57, 0x1d, 0x01, 0x7e, + ]; + + let mut stream = make_box(BoxSize::Auto, b"moov", |s| s.append_bytes(pssh.as_slice())); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); let mut context = super::MediaContext::new(); @@ -1305,25 +1260,16 @@ fn read_invalid_pssh() { fn read_stsd_lpcm() { // Extract from sample converted by ffmpeg. // "ffmpeg -i ./gizmo-short.mp4 -acodec pcm_s16le -ar 96000 -vcodec copy -f mov gizmo-short.mov" - let lpcm = - vec![ - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0xff, - 0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x48, 0x40, 0xf7, 0x70, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x63, - 0x68, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - ]; - - let mut stream = make_box(BoxSize::Auto, b"lpcm", |s| { - s.append_bytes(lpcm.as_slice()) - }); + let lpcm = vec![ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x10, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x40, 0xf7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x63, 0x68, 0x61, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let mut stream = make_box(BoxSize::Auto, b"lpcm", |s| s.append_bytes(lpcm.as_slice())); let mut iter = super::BoxIter::new(&mut stream); let mut stream = iter.next_box().unwrap().unwrap(); @@ -1339,10 +1285,9 @@ fn read_stsd_lpcm() { super::AudioCodecSpecific::LPCM => (), _ => panic!("it should be LPCM!"), } - }, + } _ => panic!("it should be a audio sample entry!"), } - } #[test] diff --git a/mp4parse/tests/public.rs b/mp4parse/tests/public.rs index 1bf97e9d..3cfc52e6 100644 --- a/mp4parse/tests/public.rs +++ b/mp4parse/tests/public.rs @@ -1,13 +1,11 @@ /// Check if needed fields are still public. - // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. - extern crate mp4parse as mp4; -use std::io::{Cursor, Read}; use std::fs::File; +use std::io::{Cursor, Read}; use std::path::Path; static MINI_MP4: &str = "tests/minimal.mp4"; @@ -69,27 +67,30 @@ fn public_api() { }; assert_eq!(v.width, 320); assert_eq!(v.height, 240); - assert_eq!(match v.codec_specific { - mp4::VideoCodecSpecific::AVCConfig(ref avc) => { - assert!(!avc.is_empty()); - "AVC" - } - mp4::VideoCodecSpecific::VPxConfig(ref vpx) => { - // We don't enter in here, we just check if fields are public. - assert!(vpx.bit_depth > 0); - assert!(vpx.colour_primaries > 0); - assert!(vpx.chroma_subsampling > 0); - assert!(!vpx.codec_init.is_empty()); - "VPx" - } - mp4::VideoCodecSpecific::ESDSConfig(ref mp4v) => { - assert!(!mp4v.is_empty()); - "MP4V" - } - mp4::VideoCodecSpecific::AV1Config(ref _av1c) => { - "AV1" - } - }, "AVC"); + assert_eq!( + match v.codec_specific { + mp4::VideoCodecSpecific::AVCConfig(ref avc) => { + assert!(!avc.is_empty()); + "AVC" + } + mp4::VideoCodecSpecific::VPxConfig(ref vpx) => { + // We don't enter in here, we just check if fields are public. + assert!(vpx.bit_depth > 0); + assert!(vpx.colour_primaries > 0); + assert!(vpx.chroma_subsampling > 0); + assert!(!vpx.codec_init.is_empty()); + "VPx" + } + mp4::VideoCodecSpecific::ESDSConfig(ref mp4v) => { + assert!(!mp4v.is_empty()); + "MP4V" + } + mp4::VideoCodecSpecific::AV1Config(ref _av1c) => { + "AV1" + } + }, + "AVC" + ); } mp4::TrackType::Audio => { // track part @@ -111,36 +112,39 @@ fn public_api() { mp4::SampleEntry::Audio(a) => a, _ => panic!("expected a AudioSampleEntry"), }; - assert_eq!(match a.codec_specific { - mp4::AudioCodecSpecific::ES_Descriptor(ref esds) => { - assert_eq!(esds.audio_codec, mp4::CodecType::AAC); - assert_eq!(esds.audio_sample_rate.unwrap(), 48000); - assert_eq!(esds.audio_object_type.unwrap(), 2); - "ES" - } - mp4::AudioCodecSpecific::FLACSpecificBox(ref flac) => { - // STREAMINFO block must be present and first. - assert!(!flac.blocks.is_empty()); - assert_eq!(flac.blocks[0].block_type, 0); - assert_eq!(flac.blocks[0].data.len(), 34); - "FLAC" - } - mp4::AudioCodecSpecific::OpusSpecificBox(ref opus) => { - // We don't enter in here, we just check if fields are public. - assert!(opus.version > 0); - "Opus" - } - mp4::AudioCodecSpecific::ALACSpecificBox(ref alac) => { - assert!(alac.data.len() == 24 || alac.data.len() == 48); - "ALAC" - } - mp4::AudioCodecSpecific::MP3 => { - "MP3" - } - mp4::AudioCodecSpecific::LPCM => { - "LPCM" - } - }, "ES"); + assert_eq!( + match a.codec_specific { + mp4::AudioCodecSpecific::ES_Descriptor(ref esds) => { + assert_eq!(esds.audio_codec, mp4::CodecType::AAC); + assert_eq!(esds.audio_sample_rate.unwrap(), 48000); + assert_eq!(esds.audio_object_type.unwrap(), 2); + "ES" + } + mp4::AudioCodecSpecific::FLACSpecificBox(ref flac) => { + // STREAMINFO block must be present and first. + assert!(!flac.blocks.is_empty()); + assert_eq!(flac.blocks[0].block_type, 0); + assert_eq!(flac.blocks[0].data.len(), 34); + "FLAC" + } + mp4::AudioCodecSpecific::OpusSpecificBox(ref opus) => { + // We don't enter in here, we just check if fields are public. + assert!(opus.version > 0); + "Opus" + } + mp4::AudioCodecSpecific::ALACSpecificBox(ref alac) => { + assert!(alac.data.len() == 24 || alac.data.len() == 48); + "ALAC" + } + mp4::AudioCodecSpecific::MP3 => { + "MP3" + } + mp4::AudioCodecSpecific::LPCM => { + "LPCM" + } + }, + "ES" + ); assert!(a.samplesize > 0); assert!(a.samplerate > 0.0); } @@ -159,7 +163,9 @@ fn public_metadata() { let mut c = Cursor::new(&buf); let mut context = mp4::MediaContext::new(); mp4::read_mp4(&mut c, &mut context).expect("read_mp4 failed"); - let udta = context.userdata.expect("didn't find udta") + let udta = context + .userdata + .expect("didn't find udta") .expect("failed to parse udta"); let meta = udta.meta.expect("didn't find meta"); assert_eq!(meta.title.unwrap(), "Title"); @@ -167,7 +173,10 @@ fn public_metadata() { assert_eq!(meta.album_artist.unwrap(), "Album Artist"); assert_eq!(meta.comment.unwrap(), "Comments"); assert_eq!(meta.year.unwrap(), "2019"); - assert_eq!(meta.genre.unwrap(), mp4::Genre::CustomGenre("Custom Genre".to_string())); + assert_eq!( + meta.genre.unwrap(), + mp4::Genre::CustomGenre("Custom Genre".to_string()) + ); assert_eq!(meta.encoder.unwrap(), "Lavf56.40.101"); assert_eq!(meta.encoded_by.unwrap(), "Encoded-by"); assert_eq!(meta.copyright.unwrap(), "Copyright"); @@ -222,7 +231,9 @@ fn public_metadata_gnre() { let mut c = Cursor::new(&buf); let mut context = mp4::MediaContext::new(); mp4::read_mp4(&mut c, &mut context).expect("read_mp4 failed"); - let udta = context.userdata.expect("didn't find udta") + let udta = context + .userdata + .expect("didn't find udta") .expect("failed to parse udta"); let meta = udta.meta.expect("didn't find meta"); assert_eq!(meta.title.unwrap(), "Title"); @@ -277,9 +288,10 @@ fn public_metadata_gnre() { #[test] fn public_audio_tenc() { - let kid = - vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04]; + let kid = vec![ + 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, + 0x04, + ]; let mut fd = File::open(AUDIO_EME_CENC_MP4).expect("Unknown file"); let mut buf = Vec::new(); @@ -313,32 +325,32 @@ fn public_audio_tenc() { } else { panic!("Invalid test condition"); } - }, - _=> { + } + _ => { panic!("Invalid test condition"); - }, + } } } } #[test] fn public_video_cenc() { - let system_id = - vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, - 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b]; - - let kid = - vec![0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, - 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x11]; - - let pssh_box = - vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec, - 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, - 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01, - 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, - 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x11, - 0x00, 0x00, 0x00, 0x00]; + let system_id = vec![ + 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, + 0x4b, + ]; + + let kid = vec![ + 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, + 0x11, + ]; + + let pssh_box = vec![ + 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, + 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, + 0x00, 0x01, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, + 0x57, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + ]; let mut fd = File::open(VIDEO_EME_CENC_MP4).expect("Unknown file"); let mut buf = Vec::new(); @@ -372,8 +384,8 @@ fn public_video_cenc() { } else { panic!("Invalid test condition"); } - }, - _=> { + } + _ => { panic!("Invalid test condition"); } } @@ -391,26 +403,27 @@ fn public_video_cenc() { #[test] fn publicaudio_cbcs() { - let system_id = - vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, - 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b]; - - let kid = - vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21]; - - let default_iv = - vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66]; - - let pssh_box = - vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec, - 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, - 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21, - 0x00, 0x00, 0x00, 0x00]; + let system_id = vec![ + 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, + 0x4b, + ]; + + let kid = vec![ + 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, + 0x21, + ]; + + let default_iv = vec![ + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, + ]; + + let pssh_box = vec![ + 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, + 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, + 0x00, 0x01, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, + 0x57, 0x1d, 0x21, 0x00, 0x00, 0x00, 0x00, + ]; let mut fd = File::open(AUDIO_EME_CBCS_MP4).expect("Unknown file"); let mut buf = Vec::new(); @@ -448,14 +461,16 @@ fn publicaudio_cbcs() { panic!("Invalid test condition"); } } - }, + } _ => { panic!("expected a VideoSampleEntry"); - }, + } } } - assert!(found_encrypted_sample_description, - "Should have found an encrypted sample description"); + assert!( + found_encrypted_sample_description, + "Should have found an encrypted sample description" + ); } for pssh in context.psshs { @@ -471,26 +486,27 @@ fn publicaudio_cbcs() { #[test] #[allow(clippy::cognitive_complexity)] // TODO: Consider simplifying this fn public_video_cbcs() { - let system_id = - vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, - 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b]; - - let kid = - vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21]; - - let default_iv = - vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66]; - - let pssh_box = - vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec, - 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, - 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21, - 0x00, 0x00, 0x00, 0x00]; + let system_id = vec![ + 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, + 0x4b, + ]; + + let kid = vec![ + 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, + 0x21, + ]; + + let default_iv = vec![ + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, + ]; + + let pssh_box = vec![ + 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, + 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, + 0x00, 0x01, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, + 0x57, 0x1d, 0x21, 0x00, 0x00, 0x00, 0x00, + ]; let mut fd = File::open(VIDEO_EME_CBCS_MP4).expect("Unknown file"); let mut buf = Vec::new(); @@ -527,14 +543,16 @@ fn public_video_cbcs() { panic!("Invalid test condition"); } } - }, + } _ => { panic!("expected a VideoSampleEntry"); - }, + } } } - assert!(found_encrypted_sample_description, - "Should have found an encrypted sample description"); + assert!( + found_encrypted_sample_description, + "Should have found an encrypted sample description" + ); } for pssh in context.psshs { @@ -561,7 +579,7 @@ fn public_video_av1() { // track part assert_eq!(track.duration, Some(mp4::TrackScaledTime(512, 0))); assert_eq!(track.empty_duration, Some(mp4::MediaScaledTime(0))); - assert_eq!(track.media_time, Some(mp4::TrackScaledTime(0,0))); + assert_eq!(track.media_time, Some(mp4::TrackScaledTime(0, 0))); assert_eq!(track.timescale, Some(mp4::TrackTimeScale(12288, 0))); // track.tkhd part @@ -594,7 +612,7 @@ fn public_video_av1() { assert_eq!(av1c.chroma_sample_position, 0); assert_eq!(av1c.initial_presentation_delay_present, false); assert_eq!(av1c.initial_presentation_delay_minus_one, 0); - }, + } _ => panic!("Invalid test condition"), } } @@ -621,8 +639,12 @@ fn public_avif_primary_item_is_grid() { #[test] fn public_avif_read_samples() { env_logger::init(); - let microsoft = Path::new(MICROSOFT_AVIF_TEST_DIR).read_dir().expect("Cannot read AVIF test dir"); - let netflix = Path::new(NETFLIX_AVIF_TEST_DIR).read_dir().expect("Cannot read AVIF test dir"); + let microsoft = Path::new(MICROSOFT_AVIF_TEST_DIR) + .read_dir() + .expect("Cannot read AVIF test dir"); + let netflix = Path::new(NETFLIX_AVIF_TEST_DIR) + .read_dir() + .expect("Cannot read AVIF test dir"); for entry in microsoft.chain(netflix) { let path = entry.expect("AVIF entry").path(); if path.extension().expect("no extension") != "avif" { diff --git a/mp4parse_capi/build.rs b/mp4parse_capi/build.rs index e973b0ec..67bb32ca 100644 --- a/mp4parse_capi/build.rs +++ b/mp4parse_capi/build.rs @@ -9,7 +9,8 @@ fn main() { let config = { let mut c: Config = Default::default(); - c.header = Some(r##" + c.header = Some( + r##" // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. @@ -17,12 +18,19 @@ fn main() { #ifdef __cplusplus extern "C" { #endif -"##.trim().into()); - c.trailer = Some(r##" +"## + .trim() + .into(), + ); + c.trailer = Some( + r##" #ifdef __cplusplus } /* extern "C" */ #endif -"##.trim().into()); +"## + .trim() + .into(), + ); c.include_guard = Some("MP4PARSE_CAPI_H".to_owned()); c.autogen_warning = Some( "// THIS FILE IS AUTOGENERATED BY mp4parse_capi/build.rs - DO NOT EDIT".to_owned(), diff --git a/mp4parse_capi/examples/dump.rs b/mp4parse_capi/examples/dump.rs index b1137063..bb17078a 100644 --- a/mp4parse_capi/examples/dump.rs +++ b/mp4parse_capi/examples/dump.rs @@ -6,12 +6,12 @@ extern crate log; extern crate env_logger; +use mp4parse_capi::*; use std::env; use std::fs::File; use std::io::Read; -use mp4parse_capi::*; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -24,7 +24,7 @@ fn dump_file(filename: &str) { let mut file = File::open(filename).expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -36,14 +36,14 @@ fn dump_file(filename: &str) { _ => { println!("-- fail to parse, '-v' for more info"); return; - }, + } } let mut frag_info = Mp4parseFragmentInfo::default(); match mp4parse_get_fragment_info(parser, &mut frag_info) { Mp4parseStatus::Ok => { println!("-- mp4parse_fragment_info {:?}", frag_info); - }, + } _ => { println!("-- mp4parse_fragment_info failed"); return; @@ -59,7 +59,7 @@ fn dump_file(filename: &str) { } } - for i in 0 .. counts { + for i in 0..counts { let mut track_info = Mp4parseTrackInfo { track_type: Mp4parseTrackType::Audio, track_id: 0, @@ -69,7 +69,7 @@ fn dump_file(filename: &str) { match mp4parse_get_track_info(parser, i, &mut track_info) { Mp4parseStatus::Ok => { println!("-- mp4parse_get_track_info {:?}", track_info); - }, + } _ => { println!("-- mp4parse_get_track_info failed, track id: {}", i); return; @@ -81,49 +81,59 @@ fn dump_file(filename: &str) { let mut audio_info = Mp4parseTrackAudioInfo::default(); match mp4parse_get_track_audio_info(parser, i, &mut audio_info) { Mp4parseStatus::Ok => { - println!("-- mp4parse_get_track_audio_info {:?}", audio_info); - for i in 0 .. audio_info.sample_info_count as isize { - let sample_info = audio_info.sample_info.offset(i); - println!(" -- mp4parse_get_track_audio_info sample_info[{:?}] {:?}", - i, *sample_info); - } - }, + println!("-- mp4parse_get_track_audio_info {:?}", audio_info); + for i in 0..audio_info.sample_info_count as isize { + let sample_info = audio_info.sample_info.offset(i); + println!( + " -- mp4parse_get_track_audio_info sample_info[{:?}] {:?}", + i, *sample_info + ); + } + } _ => { - println!("-- mp4parse_get_track_audio_info failed, track id: {}", i); - return; + println!("-- mp4parse_get_track_audio_info failed, track id: {}", i); + return; } } - }, + } Mp4parseTrackType::Video => { let mut video_info = Mp4parseTrackVideoInfo::default(); match mp4parse_get_track_video_info(parser, i, &mut video_info) { Mp4parseStatus::Ok => { - println!("-- mp4parse_get_track_video_info {:?}", video_info); - for i in 0 .. video_info.sample_info_count as isize { - let sample_info = video_info.sample_info.offset(i); - println!(" -- mp4parse_get_track_video_info sample_info[{:?}] {:?}", - i, *sample_info); - } - }, + println!("-- mp4parse_get_track_video_info {:?}", video_info); + for i in 0..video_info.sample_info_count as isize { + let sample_info = video_info.sample_info.offset(i); + println!( + " -- mp4parse_get_track_video_info sample_info[{:?}] {:?}", + i, *sample_info + ); + } + } _ => { - println!("-- mp4parse_get_track_video_info failed, track id: {}", i); - return; + println!("-- mp4parse_get_track_video_info failed, track id: {}", i); + return; } } - }, + } Mp4parseTrackType::Metadata => { println!("TODO metadata track"); - }, + } } let mut indices = Mp4parseByteData::default(); match mp4parse_get_indice_table(parser, track_info.track_id, &mut indices) { Mp4parseStatus::Ok => { - println!("-- mp4parse_get_indice_table track_id {} indices {:?}", track_info.track_id, indices); - }, + println!( + "-- mp4parse_get_indice_table track_id {} indices {:?}", + track_info.track_id, indices + ); + } _ => { - println!("-- mp4parse_get_indice_table failed, track_info.track_id: {}", track_info.track_id); - return; + println!( + "-- mp4parse_get_indice_table failed, track_info.track_id: {}", + track_info.track_id + ); + return; } } } diff --git a/mp4parse_capi/src/lib.rs b/mp4parse_capi/src/lib.rs index a49b7d8f..dc1ff8a4 100644 --- a/mp4parse_capi/src/lib.rs +++ b/mp4parse_capi/src/lib.rs @@ -35,34 +35,34 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -extern crate mp4parse; extern crate byteorder; +extern crate mp4parse; extern crate num_traits; -use std::io::Read; -use std::collections::HashMap; use byteorder::WriteBytesExt; use num_traits::{PrimInt, Zero}; +use std::collections::HashMap; +use std::io::Read; // Symbols we need from our rust api. -use mp4parse::MediaContext; -use mp4parse::AvifContext; -use mp4parse::TrackType; -use mp4parse::read_mp4; +use mp4parse::extend_from_slice; use mp4parse::read_avif; -use mp4parse::Error; -use mp4parse::SampleEntry; -use mp4parse::AudioCodecSpecific; -use mp4parse::VideoCodecSpecific; -use mp4parse::MediaTimeScale; -use mp4parse::MediaScaledTime; -use mp4parse::TrackTimeScale; -use mp4parse::TrackScaledTime; +use mp4parse::read_mp4; use mp4parse::serialize_opus_header; +use mp4parse::vec_push; +use mp4parse::AudioCodecSpecific; +use mp4parse::AvifContext; use mp4parse::CodecType; +use mp4parse::Error; +use mp4parse::MediaContext; +use mp4parse::MediaScaledTime; +use mp4parse::MediaTimeScale; +use mp4parse::SampleEntry; use mp4parse::Track; -use mp4parse::vec_push; -use mp4parse::extend_from_slice; +use mp4parse::TrackScaledTime; +use mp4parse::TrackTimeScale; +use mp4parse::TrackType; +use mp4parse::VideoCodecSpecific; #[repr(C)] #[derive(PartialEq, Debug)] @@ -85,7 +85,9 @@ pub enum Mp4parseTrackType { } impl Default for Mp4parseTrackType { - fn default() -> Self { Mp4parseTrackType::Video } + fn default() -> Self { + Mp4parseTrackType::Video + } } #[allow(non_camel_case_types)] @@ -101,14 +103,16 @@ pub enum Mp4parseCodec { Av1, Mp3, Mp4v, - Jpeg, // for QT JPEG atom in video track + Jpeg, // for QT JPEG atom in video track Ac3, Ec3, Alac, } impl Default for Mp4parseCodec { - fn default() -> Self { Mp4parseCodec::Unknown } + fn default() -> Self { + Mp4parseCodec::Unknown + } } #[repr(C)] @@ -125,7 +129,9 @@ pub enum Mp4ParseEncryptionSchemeType { } impl Default for Mp4ParseEncryptionSchemeType { - fn default() -> Self { Mp4ParseEncryptionSchemeType::None } + fn default() -> Self { + Mp4ParseEncryptionSchemeType::None + } } #[repr(C)] @@ -135,7 +141,7 @@ pub struct Mp4parseTrackInfo { pub track_id: u32, pub duration: u64, pub media_time: i64, // wants to be u64? understand how elst adjustment works - // TODO(kinetik): include crypto guff + // TODO(kinetik): include crypto guff } #[repr(C)] @@ -303,7 +309,10 @@ pub struct Mp4parseParser { /// A unified interface for the parsers which have different contexts, but /// share the same pattern of construction. This allows unification of /// argument validation from C and minimizes the surface of unsafe code. -trait ContextParser where Self: Sized { +trait ContextParser +where + Self: Sized, +{ type Context: Default; fn with_context(context: Self::Context) -> Self; @@ -337,7 +346,10 @@ impl ContextParser for Mp4parseParser { type Context = MediaContext; fn with_context(context: Self::Context) -> Self { - Self { context, ..Default::default() } + Self { + context, + ..Default::default() + } } fn read(io: &mut T, context: &mut Self::Context) -> mp4parse::Result<()> { @@ -371,20 +383,28 @@ impl ContextParser for Mp4parseAvifParser { #[repr(C)] #[derive(Clone)] pub struct Mp4parseIo { - pub read: Option isize>, + pub read: Option< + extern "C" fn(buffer: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize, + >, pub userdata: *mut std::os::raw::c_void, } impl Read for Mp4parseIo { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { if buf.len() > isize::max_value() as usize { - return Err(std::io::Error::new(std::io::ErrorKind::Other, "buf length overflow in Mp4parseIo Read impl")); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "buf length overflow in Mp4parseIo Read impl", + )); } let rv = self.read.unwrap()(buf.as_mut_ptr(), buf.len(), self.userdata); if rv >= 0 { Ok(rv as usize) } else { - Err(std::io::Error::new(std::io::ErrorKind::Other, "I/O error in Mp4parseIo Read impl")) + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "I/O error in Mp4parseIo Read impl", + )) } } } @@ -414,7 +434,10 @@ impl Read for Mp4parseIo { /// paired with a call to `mp4parse_free`. In the event of error, no memory /// will be allocated and `mp4parse_free` must *not* be called. #[no_mangle] -pub unsafe extern fn mp4parse_new(io: *const Mp4parseIo, status_out: *mut Mp4parseStatus) -> *mut Mp4parseParser { +pub unsafe extern "C" fn mp4parse_new( + io: *const Mp4parseIo, + status_out: *mut Mp4parseStatus, +) -> *mut Mp4parseParser { mp4parse_new_common(io, status_out) } @@ -428,11 +451,17 @@ pub unsafe extern fn mp4parse_new(io: *const Mp4parseIo, status_out: *mut Mp4par /// /// Same as mp4parse_new. #[no_mangle] -pub unsafe extern fn mp4parse_avif_new(io: *const Mp4parseIo, status_out: *mut Mp4parseStatus) -> *mut Mp4parseAvifParser { +pub unsafe extern "C" fn mp4parse_avif_new( + io: *const Mp4parseIo, + status_out: *mut Mp4parseStatus, +) -> *mut Mp4parseAvifParser { mp4parse_new_common(io, status_out) } -unsafe fn mp4parse_new_common(io: *const Mp4parseIo, status_out: *mut Mp4parseStatus) -> *mut P { +unsafe fn mp4parse_new_common( + io: *const Mp4parseIo, + status_out: *mut Mp4parseStatus, +) -> *mut P { // Validate arguments from C. if io.is_null() || (*io).userdata.is_null() || (*io).read.is_none() || status_out.is_null() { set_if_non_null(status_out, Mp4parseStatus::BadArg); @@ -457,7 +486,9 @@ unsafe fn set_if_non_null(ptr: *mut T, val: T) { } } -fn mp4parse_new_common_safe(io: &mut T) -> Result<*mut P, Mp4parseStatus> { +fn mp4parse_new_common_safe( + io: &mut T, +) -> Result<*mut P, Mp4parseStatus> { let mut context = P::Context::default(); P::read(io, &mut context) @@ -470,9 +501,7 @@ fn mp4parse_new_common_safe(io: &mut T) -> Result<*mu impl From for Mp4parseStatus { fn from(error: mp4parse::Error) -> Self { match error { - Error::NoMoov | Error::InvalidData(_) => { - Mp4parseStatus::Invalid - } + Error::NoMoov | Error::InvalidData(_) => Mp4parseStatus::Invalid, Error::Unsupported(_) => Mp4parseStatus::Unsupported, Error::UnexpectedEOF => Mp4parseStatus::Eof, Error::Io(_) => { @@ -494,7 +523,7 @@ impl From for Mp4parseStatus { /// Callers should ensure that the parser pointer points to a valid /// `Mp4parseParser` created by `mp4parse_new`. #[no_mangle] -pub unsafe extern fn mp4parse_free(parser: *mut Mp4parseParser) { +pub unsafe extern "C" fn mp4parse_free(parser: *mut Mp4parseParser) { assert!(!parser.is_null()); let _ = Box::from_raw(parser); } @@ -507,7 +536,7 @@ pub unsafe extern fn mp4parse_free(parser: *mut Mp4parseParser) { /// Callers should ensure that the parser pointer points to a valid /// `Mp4parseAvifParser` created by `mp4parse_avif_new`. #[no_mangle] -pub unsafe extern fn mp4parse_avif_free(parser: *mut Mp4parseAvifParser) { +pub unsafe extern "C" fn mp4parse_avif_free(parser: *mut Mp4parseAvifParser) { assert!(!parser.is_null()); let _ = Box::from_raw(parser); } @@ -521,7 +550,10 @@ pub unsafe extern fn mp4parse_avif_free(parser: *mut Mp4parseAvifParser) { /// points to a valid `Mp4parseParser`, and that the count pointer points an /// appropriate memory location to have a `u32` written to. #[no_mangle] -pub unsafe extern fn mp4parse_get_track_count(parser: *const Mp4parseParser, count: *mut u32) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_track_count( + parser: *const Mp4parseParser, + count: *mut u32, +) -> Mp4parseStatus { // Validate arguments from C. if parser.is_null() || count.is_null() { return Mp4parseStatus::BadArg; @@ -545,19 +577,21 @@ pub unsafe extern fn mp4parse_get_track_count(parser: *const Mp4parseParser, cou /// /// Return None on overflow or if the denominator is zero. fn rational_scale(numerator: T, denominator: T, scale2: S) -> Option - where T: PrimInt + Zero, S: PrimInt { +where + T: PrimInt + Zero, + S: PrimInt, +{ if denominator.is_zero() { return None; } let integer = numerator / denominator; let remainder = numerator % denominator; - num_traits::cast(scale2).and_then(|s| { - match integer.checked_mul(&s) { - Some(integer) => remainder.checked_mul(&s) - .and_then(|remainder| (remainder/denominator).checked_add(&integer)), - None => None, - } + num_traits::cast(scale2).and_then(|s| match integer.checked_mul(&s) { + Some(integer) => remainder + .checked_mul(&s) + .and_then(|remainder| (remainder / denominator).checked_add(&integer)), + None => None, }) } @@ -567,7 +601,9 @@ fn media_time_to_us(time: MediaScaledTime, scale: MediaTimeScale) -> Option } fn track_time_to_us(time: TrackScaledTime, scale: TrackTimeScale) -> Option - where T: PrimInt + Zero { +where + T: PrimInt + Zero, +{ assert_eq!(time.1, scale.1); let microseconds_per_second = 1_000_000; rational_scale::(time.0, scale.0, microseconds_per_second) @@ -582,7 +618,11 @@ fn track_time_to_us(time: TrackScaledTime, scale: TrackTimeScale) -> Op /// valid `Mp4parseParser` and that the info pointer points to a valid /// `Mp4parseTrackInfo`. #[no_mangle] -pub unsafe extern fn mp4parse_get_track_info(parser: *mut Mp4parseParser, track_index: u32, info: *mut Mp4parseTrackInfo) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_track_info( + parser: *mut Mp4parseParser, + track_index: u32, + info: *mut Mp4parseTrackInfo, +) -> Mp4parseStatus { if parser.is_null() || info.is_null() { return Mp4parseStatus::BadArg; } @@ -607,21 +647,19 @@ pub unsafe extern fn mp4parse_get_track_info(parser: *mut Mp4parseParser, track_ let track = &context.tracks[track_index]; - if let (Some(track_timescale), - Some(context_timescale)) = (track.timescale, - context.timescale) { - let media_time = - match track.media_time.map_or(Some(0), |media_time| { - track_time_to_us(media_time, track_timescale) }) { - Some(time) => time as i64, - None => return Mp4parseStatus::Invalid, - }; - let empty_duration = - match track.empty_duration.map_or(Some(0), |empty_duration| { - media_time_to_us(empty_duration, context_timescale) }) { - Some(time) => time as i64, - None => return Mp4parseStatus::Invalid, - }; + if let (Some(track_timescale), Some(context_timescale)) = (track.timescale, context.timescale) { + let media_time = match track.media_time.map_or(Some(0), |media_time| { + track_time_to_us(media_time, track_timescale) + }) { + Some(time) => time as i64, + None => return Mp4parseStatus::Invalid, + }; + let empty_duration = match track.empty_duration.map_or(Some(0), |empty_duration| { + media_time_to_us(empty_duration, context_timescale) + }) { + Some(time) => time as i64, + None => return Mp4parseStatus::Invalid, + }; info.media_time = media_time - empty_duration; if let Some(track_duration) = track.duration { @@ -634,7 +672,7 @@ pub unsafe extern fn mp4parse_get_track_info(parser: *mut Mp4parseParser, track_ info.duration = 0 } } else { - return Mp4parseStatus::Invalid + return Mp4parseStatus::Invalid; } info.track_id = match track.track_id { @@ -654,7 +692,11 @@ pub unsafe extern fn mp4parse_get_track_info(parser: *mut Mp4parseParser, track_ /// valid `Mp4parseParser` and that the info pointer points to a valid /// `Mp4parseTrackAudioInfo`. #[no_mangle] -pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, track_index: u32, info: *mut Mp4parseTrackAudioInfo) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_track_audio_info( + parser: *mut Mp4parseParser, + track_index: u32, + info: *mut Mp4parseTrackAudioInfo, +) -> Mp4parseStatus { if parser.is_null() || info.is_null() { return Mp4parseStatus::BadArg; } @@ -684,7 +726,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, return Mp4parseStatus::Invalid; // Should have at least 1 description } - let mut audio_sample_infos = Vec:: with_capacity(stsd.descriptions.len()); + let mut audio_sample_infos = Vec::with_capacity(stsd.descriptions.len()); for description in stsd.descriptions.iter() { let mut sample_info = Mp4parseTrackAudioSampleInfo::default(); let audio = match description { @@ -694,20 +736,19 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, // UNKNOWN for unsupported format. sample_info.codec_type = match audio.codec_specific { - AudioCodecSpecific::OpusSpecificBox(_) => - Mp4parseCodec::Opus, - AudioCodecSpecific::FLACSpecificBox(_) => - Mp4parseCodec::Flac, - AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::AAC => - Mp4parseCodec::Aac, - AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::MP3 => - Mp4parseCodec::Mp3, - AudioCodecSpecific::ES_Descriptor(_) | AudioCodecSpecific::LPCM => - Mp4parseCodec::Unknown, - AudioCodecSpecific::MP3 => - Mp4parseCodec::Mp3, - AudioCodecSpecific::ALACSpecificBox(_) => - Mp4parseCodec::Alac, + AudioCodecSpecific::OpusSpecificBox(_) => Mp4parseCodec::Opus, + AudioCodecSpecific::FLACSpecificBox(_) => Mp4parseCodec::Flac, + AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::AAC => { + Mp4parseCodec::Aac + } + AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::MP3 => { + Mp4parseCodec::Mp3 + } + AudioCodecSpecific::ES_Descriptor(_) | AudioCodecSpecific::LPCM => { + Mp4parseCodec::Unknown + } + AudioCodecSpecific::MP3 => Mp4parseCodec::Mp3, + AudioCodecSpecific::ALACSpecificBox(_) => Mp4parseCodec::Alac, }; sample_info.channels = audio.channelcount as u16; sample_info.bit_depth = audio.samplesize; @@ -734,7 +775,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, } sample_info.extended_profile = match esds.extended_audio_object_type { Some(extended_profile) => extended_profile, - _ => sample_info.profile + _ => sample_info.profile, }; } AudioCodecSpecific::FLACSpecificBox(ref flac) => { @@ -772,7 +813,11 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, AudioCodecSpecific::MP3 | AudioCodecSpecific::LPCM => (), } - if let Some(p) = audio.protection_info.iter().find(|sinf| sinf.tenc.is_some()) { + if let Some(p) = audio + .protection_info + .iter() + .find(|sinf| sinf.tenc.is_some()) + { sample_info.protected_data.scheme_type = match p.scheme_type { Some(ref scheme_type_box) => { match scheme_type_box.scheme_type.value.as_ref() { @@ -783,7 +828,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, // no encryption case. _ => Mp4ParseEncryptionSchemeType::None, } - }, + } None => Mp4ParseEncryptionSchemeType::None, }; if let Some(ref tenc) = p.tenc { @@ -812,7 +857,9 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, } } - (*parser).audio_track_sample_descriptions.insert(track_index, audio_sample_infos); + (*parser) + .audio_track_sample_descriptions + .insert(track_index, audio_sample_infos); match (*parser).audio_track_sample_descriptions.get(&track_index) { Some(sample_info) => { if sample_info.len() > std::u32::MAX as usize { @@ -822,7 +869,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, } (*info).sample_info_count = sample_info.len() as u32; (*info).sample_info = sample_info.as_ptr(); - }, + } None => return Mp4parseStatus::Invalid, // Shouldn't happen, we just inserted the info! } @@ -838,7 +885,11 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser, /// valid `Mp4parseParser` and that the info pointer points to a valid /// `Mp4parseTrackVideoInfo`. #[no_mangle] -pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, track_index: u32, info: *mut Mp4parseTrackVideoInfo) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_track_video_info( + parser: *mut Mp4parseParser, + track_index: u32, + info: *mut Mp4parseTrackVideoInfo, +) -> Mp4parseStatus { if parser.is_null() || info.is_null() { return Mp4parseStatus::BadArg; } @@ -862,12 +913,16 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, if let Some(ref tkhd) = track.tkhd { (*info).display_width = tkhd.width >> 16; // 16.16 fixed point (*info).display_height = tkhd.height >> 16; // 16.16 fixed point - let matrix = (tkhd.matrix.a >> 16, tkhd.matrix.b >> 16, - tkhd.matrix.c >> 16, tkhd.matrix.d >> 16); + let matrix = ( + tkhd.matrix.a >> 16, + tkhd.matrix.b >> 16, + tkhd.matrix.c >> 16, + tkhd.matrix.d >> 16, + ); (*info).rotation = match matrix { - ( 0, 1, -1, 0) => 90, // rotate 90 degrees - (-1, 0, 0, -1) => 180, // rotate 180 degrees - ( 0, -1, 1, 0) => 270, // rotate 270 degrees + (0, 1, -1, 0) => 90, // rotate 90 degrees + (-1, 0, 0, -1) => 180, // rotate 180 degrees + (0, -1, 1, 0) => 270, // rotate 270 degrees _ => 0, }; } else { @@ -884,7 +939,7 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, return Mp4parseStatus::Invalid; // Should have at least 1 description } - let mut video_sample_infos = Vec:: with_capacity(stsd.descriptions.len()); + let mut video_sample_infos = Vec::with_capacity(stsd.descriptions.len()); for description in stsd.descriptions.iter() { let mut sample_info = Mp4parseTrackVideoSampleInfo::default(); let video = match description { @@ -894,14 +949,14 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, // UNKNOWN for unsupported format. sample_info.codec_type = match video.codec_specific { - VideoCodecSpecific::VPxConfig(_) => - Mp4parseCodec::Vp9, - VideoCodecSpecific::AV1Config(_) => - Mp4parseCodec::Av1, - VideoCodecSpecific::AVCConfig(_) => - Mp4parseCodec::Avc, - VideoCodecSpecific::ESDSConfig(_) => // MP4V (14496-2) video is unsupported. - Mp4parseCodec::Unknown, + VideoCodecSpecific::VPxConfig(_) => Mp4parseCodec::Vp9, + VideoCodecSpecific::AV1Config(_) => Mp4parseCodec::Av1, + VideoCodecSpecific::AVCConfig(_) => Mp4parseCodec::Avc, + VideoCodecSpecific::ESDSConfig(_) => + // MP4V (14496-2) video is unsupported. + { + Mp4parseCodec::Unknown + } }; sample_info.image_width = video.width; sample_info.image_height = video.height; @@ -909,11 +964,15 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, match video.codec_specific { VideoCodecSpecific::AVCConfig(ref data) | VideoCodecSpecific::ESDSConfig(ref data) => { sample_info.extra_data.set_data(data); - }, + } _ => {} } - if let Some(p) = video.protection_info.iter().find(|sinf| sinf.tenc.is_some()) { + if let Some(p) = video + .protection_info + .iter() + .find(|sinf| sinf.tenc.is_some()) + { sample_info.protected_data.scheme_type = match p.scheme_type { Some(ref scheme_type_box) => { match scheme_type_box.scheme_type.value.as_ref() { @@ -924,7 +983,7 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, // no encryption case. _ => Mp4ParseEncryptionSchemeType::None, } - }, + } None => Mp4ParseEncryptionSchemeType::None, }; if let Some(ref tenc) = p.tenc { @@ -953,7 +1012,9 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, } } - (*parser).video_track_sample_descriptions.insert(track_index, video_sample_infos); + (*parser) + .video_track_sample_descriptions + .insert(track_index, video_sample_infos); match (*parser).video_track_sample_descriptions.get(&track_index) { Some(sample_info) => { if sample_info.len() > std::u32::MAX as usize { @@ -963,7 +1024,7 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, } (*info).sample_info_count = sample_info.len() as u32; (*info).sample_info = sample_info.as_ptr(); - }, + } None => return Mp4parseStatus::Invalid, // Shouldn't happen, we just inserted the info! } Mp4parseStatus::Ok @@ -980,7 +1041,10 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser, /// successful call to `mp4parse_avif_read()`, no guarantees are made as to /// the state of `primary_item`. #[no_mangle] -pub unsafe extern fn mp4parse_avif_get_primary_item(parser: *mut Mp4parseAvifParser, primary_item: *mut Mp4parseByteData) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_avif_get_primary_item( + parser: *mut Mp4parseAvifParser, + primary_item: *mut Mp4parseByteData, +) -> Mp4parseStatus { if parser.is_null() { return Mp4parseStatus::BadArg; } @@ -1005,7 +1069,11 @@ pub unsafe extern fn mp4parse_avif_get_primary_item(parser: *mut Mp4parseAvifPar /// to a valid `Mp4parseParser` and that the indices pointer points to a valid /// `Mp4parseByteData`. #[no_mangle] -pub unsafe extern fn mp4parse_get_indice_table(parser: *mut Mp4parseParser, track_id: u32, indices: *mut Mp4parseByteData) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_indice_table( + parser: *mut Mp4parseParser, + track_id: u32, + indices: *mut Mp4parseByteData, +) -> Mp4parseStatus { if parser.is_null() { return Mp4parseStatus::BadArg; } @@ -1027,17 +1095,13 @@ pub unsafe extern fn mp4parse_get_indice_table(parser: *mut Mp4parseParser, trac } let media_time = match (&track.media_time, &track.timescale) { - (&Some(t), &Some(s)) => { - track_time_to_us(t, s).map(|v| v as i64) - }, + (&Some(t), &Some(s)) => track_time_to_us(t, s).map(|v| v as i64), _ => None, }; let empty_duration = match (&track.empty_duration, &context.timescale) { - (&Some(e), &Some(s)) => { - media_time_to_us(e, s).map(|v| v as i64) - }, - _ => None + (&Some(e), &Some(s)) => media_time_to_us(e, s).map(|v| v as i64), + _ => None, }; // Find the track start offset time from 'elst'. @@ -1075,32 +1139,31 @@ impl<'a> Iterator for TimeOffsetIterator<'a> { type Item = i64; fn next(&mut self) -> Option { - let has_sample = self.cur_sample_range.next() - .or_else(|| { - // At end of current TimeOffset, find the next TimeOffset. - let iter = match self.ctts_iter { - Some(ref mut v) => v, - _ => return None, - }; - let offset_version; - self.cur_sample_range = match iter.next() { - Some(v) => { - offset_version = v.time_offset; - 0 .. v.sample_count - }, - _ => { - offset_version = mp4parse::TimeOffsetVersion::Version0(0); - 0 .. 0 - }, - }; + let has_sample = self.cur_sample_range.next().or_else(|| { + // At end of current TimeOffset, find the next TimeOffset. + let iter = match self.ctts_iter { + Some(ref mut v) => v, + _ => return None, + }; + let offset_version; + self.cur_sample_range = match iter.next() { + Some(v) => { + offset_version = v.time_offset; + 0..v.sample_count + } + _ => { + offset_version = mp4parse::TimeOffsetVersion::Version0(0); + 0..0 + } + }; - self.cur_offset = match offset_version { - mp4parse::TimeOffsetVersion::Version0(i) => i64::from(i), - mp4parse::TimeOffsetVersion::Version1(i) => i64::from(i), - }; + self.cur_offset = match offset_version { + mp4parse::TimeOffsetVersion::Version0(i) => i64::from(i), + mp4parse::TimeOffsetVersion::Version1(i) => i64::from(i), + }; - self.cur_sample_range.next() - }); + self.cur_sample_range.next() + }); has_sample.and(Some(self.cur_offset)) } @@ -1132,18 +1195,17 @@ impl<'a> Iterator for TimeToSampleIterator<'a> { type Item = u32; fn next(&mut self) -> Option { - let has_sample = self.cur_sample_count.next() - .or_else(|| { - self.cur_sample_count = match self.stts_iter.next() { - Some(v) => { - self.cur_sample_delta = v.sample_delta; - 0 .. v.sample_count - }, - _ => 0 .. 0, - }; + let has_sample = self.cur_sample_count.next().or_else(|| { + self.cur_sample_count = match self.stts_iter.next() { + Some(v) => { + self.cur_sample_delta = v.sample_delta; + 0..v.sample_count + } + _ => 0..0, + }; - self.cur_sample_count.next() - }); + self.cur_sample_count.next() + }); has_sample.and(Some(self.cur_sample_delta)) } @@ -1180,16 +1242,17 @@ impl<'a> Iterator for SampleToChunkIterator<'a> { type Item = (u32, u32); fn next(&mut self) -> Option<(u32, u32)> { - let has_chunk = self.chunks.next() - .or_else(|| { - self.chunks = self.locate(); - self.remain_chunk_count.checked_sub(self.chunks.len() as u32).and_then(|res| { + let has_chunk = self.chunks.next().or_else(|| { + self.chunks = self.locate(); + self.remain_chunk_count + .checked_sub(self.chunks.len() as u32) + .and_then(|res| { self.remain_chunk_count = res; self.chunks.next() }) - }); + }); - has_chunk.map(|id| { (id, self.sample_count) }) + has_chunk.map(|id| (id, self.sample_count)) } } @@ -1200,24 +1263,24 @@ impl<'a> SampleToChunkIterator<'a> { (Some(next), Some(peek)) if next.first_chunk == peek.first_chunk => { // Invalid entry, skip it and will continue searching at // next loop iteration. - continue - }, + continue; + } (Some(next), Some(peek)) if next.first_chunk > 0 && peek.first_chunk > 0 => { self.sample_count = next.samples_per_chunk; - (next.first_chunk - 1) .. (peek.first_chunk - 1) - }, + (next.first_chunk - 1)..(peek.first_chunk - 1) + } (Some(next), None) if next.first_chunk > 0 => { self.sample_count = next.samples_per_chunk; // Total chunk number in 'stsc' could be different to 'stco', // there could be more chunks at the last 'stsc' record. match next.first_chunk.checked_add(self.remain_chunk_count) { - Some(r) => (next.first_chunk - 1) .. r - 1, - _ => 0 .. 0, + Some(r) => (next.first_chunk - 1)..r - 1, + _ => 0..0, } - }, - _ => 0 .. 0 + } + _ => 0..0, }; - }; + } } } @@ -1227,11 +1290,10 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option TrackTimeScale::(0, 0), }; - let (stsc, stco, stsz, stts) = - match (&track.stsc, &track.stco, &track.stsz, &track.stts) { - (&Some(ref a), &Some(ref b), &Some(ref c), &Some(ref d)) => (a, b, c, d), - _ => return None, - }; + let (stsc, stco, stsz, stts) = match (&track.stsc, &track.stco, &track.stsz, &track.stts) { + (&Some(ref a), &Some(ref b), &Some(ref c), &Some(ref d)) => (a, b, c, d), + _ => return None, + }; // According to spec, no sync table means every sample is sync sample. let has_sync_table = match track.stss { @@ -1245,7 +1307,7 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option Option i, _ => return None, }; - for _ in 0 .. sample_counts { + for _ in 0..sample_counts { let start_offset = cur_position; let end_offset = match (stsz.sample_size, sample_size_iter.next()) { (_, Some(t)) => start_offset + u64::from(*t), @@ -1270,14 +1332,17 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option Option elem.sync = true, _ => return None, } @@ -1300,14 +1368,14 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option Option return None, } } @@ -1350,23 +1418,19 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option { - v.start_composition - }, - _ => 0, - } + sort_table.sort_by_key(|i| match sample_table.get(*i) { + Some(v) => v.start_composition, + _ => 0, }); let iter = sort_table.iter(); - for i in 0 .. (iter.len() - 1) { + for i in 0..(iter.len() - 1) { let current_index = sort_table[i]; let peek_index = sort_table[i + 1]; let next_start_composition_time = sample_table[peek_index].start_composition; @@ -1388,7 +1452,10 @@ fn create_sample_table(track: &Track, track_offset_time: i64) -> Option Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_fragment_info( + parser: *mut Mp4parseParser, + info: *mut Mp4parseFragmentInfo, +) -> Mp4parseStatus { if parser.is_null() || info.is_null() { return Mp4parseStatus::BadArg; } @@ -1426,7 +1493,11 @@ pub unsafe extern fn mp4parse_get_fragment_info(parser: *mut Mp4parseParser, inf /// pointer points to a valid `Mp4parseParser` and that the fragmented pointer /// points to an appropriate memory location to have a `u8` written to. #[no_mangle] -pub unsafe extern fn mp4parse_is_fragmented(parser: *mut Mp4parseParser, track_id: u32, fragmented: *mut u8) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_is_fragmented( + parser: *mut Mp4parseParser, + track_id: u32, + fragmented: *mut u8, +) -> Mp4parseStatus { if parser.is_null() { return Mp4parseStatus::BadArg; } @@ -1441,14 +1512,20 @@ pub unsafe extern fn mp4parse_is_fragmented(parser: *mut Mp4parseParser, track_i // check sample tables. let mut iter = tracks.iter(); - iter.find(|track| track.track_id == Some(track_id)).map_or(Mp4parseStatus::BadArg, |track| { - match (&track.stsc, &track.stco, &track.stts) { - (&Some(ref stsc), &Some(ref stco), &Some(ref stts)) - if stsc.samples.is_empty() && stco.offsets.is_empty() && stts.samples.is_empty() => (*fragmented) = true as u8, - _ => {}, - }; - Mp4parseStatus::Ok - }) + iter.find(|track| track.track_id == Some(track_id)) + .map_or(Mp4parseStatus::BadArg, |track| { + match (&track.stsc, &track.stco, &track.stts) { + (&Some(ref stsc), &Some(ref stco), &Some(ref stts)) + if stsc.samples.is_empty() + && stco.offsets.is_empty() + && stts.samples.is_empty() => + { + (*fragmented) = true as u8 + } + _ => {} + }; + Mp4parseStatus::Ok + }) } /// Get 'pssh' system id and 'pssh' box content for eme playback. @@ -1466,7 +1543,10 @@ pub unsafe extern fn mp4parse_is_fragmented(parser: *mut Mp4parseParser, track_i /// pointer points to a valid `Mp4parseParser` and that the fragmented pointer /// points to a valid `Mp4parsePsshInfo`. #[no_mangle] -pub unsafe extern fn mp4parse_get_pssh_info(parser: *mut Mp4parseParser, info: *mut Mp4parsePsshInfo) -> Mp4parseStatus { +pub unsafe extern "C" fn mp4parse_get_pssh_info( + parser: *mut Mp4parseParser, + info: *mut Mp4parsePsshInfo, +) -> Mp4parseStatus { if parser.is_null() || info.is_null() { return Mp4parseStatus::BadArg; } @@ -1485,7 +1565,10 @@ pub unsafe extern fn mp4parse_get_pssh_info(parser: *mut Mp4parseParser, info: * return Mp4parseStatus::Invalid; } let mut data_len = Vec::new(); - if data_len.write_u32::(content_len as u32).is_err() { + if data_len + .write_u32::(content_len as u32) + .is_err() + { return Mp4parseStatus::Io; } pssh_data.extend_from_slice(pssh.system_id.as_slice()); @@ -1505,12 +1588,12 @@ pub unsafe extern fn mp4parse_get_pssh_info(parser: *mut Mp4parseParser, info: * } #[cfg(test)] -extern fn error_read(_: *mut u8, _: usize, _: *mut std::os::raw::c_void) -> isize { +extern "C" fn error_read(_: *mut u8, _: usize, _: *mut std::os::raw::c_void) -> isize { -1 } #[cfg(test)] -extern fn valid_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn valid_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; @@ -1546,8 +1629,10 @@ fn arg_validation() { let null_mut: *mut std::os::raw::c_void = std::ptr::null_mut(); // Passing an Mp4parseIo with null members is an error. - let io = Mp4parseIo { read: None, - userdata: null_mut }; + let io = Mp4parseIo { + read: None, + userdata: null_mut, + }; let mut rv = Mp4parseStatus::Invalid; let parser = mp4parse_new(&io, &mut rv); assert_eq!(rv, Mp4parseStatus::BadArg); @@ -1569,7 +1654,10 @@ fn arg_validation() { duration: 0, media_time: 0, }; - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_info(std::ptr::null_mut(), 0, &mut dummy_info)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_info(std::ptr::null_mut(), 0, &mut dummy_info) + ); let mut dummy_video = Mp4parseTrackVideoInfo { display_width: 0, @@ -1578,10 +1666,16 @@ fn arg_validation() { sample_info_count: 0, sample_info: std::ptr::null(), }; - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_video_info(std::ptr::null_mut(), 0, &mut dummy_video)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_video_info(std::ptr::null_mut(), 0, &mut dummy_video) + ); let mut dummy_audio = Default::default(); - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_audio_info(std::ptr::null_mut(), 0, &mut dummy_audio)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_audio_info(std::ptr::null_mut(), 0, &mut dummy_audio) + ); } } @@ -1599,9 +1693,18 @@ fn arg_validation_with_parser() { assert!(parser.is_null()); // Null info pointers are an error. - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_info(parser, 0, std::ptr::null_mut())); - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_video_info(parser, 0, std::ptr::null_mut())); - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_audio_info(parser, 0, std::ptr::null_mut())); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_info(parser, 0, std::ptr::null_mut()) + ); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_video_info(parser, 0, std::ptr::null_mut()) + ); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_audio_info(parser, 0, std::ptr::null_mut()) + ); let mut dummy_info = Mp4parseTrackInfo { track_type: Mp4parseTrackType::Video, @@ -1609,7 +1712,10 @@ fn arg_validation_with_parser() { duration: 0, media_time: 0, }; - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_info(parser, 0, &mut dummy_info)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_info(parser, 0, &mut dummy_info) + ); let mut dummy_video = Mp4parseTrackVideoInfo { display_width: 0, @@ -1618,10 +1724,16 @@ fn arg_validation_with_parser() { sample_info_count: 0, sample_info: std::ptr::null(), }; - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_video_info(parser, 0, &mut dummy_video)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_video_info(parser, 0, &mut dummy_video) + ); let mut dummy_audio = Default::default(); - assert_eq!(Mp4parseStatus::BadArg, mp4parse_get_track_audio_info(parser, 0, &mut dummy_audio)); + assert_eq!( + Mp4parseStatus::BadArg, + mp4parse_get_track_audio_info(parser, 0, &mut dummy_audio) + ); } } @@ -1647,8 +1759,10 @@ fn get_track_count_poisoned_parser() { #[cfg(test)] fn parse_minimal_mp4() -> *mut Mp4parseParser { let mut file = std::fs::File::open("../mp4parse/tests/minimal.mp4").unwrap(); - let io = Mp4parseIo { read: Some(valid_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void }; + let io = Mp4parseIo { + read: Some(valid_read), + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, + }; let mut rv = Mp4parseStatus::Invalid; let parser; unsafe { parser = mp4parse_new(&io, &mut rv) } @@ -1662,7 +1776,9 @@ fn minimal_mp4_parse_ok() { assert!(!parser.is_null()); - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1670,10 +1786,14 @@ fn minimal_mp4_get_track_cout() { let parser = parse_minimal_mp4(); let mut count: u32 = 0; - assert_eq!(Mp4parseStatus::Ok, unsafe { mp4parse_get_track_count(parser, &mut count) }); + assert_eq!(Mp4parseStatus::Ok, unsafe { + mp4parse_get_track_count(parser, &mut count) + }); assert_eq!(2, count); - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1686,19 +1806,25 @@ fn minimal_mp4_get_track_info() { duration: 0, media_time: 0, }; - assert_eq!(Mp4parseStatus::Ok, unsafe { mp4parse_get_track_info(parser, 0, &mut info) }); + assert_eq!(Mp4parseStatus::Ok, unsafe { + mp4parse_get_track_info(parser, 0, &mut info) + }); assert_eq!(info.track_type, Mp4parseTrackType::Video); assert_eq!(info.track_id, 1); assert_eq!(info.duration, 40000); assert_eq!(info.media_time, 0); - assert_eq!(Mp4parseStatus::Ok, unsafe { mp4parse_get_track_info(parser, 1, &mut info) }); + assert_eq!(Mp4parseStatus::Ok, unsafe { + mp4parse_get_track_info(parser, 1, &mut info) + }); assert_eq!(info.track_type, Mp4parseTrackType::Audio); assert_eq!(info.track_id, 2); assert_eq!(info.duration, 61333); assert_eq!(info.media_time, 21333); - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1706,7 +1832,9 @@ fn minimal_mp4_get_track_video_info() { let parser = parse_minimal_mp4(); let mut video = Mp4parseTrackVideoInfo::default(); - assert_eq!(Mp4parseStatus::Ok, unsafe { mp4parse_get_track_video_info(parser, 0, &mut video) }); + assert_eq!(Mp4parseStatus::Ok, unsafe { + mp4parse_get_track_video_info(parser, 0, &mut video) + }); assert_eq!(video.display_width, 320); assert_eq!(video.display_height, 240); assert_eq!(video.sample_info_count, 1); @@ -1716,7 +1844,9 @@ fn minimal_mp4_get_track_video_info() { assert_eq!((*video.sample_info).image_height, 240); } - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1724,7 +1854,9 @@ fn minimal_mp4_get_track_audio_info() { let parser = parse_minimal_mp4(); let mut audio = Mp4parseTrackAudioInfo::default(); - assert_eq!(Mp4parseStatus::Ok, unsafe { mp4parse_get_track_audio_info(parser, 1, &mut audio) }); + assert_eq!(Mp4parseStatus::Ok, unsafe { + mp4parse_get_track_audio_info(parser, 1, &mut audio) + }); assert_eq!(audio.sample_info_count, 1); unsafe { @@ -1733,7 +1865,9 @@ fn minimal_mp4_get_track_audio_info() { assert_eq!((*audio.sample_info).sample_rate, 48000); } - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1746,23 +1880,31 @@ fn minimal_mp4_get_track_info_invalid_track_number() { duration: 0, media_time: 0, }; - assert_eq!(Mp4parseStatus::BadArg, unsafe { mp4parse_get_track_info(parser, 3, &mut info) }); + assert_eq!(Mp4parseStatus::BadArg, unsafe { + mp4parse_get_track_info(parser, 3, &mut info) + }); assert_eq!(info.track_type, Mp4parseTrackType::Video); assert_eq!(info.track_id, 0); assert_eq!(info.duration, 0); assert_eq!(info.media_time, 0); let mut video = Mp4parseTrackVideoInfo::default(); - assert_eq!(Mp4parseStatus::BadArg, unsafe { mp4parse_get_track_video_info(parser, 3, &mut video) }); + assert_eq!(Mp4parseStatus::BadArg, unsafe { + mp4parse_get_track_video_info(parser, 3, &mut video) + }); assert_eq!(video.display_width, 0); assert_eq!(video.display_height, 0); assert_eq!(video.sample_info_count, 0); let mut audio = Default::default(); - assert_eq!(Mp4parseStatus::BadArg, unsafe { mp4parse_get_track_audio_info(parser, 3, &mut audio) }); + assert_eq!(Mp4parseStatus::BadArg, unsafe { + mp4parse_get_track_audio_info(parser, 3, &mut audio) + }); assert_eq!(audio.sample_info_count, 0); - unsafe { mp4parse_free(parser); } + unsafe { + mp4parse_free(parser); + } } #[test] @@ -1772,21 +1914,27 @@ fn rational_scale_overflow() { assert_eq!(rational_scale::(large, 2, 2), Some(large)); assert_eq!(rational_scale::(large, 4, 4), Some(large)); assert_eq!(rational_scale::(large, 2, 8), None); - assert_eq!(rational_scale::(large, 8, 4), Some(large/2)); - assert_eq!(rational_scale::(large + 1, 4, 4), Some(large+1)); + assert_eq!(rational_scale::(large, 8, 4), Some(large / 2)); + assert_eq!(rational_scale::(large + 1, 4, 4), Some(large + 1)); assert_eq!(rational_scale::(large, 40, 1000), None); } #[test] fn media_time_overflow() { - let scale = MediaTimeScale(90000); - let duration = MediaScaledTime(9_007_199_254_710_000); - assert_eq!(media_time_to_us(duration, scale), Some(100_079_991_719_000_000)); + let scale = MediaTimeScale(90000); + let duration = MediaScaledTime(9_007_199_254_710_000); + assert_eq!( + media_time_to_us(duration, scale), + Some(100_079_991_719_000_000) + ); } #[test] fn track_time_overflow() { - let scale = TrackTimeScale(44100u64, 0); - let duration = TrackScaledTime(4_413_527_634_807_900u64, 0); - assert_eq!(track_time_to_us(duration, scale), Some(100_079_991_719_000_000)); + let scale = TrackTimeScale(44100u64, 0); + let duration = TrackScaledTime(4_413_527_634_807_900u64, 0); + assert_eq!( + track_time_to_us(duration, scale), + Some(100_079_991_719_000_000) + ); } diff --git a/mp4parse_capi/tests/test_chunk_out_of_range.rs b/mp4parse_capi/tests/test_chunk_out_of_range.rs index ccf5efc1..3127a4cd 100644 --- a/mp4parse_capi/tests/test_chunk_out_of_range.rs +++ b/mp4parse_capi/tests/test_chunk_out_of_range.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -16,7 +16,7 @@ fn parse_out_of_chunk_range() { let mut file = std::fs::File::open("tests/chunk_out_of_range.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { diff --git a/mp4parse_capi/tests/test_encryption.rs b/mp4parse_capi/tests/test_encryption.rs index 5f164c2a..bfc4c223 100644 --- a/mp4parse_capi/tests/test_encryption.rs +++ b/mp4parse_capi/tests/test_encryption.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -17,7 +17,7 @@ fn parse_cenc() { let mut file = std::fs::File::open("tests/short-cenc.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -51,12 +51,17 @@ fn parse_cenc() { assert_eq!((*video.sample_info).image_width, 320); assert_eq!((*video.sample_info).image_height, 240); let protected_data = &(*video.sample_info).protected_data; - assert_eq!(protected_data.scheme_type, Mp4ParseEncryptionSchemeType::Cenc); + assert_eq!( + protected_data.scheme_type, + Mp4ParseEncryptionSchemeType::Cenc + ); assert_eq!(protected_data.is_encrypted, 0x01); assert_eq!(protected_data.iv_size, 16); assert_eq!(protected_data.kid.length, 16); - let expected_kid = [0x7e, 0x57, 0x1d, 0x01, 0x7e, 0x57, 0x1d, 0x01, - 0x7e, 0x57, 0x1d, 0x01, 0x7e, 0x57, 0x1d, 0x01]; + let expected_kid = [ + 0x7e, 0x57, 0x1d, 0x01, 0x7e, 0x57, 0x1d, 0x01, 0x7e, 0x57, 0x1d, 0x01, 0x7e, 0x57, + 0x1d, 0x01, + ]; for (i, expected_byte) in expected_kid.iter().enumerate() { assert_eq!(&(*protected_data.kid.data.add(i)), expected_byte); } @@ -77,8 +82,10 @@ fn parse_cenc() { assert_eq!(protected_data.is_encrypted, 0x01); assert_eq!(protected_data.iv_size, 16); assert_eq!(protected_data.kid.length, 16); - let expected_kid = [0x7e, 0x57, 0x1d, 0x02, 0x7e, 0x57, 0x1d, 0x02, - 0x7e, 0x57, 0x1d, 0x02, 0x7e, 0x57, 0x1d, 0x02]; + let expected_kid = [ + 0x7e, 0x57, 0x1d, 0x02, 0x7e, 0x57, 0x1d, 0x02, 0x7e, 0x57, 0x1d, 0x02, 0x7e, 0x57, + 0x1d, 0x02, + ]; for (i, expected_byte) in expected_kid.iter().enumerate() { assert_eq!(&(*protected_data.kid.data.add(i)), expected_byte); } @@ -93,7 +100,7 @@ fn parse_cbcs() { let mut file = std::fs::File::open("tests/bipbop_cbcs_video_init.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -121,20 +128,27 @@ fn parse_cbcs() { assert_eq!((*video.sample_info).image_width, 400); assert_eq!((*video.sample_info).image_height, 300); let protected_data = &(*video.sample_info).protected_data; - assert_eq!(protected_data.scheme_type, Mp4ParseEncryptionSchemeType::Cbcs); + assert_eq!( + protected_data.scheme_type, + Mp4ParseEncryptionSchemeType::Cbcs + ); assert_eq!(protected_data.is_encrypted, 0x01); assert_eq!(protected_data.iv_size, 0); assert_eq!(protected_data.kid.length, 16); - let expected_kid = [0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, - 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21]; + let expected_kid = [ + 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, + 0x1d, 0x21, + ]; for (i, expected_byte) in expected_kid.iter().enumerate() { assert_eq!(&(*protected_data.kid.data.add(i)), expected_byte); } assert_eq!(protected_data.crypt_byte_block, 1); assert_eq!(protected_data.skip_byte_block, 9); assert_eq!(protected_data.constant_iv.length, 16); - let expected_iv = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66]; + let expected_iv = [ + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, + 0x55, 0x66, + ]; for (i, expected_byte) in expected_iv.iter().enumerate() { assert_eq!(&(*protected_data.constant_iv.data.add(i)), expected_byte); } @@ -148,7 +162,7 @@ fn parse_unencrypted() { let mut file = std::fs::File::open("tests/opus_audioinit.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -172,7 +186,10 @@ fn parse_unencrypted() { assert_eq!(rv, Mp4parseStatus::Ok); assert_eq!(audio.sample_info_count, 1); let protected_data = &(*audio.sample_info).protected_data; - assert_eq!(protected_data.scheme_type, Mp4ParseEncryptionSchemeType::None); + assert_eq!( + protected_data.scheme_type, + Mp4ParseEncryptionSchemeType::None + ); assert_eq!(protected_data.is_encrypted, 0x00); assert_eq!(protected_data.iv_size, 0); assert_eq!(protected_data.kid.length, 0); diff --git a/mp4parse_capi/tests/test_fragment.rs b/mp4parse_capi/tests/test_fragment.rs index 828eb8f1..d39b09d6 100644 --- a/mp4parse_capi/tests/test_fragment.rs +++ b/mp4parse_capi/tests/test_fragment.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -16,7 +16,7 @@ fn parse_fragment() { let mut file = std::fs::File::open("tests/bipbop_audioinit.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -64,13 +64,12 @@ fn parse_fragment() { } } - #[test] fn parse_opus_fragment() { let mut file = std::fs::File::open("tests/opus_audioinit.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -115,4 +114,4 @@ fn parse_opus_fragment() { mp4parse_free(parser); } -} \ No newline at end of file +} diff --git a/mp4parse_capi/tests/test_rotation.rs b/mp4parse_capi/tests/test_rotation.rs index 7a335cd7..459debcd 100644 --- a/mp4parse_capi/tests/test_rotation.rs +++ b/mp4parse_capi/tests/test_rotation.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -16,7 +16,7 @@ fn parse_rotation() { let mut file = std::fs::File::open("tests/video_rotation_90.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { diff --git a/mp4parse_capi/tests/test_sample_table.rs b/mp4parse_capi/tests/test_sample_table.rs index 9660f164..77d2c4f5 100644 --- a/mp4parse_capi/tests/test_sample_table.rs +++ b/mp4parse_capi/tests/test_sample_table.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -13,10 +13,11 @@ extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_voi #[test] fn parse_sample_table() { - let mut file = std::fs::File::open("tests/bipbop_nonfragment_header.mp4").expect("Unknown file"); + let mut file = + std::fs::File::open("tests/bipbop_nonfragment_header.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -46,8 +47,22 @@ fn parse_sample_table() { assert_eq!(rv, Mp4parseStatus::Ok); // Compare the value from stagefright. - let audio_indice_0 = Mp4parseIndice { start_offset: 27_046, end_offset: 27_052, start_composition: 0, end_composition: 46_439, start_decode: 0, sync: true }; - let audio_indice_215 = Mp4parseIndice { start_offset: 283_550, end_offset: 283_556, start_composition: 9_984_580, end_composition: 10_031_020, start_decode: 9_984_580, sync: true }; + let audio_indice_0 = Mp4parseIndice { + start_offset: 27_046, + end_offset: 27_052, + start_composition: 0, + end_composition: 46_439, + start_decode: 0, + sync: true, + }; + let audio_indice_215 = Mp4parseIndice { + start_offset: 283_550, + end_offset: 283_556, + start_composition: 9_984_580, + end_composition: 10_031_020, + start_decode: 9_984_580, + sync: true, + }; assert_eq!(indice.length, 216); assert_eq!(*indice.indices.offset(0), audio_indice_0); assert_eq!(*indice.indices.offset(215), audio_indice_215); @@ -67,14 +82,42 @@ fn parse_sample_table() { assert_eq!(rv, Mp4parseStatus::Ok); // Compare the last few data from stagefright. - let video_indice_291 = Mp4parseIndice { start_offset: 280_226, end_offset: 280_855, start_composition: 9_838_333, end_composition: 9_871_677, start_decode: 9_710_000, sync: false }; - let video_indice_292 = Mp4parseIndice { start_offset: 280_855, end_offset: 281_297, start_composition: 9_805_011, end_composition: 9_838_333, start_decode: 9_710_011, sync: false }; + let video_indice_291 = Mp4parseIndice { + start_offset: 280_226, + end_offset: 280_855, + start_composition: 9_838_333, + end_composition: 9_871_677, + start_decode: 9_710_000, + sync: false, + }; + let video_indice_292 = Mp4parseIndice { + start_offset: 280_855, + end_offset: 281_297, + start_composition: 9_805_011, + end_composition: 9_838_333, + start_decode: 9_710_011, + sync: false, + }; // TODO: start_composition time in stagefright is 9905000, but it is 9904999 in parser, it // could be rounding error. //let video_indice_293 = Mp4parseIndice { start_offset: 281_297, end_offset: 281_919, start_composition: 9_905_000, end_composition: 9_938_344, start_decode: 9_776_666, sync: false }; //let video_indice_294 = Mp4parseIndice { start_offset: 281_919, end_offset: 282_391, start_composition: 9_871_677, end_composition: 9_905_000, start_decode: 9_776_677, sync: false }; - let video_indice_295 = Mp4parseIndice { start_offset: 282_391, end_offset: 283_032, start_composition: 9_971_666, end_composition: 9_971_677, start_decode: 9_843_333, sync: false }; - let video_indice_296 = Mp4parseIndice { start_offset: 283_092, end_offset: 283_526, start_composition: 9_938_344, end_composition: 9_971_666, start_decode: 9_843_344, sync: false }; + let video_indice_295 = Mp4parseIndice { + start_offset: 282_391, + end_offset: 283_032, + start_composition: 9_971_666, + end_composition: 9_971_677, + start_decode: 9_843_333, + sync: false, + }; + let video_indice_296 = Mp4parseIndice { + start_offset: 283_092, + end_offset: 283_526, + start_composition: 9_938_344, + end_composition: 9_971_666, + start_decode: 9_843_344, + sync: false, + }; assert_eq!(indice.length, 297); assert_eq!(*indice.indices.offset(291), video_indice_291); @@ -93,7 +136,7 @@ fn parse_sample_table_with_elst() { let mut file = std::fs::File::open("tests/short-cenc.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -125,9 +168,30 @@ fn parse_sample_table_with_elst() { // Compare the value from stagefright. // Due to 'elst', the start_composition and end_composition are negative // at first two samples. - let audio_indice_0 = Mp4parseIndice { start_offset: 6992, end_offset: 7363, start_composition: -36281, end_composition: -13062, start_decode: 0, sync: true }; - let audio_indice_1 = Mp4parseIndice { start_offset: 7363, end_offset: 7735, start_composition: -13062, end_composition: 10158, start_decode: 23219, sync: true }; - let audio_indice_2 = Mp4parseIndice { start_offset: 7735, end_offset: 8106, start_composition: 10158, end_composition: 33378, start_decode: 46439, sync: true }; + let audio_indice_0 = Mp4parseIndice { + start_offset: 6992, + end_offset: 7363, + start_composition: -36281, + end_composition: -13062, + start_decode: 0, + sync: true, + }; + let audio_indice_1 = Mp4parseIndice { + start_offset: 7363, + end_offset: 7735, + start_composition: -13062, + end_composition: 10158, + start_decode: 23219, + sync: true, + }; + let audio_indice_2 = Mp4parseIndice { + start_offset: 7735, + end_offset: 8106, + start_composition: 10158, + end_composition: 33378, + start_decode: 46439, + sync: true, + }; assert_eq!(indice.length, 21); assert_eq!(*indice.indices.offset(0), audio_indice_0); assert_eq!(*indice.indices.offset(1), audio_indice_1); @@ -142,7 +206,7 @@ fn parse_sample_table_with_negative_ctts() { let mut file = std::fs::File::open("tests/white.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe { @@ -171,10 +235,38 @@ fn parse_sample_table_with_negative_ctts() { assert_eq!(rv, Mp4parseStatus::Ok); // There are negative value in 'ctts' table. - let video_indice_0 = Mp4parseIndice { start_offset: 48, end_offset: 890, start_composition: 0, end_composition: 33_333, start_decode: 0, sync: true }; - let video_indice_1 = Mp4parseIndice { start_offset: 890, end_offset: 913, start_composition: 133_333, end_composition: 166_666, start_decode: 33_333, sync: false }; - let video_indice_2 = Mp4parseIndice { start_offset: 913, end_offset: 934, start_composition: 66_666, end_composition: 100_000, start_decode: 66_666, sync: false }; - let video_indice_3 = Mp4parseIndice { start_offset: 934, end_offset: 955, start_composition: 33_333, end_composition: 66_666, start_decode: 100_000, sync: false }; + let video_indice_0 = Mp4parseIndice { + start_offset: 48, + end_offset: 890, + start_composition: 0, + end_composition: 33_333, + start_decode: 0, + sync: true, + }; + let video_indice_1 = Mp4parseIndice { + start_offset: 890, + end_offset: 913, + start_composition: 133_333, + end_composition: 166_666, + start_decode: 33_333, + sync: false, + }; + let video_indice_2 = Mp4parseIndice { + start_offset: 913, + end_offset: 934, + start_composition: 66_666, + end_composition: 100_000, + start_decode: 66_666, + sync: false, + }; + let video_indice_3 = Mp4parseIndice { + start_offset: 934, + end_offset: 955, + start_composition: 33_333, + end_composition: 66_666, + start_decode: 100_000, + sync: false, + }; assert_eq!(indice.length, 300); assert_eq!(*indice.indices.offset(0), video_indice_0); assert_eq!(*indice.indices.offset(1), video_indice_1); diff --git a/mp4parse_capi/tests/test_workaround_stsc.rs b/mp4parse_capi/tests/test_workaround_stsc.rs index 439cb2bc..7317d536 100644 --- a/mp4parse_capi/tests/test_workaround_stsc.rs +++ b/mp4parse_capi/tests/test_workaround_stsc.rs @@ -1,8 +1,8 @@ extern crate mp4parse_capi; -use std::io::Read; use mp4parse_capi::*; +use std::io::Read; -extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { +extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut std::fs::File = unsafe { &mut *(userdata as *mut _) }; let mut buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(&mut buf) { @@ -16,7 +16,7 @@ fn parse_invalid_stsc_table() { let mut file = std::fs::File::open("tests/zero_empty_stsc.mp4").expect("Unknown file"); let io = Mp4parseIo { read: Some(buf_read), - userdata: &mut file as *mut _ as *mut std::os::raw::c_void + userdata: &mut file as *mut _ as *mut std::os::raw::c_void, }; unsafe {