Bug 1946245 - update mp4parse to revision e64650a686e5c5732395cd059e17cfd3b1e5b63b. r=media-playback-reviewers,padenot
Differential Revision: https://phabricator.services.mozilla.com/D236620
This commit is contained in:
@@ -110,9 +110,9 @@ git = "https://github.com/mozilla/midir.git"
|
||||
rev = "85156e360a37d851734118104619f86bd18e94c6"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/mp4parse-rust?rev=a138e40ec1c603615873e524b5b22e11c0ec4820"]
|
||||
[source."git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b"]
|
||||
git = "https://github.com/mozilla/mp4parse-rust"
|
||||
rev = "a138e40ec1c603615873e524b5b22e11c0ec4820"
|
||||
rev = "e64650a686e5c5732395cd059e17cfd3b1e5b63b"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/neqo?tag=v0.11.0"]
|
||||
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -4435,7 +4435,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mp4parse"
|
||||
version = "0.17.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=a138e40ec1c603615873e524b5b22e11c0ec4820#a138e40ec1c603615873e524b5b22e11c0ec4820"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b#e64650a686e5c5732395cd059e17cfd3b1e5b63b"
|
||||
dependencies = [
|
||||
"bitreader",
|
||||
"byteorder",
|
||||
@@ -4452,7 +4452,7 @@ version = "0.1.0"
|
||||
[[package]]
|
||||
name = "mp4parse_capi"
|
||||
version = "0.17.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=a138e40ec1c603615873e524b5b22e11c0ec4820#a138e40ec1c603615873e524b5b22e11c0ec4820"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=e64650a686e5c5732395cd059e17cfd3b1e5b63b#e64650a686e5c5732395cd059e17cfd3b1e5b63b"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fallible_collections",
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
third_party/rust/mp4parse/Cargo.toml
vendored
2
third_party/rust/mp4parse/Cargo.toml
vendored
@@ -66,7 +66,7 @@ static_assertions = "1.1.0"
|
||||
version = "0.3.2"
|
||||
|
||||
[dependencies.fallible_collections]
|
||||
version = "0.4"
|
||||
version = "0.4.9"
|
||||
features = ["std_io"]
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
77
third_party/rust/mp4parse/src/lib.rs
vendored
77
third_party/rust/mp4parse/src/lib.rs
vendored
@@ -128,13 +128,13 @@ impl<'a, T> OffsetReader<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Offset for OffsetReader<'a, T> {
|
||||
impl<T> Offset for OffsetReader<'_, T> {
|
||||
fn offset(&self) -> u64 {
|
||||
self.offset
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Read> Read for OffsetReader<'a, T> {
|
||||
impl<T: Read> Read for OffsetReader<'_, T> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
let bytes_read = self.reader.read(buf)?;
|
||||
trace!("Read {} bytes at offset {}", bytes_read, self.offset);
|
||||
@@ -1173,6 +1173,7 @@ pub struct VideoSampleEntry {
|
||||
pub height: u16,
|
||||
pub codec_specific: VideoCodecSpecific,
|
||||
pub protection_info: TryVec<ProtectionSchemeInfoBox>,
|
||||
pub pixel_aspect_ratio: Option<f32>,
|
||||
}
|
||||
|
||||
/// Represent a Video Partition Codec Configuration 'vpcC' box (aka vp9). The meaning of each
|
||||
@@ -2000,9 +2001,9 @@ enum ConstructionMethod {
|
||||
/// Describes a region where a item specified by an `ItemLocationBoxItem` is stored.
|
||||
/// The offset is `u64` since that's the maximum possible size and since the relative
|
||||
/// nature of `DataBox` means this can still possibly succeed even in the case
|
||||
/// that the raw value exceeds std::usize::MAX on platforms where that type is smaller
|
||||
/// that the raw value exceeds usize::MAX on platforms where that type is smaller
|
||||
/// than u64. However, `len` is stored as a `usize` since no value larger than
|
||||
/// `std::usize::MAX` can be used in a successful indexing operation in rust.
|
||||
/// `usize::MAX` can be used in a successful indexing operation in rust.
|
||||
/// `extent_index` is omitted since it's only used for ConstructionMethod::Item which
|
||||
/// is currently not implemented.
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -2138,7 +2139,7 @@ struct BoxIter<'a, T: 'a> {
|
||||
src: &'a mut T,
|
||||
}
|
||||
|
||||
impl<'a, T: Read> BoxIter<'a, T> {
|
||||
impl<T: Read> BoxIter<'_, T> {
|
||||
fn new(src: &mut T) -> BoxIter<T> {
|
||||
BoxIter { src }
|
||||
}
|
||||
@@ -2156,19 +2157,19 @@ impl<'a, T: Read> BoxIter<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Read> Read for BMFFBox<'a, T> {
|
||||
impl<T: Read> Read for BMFFBox<'_, T> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
self.content.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Read> TryRead for BMFFBox<'a, T> {
|
||||
impl<T: Read> TryRead for BMFFBox<'_, T> {
|
||||
fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> std::io::Result<usize> {
|
||||
fallible_collections::try_read_up_to(self, self.bytes_left(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Offset> Offset for BMFFBox<'a, T> {
|
||||
impl<T: Offset> Offset for BMFFBox<'_, T> {
|
||||
fn offset(&self) -> u64 {
|
||||
self.content.get_ref().offset()
|
||||
}
|
||||
@@ -2183,12 +2184,12 @@ impl<'a, T: Read> BMFFBox<'a, T> {
|
||||
&self.head
|
||||
}
|
||||
|
||||
fn box_iter<'b>(&'b mut self) -> BoxIter<BMFFBox<'a, T>> {
|
||||
fn box_iter(&mut self) -> BoxIter<BMFFBox<'a, T>> {
|
||||
BoxIter::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for BMFFBox<'a, T> {
|
||||
impl<T> Drop for BMFFBox<'_, T> {
|
||||
fn drop(&mut self) {
|
||||
if self.content.limit() > 0 {
|
||||
let name: FourCC = From::from(self.head.name);
|
||||
@@ -2206,10 +2207,7 @@ impl<'a, T> Drop for BMFFBox<'a, T> {
|
||||
///
|
||||
/// See ISOBMFF (ISO 14496-12:2020) § 4.2
|
||||
fn read_box_header<T: ReadBytesExt>(src: &mut T) -> Result<BoxHeader> {
|
||||
let size32 = match be_u32(src) {
|
||||
Ok(v) => v,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let size32 = be_u32(src)?;
|
||||
let name = BoxType::from(be_u32(src)?);
|
||||
let size = match size32 {
|
||||
// valid only for top-level box and indicates it's the last box in the file. usually mdat.
|
||||
@@ -2267,7 +2265,7 @@ fn read_fullbox_extra<T: ReadBytesExt>(src: &mut T) -> Result<(u8, u32)> {
|
||||
let flags_c = src.read_u8()?;
|
||||
Ok((
|
||||
version,
|
||||
u32::from(flags_a) << 16 | u32::from(flags_b) << 8 | u32::from(flags_c),
|
||||
(u32::from(flags_a) << 16) | (u32::from(flags_b) << 8) | u32::from(flags_c),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -2484,7 +2482,7 @@ pub fn read_avif<T: Read>(f: &mut T, strictness: ParseStrictness) -> Result<Avif
|
||||
return Status::MultipleAlpha.into();
|
||||
}
|
||||
|
||||
let premultiplied_alpha = alpha_item_id.map_or(false, |alpha_item_id| {
|
||||
let premultiplied_alpha = alpha_item_id.is_some_and(|alpha_item_id| {
|
||||
item_references.iter().any(|iref| {
|
||||
iref.from_item_id == primary_item_id
|
||||
&& iref.to_item_id == alpha_item_id
|
||||
@@ -2623,7 +2621,7 @@ pub fn read_avif<T: Read>(f: &mut T, strictness: ParseStrictness) -> Result<Avif
|
||||
|
||||
// Returns true iff `id` is `Some` and there is no corresponding property for it
|
||||
let missing_property_for = |id: Option<ItemId>, property: BoxType| -> bool {
|
||||
id.map_or(false, |id| {
|
||||
id.is_some_and(|id| {
|
||||
item_properties
|
||||
.get(id, property)
|
||||
.map_or(true, |opt| opt.is_none())
|
||||
@@ -4338,7 +4336,7 @@ fn parse_mdhd<T: Read>(
|
||||
)> {
|
||||
let mdhd = read_mdhd(f)?;
|
||||
let duration = match mdhd.duration {
|
||||
std::u64::MAX => None,
|
||||
u64::MAX => None,
|
||||
duration => Some(TrackScaledTime::<u64>(duration, track.id)),
|
||||
};
|
||||
if mdhd.timescale == 0 {
|
||||
@@ -4509,8 +4507,8 @@ fn read_mvhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieHeaderBox> {
|
||||
1 => be_u64(src)?,
|
||||
0 => {
|
||||
let d = be_u32(src)?;
|
||||
if d == std::u32::MAX {
|
||||
std::u64::MAX
|
||||
if d == u32::MAX {
|
||||
u64::MAX
|
||||
} else {
|
||||
u64::from(d)
|
||||
}
|
||||
@@ -4636,8 +4634,8 @@ fn read_mdhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MediaHeaderBox> {
|
||||
// upcasting, we need to preserve the special all-1s
|
||||
// ("unknown") case by hand.
|
||||
let d = be_u32(src)?;
|
||||
if d == std::u32::MAX {
|
||||
std::u64::MAX
|
||||
if d == u32::MAX {
|
||||
u64::MAX
|
||||
} else {
|
||||
u64::from(d)
|
||||
}
|
||||
@@ -5431,14 +5429,13 @@ fn read_hdlr<T: Read>(src: &mut BMFFBox<T>, strictness: ParseStrictness) -> Resu
|
||||
|
||||
match std::str::from_utf8(src.read_into_try_vec()?.as_slice()) {
|
||||
Ok(name) => {
|
||||
match name.bytes().position(|b| b == b'\0') {
|
||||
None => fail_with_status_if(
|
||||
// `name` must be nul-terminated and any trailing bytes after the first nul ignored.
|
||||
// See https://github.com/MPEGGroup/FileFormat/issues/35
|
||||
if !name.bytes().any(|b| b == b'\0') {
|
||||
fail_with_status_if(
|
||||
strictness != ParseStrictness::Permissive,
|
||||
Status::HdlrNameNoNul,
|
||||
)?,
|
||||
// `name` must be nul-terminated and any trailing bytes after the first nul ignored.
|
||||
// See https://github.com/MPEGGroup/FileFormat/issues/35
|
||||
Some(_) => (),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Err(_) => fail_with_status_if(
|
||||
@@ -5484,6 +5481,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
|
||||
// Skip clap/pasp/etc. for now.
|
||||
let mut codec_specific = None;
|
||||
let mut pixel_aspect_ratio = None;
|
||||
let mut protection_info = TryVec::new();
|
||||
let mut iter = src.box_iter();
|
||||
while let Some(mut b) = iter.next_box()? {
|
||||
@@ -5590,6 +5588,16 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
debug!("{:?} (hvcc)", hvcc);
|
||||
codec_specific = Some(VideoCodecSpecific::HEVCConfig(hvcc));
|
||||
}
|
||||
BoxType::PixelAspectRatioBox => {
|
||||
let pasp = read_pasp(&mut b)?;
|
||||
let aspect_ratio = pasp.h_spacing as f32 / pasp.v_spacing as f32;
|
||||
let is_valid_aspect_ratio = |value: f32| -> bool { value > 0.0 && value < 10.0 };
|
||||
// Only set pixel_aspect_ratio if it is valid
|
||||
if is_valid_aspect_ratio(aspect_ratio) {
|
||||
pixel_aspect_ratio = Some(aspect_ratio);
|
||||
}
|
||||
debug!("Parsed pasp box: {:?}, PAR {:?}", pasp, pixel_aspect_ratio);
|
||||
}
|
||||
_ => {
|
||||
debug!("Unsupported video codec, box {:?} found", b.head.name);
|
||||
skip_box_content(&mut b)?;
|
||||
@@ -5607,6 +5615,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
height,
|
||||
codec_specific,
|
||||
protection_info,
|
||||
pixel_aspect_ratio,
|
||||
})
|
||||
}),
|
||||
)
|
||||
@@ -6291,10 +6300,10 @@ mod media_data_box_tests {
|
||||
|
||||
#[test]
|
||||
fn extent_with_length_which_overflows_usize() {
|
||||
let mdat = DataBox::at_offset(std::u64::MAX - 1, vec![1; 5]);
|
||||
let mdat = DataBox::at_offset(u64::MAX - 1, vec![1; 5]);
|
||||
let extent = Extent::WithLength {
|
||||
offset: std::u64::MAX,
|
||||
len: std::usize::MAX,
|
||||
offset: u64::MAX,
|
||||
len: usize::MAX,
|
||||
};
|
||||
|
||||
assert!(mdat.get(&extent).is_none());
|
||||
@@ -6304,10 +6313,8 @@ mod media_data_box_tests {
|
||||
// because the range end is unbounded, we don't calculate it.
|
||||
#[test]
|
||||
fn extent_to_end_which_overflows_usize() {
|
||||
let mdat = DataBox::at_offset(std::u64::MAX - 1, vec![1; 5]);
|
||||
let extent = Extent::ToEnd {
|
||||
offset: std::u64::MAX,
|
||||
};
|
||||
let mdat = DataBox::at_offset(u64::MAX - 1, vec![1; 5]);
|
||||
let extent = Extent::ToEnd { offset: u64::MAX };
|
||||
|
||||
assert_eq!(mdat.get(&extent), Some(&[1, 1, 1, 1][..]));
|
||||
}
|
||||
|
||||
14
third_party/rust/mp4parse/src/tests.rs
vendored
14
third_party/rust/mp4parse/src/tests.rs
vendored
@@ -59,7 +59,7 @@ where
|
||||
BoxSize::Long(size) => assert_eq!(size, section.size()),
|
||||
BoxSize::Auto => {
|
||||
assert!(
|
||||
section.size() <= u64::from(u32::max_value()),
|
||||
section.size() <= u64::from(u32::MAX),
|
||||
"Tried to use a long box with BoxSize::Auto"
|
||||
);
|
||||
box_size.set_const(section.size());
|
||||
@@ -335,7 +335,7 @@ fn read_mdhd_unknown_duration() {
|
||||
s.B32(0)
|
||||
.B32(0)
|
||||
.B32(1234) // timescale
|
||||
.B32(::std::u32::MAX) // duration
|
||||
.B32(u32::MAX) // duration
|
||||
.B32(0)
|
||||
});
|
||||
let mut iter = super::BoxIter::new(&mut stream);
|
||||
@@ -344,7 +344,7 @@ fn read_mdhd_unknown_duration() {
|
||||
assert_eq!(stream.head.size, 32);
|
||||
let parsed = super::read_mdhd(&mut stream).unwrap();
|
||||
assert_eq!(parsed.timescale, 1234);
|
||||
assert_eq!(parsed.duration, ::std::u64::MAX);
|
||||
assert_eq!(parsed.duration, u64::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -411,7 +411,7 @@ fn read_mvhd_unknown_duration() {
|
||||
s.B32(0)
|
||||
.B32(0)
|
||||
.B32(1234)
|
||||
.B32(::std::u32::MAX)
|
||||
.B32(u32::MAX)
|
||||
.append_repeated(0, 80)
|
||||
});
|
||||
let mut iter = super::BoxIter::new(&mut stream);
|
||||
@@ -420,7 +420,7 @@ fn read_mvhd_unknown_duration() {
|
||||
assert_eq!(stream.head.size, 108);
|
||||
let parsed = super::read_mvhd(&mut stream).unwrap();
|
||||
assert_eq!(parsed.timescale, 1234);
|
||||
assert_eq!(parsed.duration, ::std::u64::MAX);
|
||||
assert_eq!(parsed.duration, u64::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -688,7 +688,7 @@ fn make_dfla(
|
||||
}
|
||||
};
|
||||
let block_type = (block_type as u32) & 0x7f;
|
||||
s.B32(flag << 31 | block_type << 24 | size)
|
||||
s.B32((flag << 31) | (block_type << 24) | size)
|
||||
.append_bytes(data)
|
||||
})
|
||||
}
|
||||
@@ -1361,6 +1361,6 @@ fn read_to_end_() {
|
||||
|
||||
#[test]
|
||||
fn read_to_end_oom() {
|
||||
let mut src = b"1234567890".take(std::isize::MAX.try_into().expect("isize < u64"));
|
||||
let mut src = b"1234567890".take(isize::MAX.try_into().expect("isize < u64"));
|
||||
assert!(src.read_into_try_vec().is_err());
|
||||
}
|
||||
|
||||
12
third_party/rust/mp4parse/src/unstable.rs
vendored
12
third_party/rust/mp4parse/src/unstable.rs
vendored
@@ -285,7 +285,7 @@ struct TimeOffsetIterator<'a> {
|
||||
track_id: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for TimeOffsetIterator<'a> {
|
||||
impl Iterator for TimeOffsetIterator<'_> {
|
||||
type Item = i64;
|
||||
|
||||
#[allow(clippy::reversed_empty_ranges)]
|
||||
@@ -320,7 +320,7 @@ impl<'a> Iterator for TimeOffsetIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TimeOffsetIterator<'a> {
|
||||
impl TimeOffsetIterator<'_> {
|
||||
fn next_offset_time(&mut self) -> TrackScaledTime<i64> {
|
||||
match self.next() {
|
||||
Some(v) => TrackScaledTime::<i64>(v, self.track_id),
|
||||
@@ -342,7 +342,7 @@ struct TimeToSampleIterator<'a> {
|
||||
track_id: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for TimeToSampleIterator<'a> {
|
||||
impl Iterator for TimeToSampleIterator<'_> {
|
||||
type Item = u32;
|
||||
|
||||
#[allow(clippy::reversed_empty_ranges)]
|
||||
@@ -363,7 +363,7 @@ impl<'a> Iterator for TimeToSampleIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TimeToSampleIterator<'a> {
|
||||
impl TimeToSampleIterator<'_> {
|
||||
fn next_delta(&mut self) -> TrackScaledTime<i64> {
|
||||
match self.next() {
|
||||
Some(v) => TrackScaledTime::<i64>(i64::from(v), self.track_id),
|
||||
@@ -405,7 +405,7 @@ struct SampleToChunkIterator<'a> {
|
||||
remain_chunk_count: u32, // total chunk number from 'stco'.
|
||||
}
|
||||
|
||||
impl<'a> Iterator for SampleToChunkIterator<'a> {
|
||||
impl Iterator for SampleToChunkIterator<'_> {
|
||||
type Item = (u32, u32);
|
||||
|
||||
fn next(&mut self) -> Option<(u32, u32)> {
|
||||
@@ -428,7 +428,7 @@ impl<'a> Iterator for SampleToChunkIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SampleToChunkIterator<'a> {
|
||||
impl SampleToChunkIterator<'_> {
|
||||
#[allow(clippy::reversed_empty_ranges)]
|
||||
fn locate(&mut self) -> std::ops::Range<u32> {
|
||||
loop {
|
||||
|
||||
5
third_party/rust/mp4parse/tests/overflow.rs
vendored
5
third_party/rust/mp4parse/tests/overflow.rs
vendored
@@ -5,11 +5,12 @@
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#[test]
|
||||
#[allow(arithmetic_overflow)]
|
||||
#[should_panic(expected = "attempt to add with overflow")]
|
||||
fn overflow_protection() {
|
||||
let edge = u32::max_value();
|
||||
let edge = u32::MAX;
|
||||
assert_eq!(0u32, edge + 1);
|
||||
|
||||
let edge = u64::max_value();
|
||||
let edge = u64::MAX;
|
||||
assert_eq!(0u64, edge + 1);
|
||||
}
|
||||
|
||||
33
third_party/rust/mp4parse/tests/public.rs
vendored
33
third_party/rust/mp4parse/tests/public.rs
vendored
@@ -231,6 +231,10 @@ static AUDIO_AMRWB_3GP: &str = "tests/amr_wb_1f.3gp";
|
||||
// "ffmpeg -i [input file] -f mp4 -c:v mpeg4 -vf scale=176x144 -frames:v 1 -an output.mp4"
|
||||
static VIDEO_MP4V_MP4: &str = "tests/bbb_sunflower_QCIF_30fps_mp4v_noaudio_1f.mp4";
|
||||
|
||||
// The 1 frame h264 mp4 file with pasp box generated by ffmpeg with command
|
||||
// ffmpeg -f lavfi -i color=c=white:s=640x480 -c:v libx264 -frames:v 1 -pix_fmt yuv420p -vf "setsar=16/9" h264_white_frame_sar_16_9.mp4
|
||||
static VIDEO_H264_PASP_MP4: &str = "tests/h264_white_frame_sar_16_9.mp4";
|
||||
|
||||
// Adapted from https://github.com/GuillaumeGomez/audio-video-metadata/blob/9dff40f565af71d5502e03a2e78ae63df95cfd40/src/metadata.rs#L53
|
||||
#[test]
|
||||
fn public_api() {
|
||||
@@ -1468,6 +1472,35 @@ fn public_video_hevc() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_parse_pasp_h264() {
|
||||
let mut fd = File::open(VIDEO_H264_PASP_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
fd.read_to_end(&mut buf).expect("File error");
|
||||
|
||||
let mut c = Cursor::new(&buf);
|
||||
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
|
||||
for track in context.tracks {
|
||||
let stsd = track.stsd.expect("expected an stsd");
|
||||
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
|
||||
mp4::SampleEntry::Video(ref v) => v,
|
||||
_ => panic!("expected a VideoSampleEntry"),
|
||||
};
|
||||
assert_eq!(v.codec_type, mp4::CodecType::H264);
|
||||
assert_eq!(v.width, 640);
|
||||
assert_eq!(v.height, 480);
|
||||
assert!(
|
||||
v.pixel_aspect_ratio.is_some(),
|
||||
"pixel_aspect_ratio should exist"
|
||||
);
|
||||
assert_eq!(
|
||||
{ v.pixel_aspect_ratio.unwrap() },
|
||||
16.0 / 9.0,
|
||||
"pixel_aspect_ratio should be 16/9"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "3gpp")]
|
||||
fn public_audio_amrnb() {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"b82786cfefb5e38d154b64ecc3e610b2a713ff7f036ea800e143e5a01c6fcbdb","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"2a3cdebc5ed6f0f6b640e6722cd13fc7f4534774eb057b369a791c2eddb8132d","src/lib.rs":"97c7f8d6a47b395e3e31ac98e66ac08cf5b35a5bd94fcf3fb373b10749916cd8","tests/test_avis.rs":"d480b104ab2dfde7a25afd6705532caf7988aea21fc955dcf2f86fc8a5e85151","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"53ed6a5e8db463ad8dc0300116f470c2aadd39896e6ba4cabcd01c6b9a7b5c59","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null}
|
||||
{"files":{"Cargo.toml":"fb25b7a0c2332314bd9b381e0c4fff40281bbdf7704671022462d00fe406f63c","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"aef3a73e9f5e8dc125e449f7dc7eb8a8c6cfa0edf5f99114d4b90c52e0903613","src/lib.rs":"4f8048452328adeb23e6bfb656e2305b64ed3b3cef30c68509acf1635953212b","tests/test_avis.rs":"f01df914abcb18b562e74c39e15a0fa53159dbe93e9bd8698fab30d792e74645","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"6a0095c155a3618b2338d7252101ff16adaa020f511abdac410548b417aee11b","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null}
|
||||
2
third_party/rust/mp4parse_capi/Cargo.toml
vendored
2
third_party/rust/mp4parse_capi/Cargo.toml
vendored
@@ -78,7 +78,7 @@ log = "0.4"
|
||||
num-traits = "0.2.14"
|
||||
|
||||
[dependencies.fallible_collections]
|
||||
version = "0.4"
|
||||
version = "0.4.9"
|
||||
features = ["std_io"]
|
||||
|
||||
[dependencies.mp4parse]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use log::info;
|
||||
use mp4parse::ParseStrictness;
|
||||
use mp4parse_capi::*;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
|
||||
40
third_party/rust/mp4parse_capi/src/lib.rs
vendored
40
third_party/rust/mp4parse_capi/src/lib.rs
vendored
@@ -259,6 +259,7 @@ pub struct Mp4parseTrackVideoInfo {
|
||||
pub rotation: u16,
|
||||
pub sample_info_count: u32,
|
||||
pub sample_info: *const Mp4parseTrackVideoSampleInfo,
|
||||
pub pixel_aspect_ratio: f32,
|
||||
}
|
||||
|
||||
impl Default for Mp4parseTrackVideoInfo {
|
||||
@@ -269,6 +270,7 @@ impl Default for Mp4parseTrackVideoInfo {
|
||||
rotation: 0,
|
||||
sample_info_count: 0,
|
||||
sample_info: std::ptr::null(),
|
||||
pixel_aspect_ratio: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,7 +441,7 @@ pub struct Mp4parseIo {
|
||||
|
||||
impl Read for Mp4parseIo {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
if buf.len() > isize::max_value() as usize {
|
||||
if buf.len() > isize::MAX as usize {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"buf length overflow in Mp4parseIo Read impl",
|
||||
@@ -583,7 +585,7 @@ pub unsafe extern "C" fn mp4parse_get_track_count(
|
||||
let context = (*parser).context();
|
||||
|
||||
// Make sure the track count fits in a u32.
|
||||
if context.tracks.len() > u32::max_value() as usize {
|
||||
if context.tracks.len() > u32::MAX as usize {
|
||||
return Mp4parseStatus::Invalid;
|
||||
}
|
||||
*count = context.tracks.len() as u32;
|
||||
@@ -763,7 +765,7 @@ fn get_track_audio_info(
|
||||
|
||||
match audio.codec_specific {
|
||||
AudioCodecSpecific::ES_Descriptor(ref esds) => {
|
||||
if esds.codec_esds.len() > std::u32::MAX as usize {
|
||||
if esds.codec_esds.len() > u32::MAX as usize {
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
}
|
||||
sample_info.extra_data.length = esds.codec_esds.len();
|
||||
@@ -802,7 +804,7 @@ fn get_track_audio_info(
|
||||
Ok(_) => {
|
||||
opus_header.insert(track_index, v)?;
|
||||
if let Some(v) = opus_header.get(&track_index) {
|
||||
if v.len() > std::u32::MAX as usize {
|
||||
if v.len() > u32::MAX as usize {
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
}
|
||||
sample_info.codec_specific_config.length = v.len();
|
||||
@@ -849,7 +851,7 @@ fn get_track_audio_info(
|
||||
sample_info.protected_data.skip_byte_block =
|
||||
tenc.skip_byte_block_count.unwrap_or(0);
|
||||
if let Some(ref iv_vec) = tenc.constant_iv {
|
||||
if iv_vec.len() > std::u32::MAX as usize {
|
||||
if iv_vec.len() > u32::MAX as usize {
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
}
|
||||
sample_info.protected_data.constant_iv.set_data(iv_vec);
|
||||
@@ -864,7 +866,7 @@ fn get_track_audio_info(
|
||||
.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 {
|
||||
if sample_info.len() > u32::MAX as usize {
|
||||
// Should never happen due to upper limits on number of sample
|
||||
// descriptions a track can have, but lets be safe.
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
@@ -975,6 +977,9 @@ fn mp4parse_get_track_video_info_safe(
|
||||
};
|
||||
sample_info.image_width = video.width;
|
||||
sample_info.image_height = video.height;
|
||||
if let Some(ratio) = video.pixel_aspect_ratio {
|
||||
info.pixel_aspect_ratio = ratio;
|
||||
}
|
||||
|
||||
match video.codec_specific {
|
||||
VideoCodecSpecific::AV1Config(ref config) => {
|
||||
@@ -1017,7 +1022,7 @@ fn mp4parse_get_track_video_info_safe(
|
||||
sample_info.protected_data.skip_byte_block =
|
||||
tenc.skip_byte_block_count.unwrap_or(0);
|
||||
if let Some(ref iv_vec) = tenc.constant_iv {
|
||||
if iv_vec.len() > std::u32::MAX as usize {
|
||||
if iv_vec.len() > u32::MAX as usize {
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
}
|
||||
sample_info.protected_data.constant_iv.set_data(iv_vec);
|
||||
@@ -1032,7 +1037,7 @@ fn mp4parse_get_track_video_info_safe(
|
||||
.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 {
|
||||
if sample_info.len() > u32::MAX as usize {
|
||||
// Should never happen due to upper limits on number of sample
|
||||
// descriptions a track can have, but lets be safe.
|
||||
return Err(Mp4parseStatus::Invalid);
|
||||
@@ -1185,7 +1190,7 @@ fn mp4parse_avif_get_info_safe(context: &AvifContext) -> mp4parse::Result<Mp4par
|
||||
};
|
||||
|
||||
let (loop_mode, loop_count) = match color_track.tkhd.as_ref().map(|tkhd| tkhd.duration) {
|
||||
Some(movie_duration) if movie_duration == std::u64::MAX => {
|
||||
Some(movie_duration) if movie_duration == u64::MAX => {
|
||||
(Mp4parseAvifLoopMode::LoopInfinitely, 0)
|
||||
}
|
||||
Some(movie_duration) => match color_track.looped {
|
||||
@@ -1416,7 +1421,6 @@ fn get_indice_table(
|
||||
/// info raw pointers passed to it. Callers should ensure the parser
|
||||
/// pointer points to a valid `Mp4parseParser` and that the info pointer points
|
||||
/// to a valid `Mp4parseFragmentInfo`.
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mp4parse_get_fragment_info(
|
||||
parser: *mut Mp4parseParser,
|
||||
@@ -1618,13 +1622,7 @@ fn arg_validation() {
|
||||
mp4parse_get_track_info(std::ptr::null_mut(), 0, &mut dummy_info)
|
||||
);
|
||||
|
||||
let mut dummy_video = Mp4parseTrackVideoInfo {
|
||||
display_width: 0,
|
||||
display_height: 0,
|
||||
rotation: 0,
|
||||
sample_info_count: 0,
|
||||
sample_info: std::ptr::null(),
|
||||
};
|
||||
let mut dummy_video = Default::default();
|
||||
assert_eq!(
|
||||
Mp4parseStatus::BadArg,
|
||||
mp4parse_get_track_video_info(std::ptr::null_mut(), 0, &mut dummy_video)
|
||||
@@ -1686,13 +1684,7 @@ fn arg_validation_with_parser() {
|
||||
mp4parse_get_track_info(parser, 0, &mut dummy_info)
|
||||
);
|
||||
|
||||
let mut dummy_video = Mp4parseTrackVideoInfo {
|
||||
display_width: 0,
|
||||
display_height: 0,
|
||||
rotation: 0,
|
||||
sample_info_count: 0,
|
||||
sample_info: std::ptr::null(),
|
||||
};
|
||||
let mut dummy_video = Default::default();
|
||||
assert_eq!(
|
||||
Mp4parseStatus::BadArg,
|
||||
mp4parse_get_track_video_info(parser, 0, &mut dummy_video)
|
||||
|
||||
@@ -57,7 +57,7 @@ fn check_loop_count(path: &str, expected_loop_count: i64) {
|
||||
Mp4parseAvifLoopMode::LoopByCount => {
|
||||
assert_eq!(info.loop_count.to_i64(), Some(expected_loop_count))
|
||||
}
|
||||
Mp4parseAvifLoopMode::LoopInfinitely => assert_eq!(expected_loop_count, std::i64::MIN),
|
||||
Mp4parseAvifLoopMode::LoopInfinitely => assert_eq!(expected_loop_count, i64::MIN),
|
||||
}
|
||||
|
||||
unsafe { mp4parse_avif_free(parser) };
|
||||
@@ -95,7 +95,7 @@ fn loop_four_times_due_to_ceiling() {
|
||||
|
||||
#[test]
|
||||
fn loop_forever() {
|
||||
check_loop_count("tests/loop_forever.avif", std::i64::MIN);
|
||||
check_loop_count("tests/loop_forever.avif", i64::MIN);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -156,7 +156,7 @@ fn parse_sample_table_with_elst() {
|
||||
assert_eq!(track_info.track_type, Mp4parseTrackType::Audio);
|
||||
|
||||
// Check audio sample table
|
||||
let mut is_fragmented_file: u8 = std::u8::MAX;
|
||||
let mut is_fragmented_file: u8 = u8::MAX;
|
||||
rv = mp4parse_is_fragmented(parser, track_info.track_id, &mut is_fragmented_file);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(is_fragmented_file, 0);
|
||||
@@ -225,7 +225,7 @@ fn parse_sample_table_with_negative_ctts() {
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(track_info.track_type, Mp4parseTrackType::Video);
|
||||
|
||||
let mut is_fragmented_file: u8 = std::u8::MAX;
|
||||
let mut is_fragmented_file: u8 = u8::MAX;
|
||||
rv = mp4parse_is_fragmented(parser, track_info.track_id, &mut is_fragmented_file);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(is_fragmented_file, 0);
|
||||
|
||||
@@ -13,7 +13,7 @@ mozglue-static = { path = "../../../../mozglue/static/rust" }
|
||||
geckoservo = { path = "../../../../servo/ports/geckolib" }
|
||||
kvstore = { path = "../../../components/kvstore" }
|
||||
lmdb-rkv-sys = { version = "0.11", features = ["mdb_idl_logn_9"] }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "a138e40ec1c603615873e524b5b22e11c0ec4820", features = ["missing-pixi-permitted"] }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "e64650a686e5c5732395cd059e17cfd3b1e5b63b", features = ["missing-pixi-permitted"] }
|
||||
nserror = { path = "../../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring" }
|
||||
netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
|
||||
|
||||
Reference in New Issue
Block a user