mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1695464
- Update mp4parse-rust to ccbe4eb. r=bryce,kinetik
Differential Revision: https://phabricator.services.mozilla.com/D106727
This commit is contained in:
parent
cd5708a26d
commit
4d56684865
@ -30,7 +30,7 @@ tag = "v0.4.21"
|
||||
[source."https://github.com/mozilla/mp4parse-rust"]
|
||||
git = "https://github.com/mozilla/mp4parse-rust"
|
||||
replace-with = "vendored-sources"
|
||||
rev = "3011a2b923c8b0f1b392bcdd008cd8b95ffd846b"
|
||||
rev = "ccbe4eb8a96d64e58414ec70d2479c7f363e6763"
|
||||
|
||||
[source."https://github.com/mozilla/cubeb-pulse-rs"]
|
||||
git = "https://github.com/mozilla/cubeb-pulse-rs"
|
||||
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -3316,7 +3316,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mp4parse"
|
||||
version = "0.11.5"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=3011a2b923c8b0f1b392bcdd008cd8b95ffd846b#3011a2b923c8b0f1b392bcdd008cd8b95ffd846b"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=ccbe4eb8a96d64e58414ec70d2479c7f363e6763#ccbe4eb8a96d64e58414ec70d2479c7f363e6763"
|
||||
dependencies = [
|
||||
"bitreader",
|
||||
"byteorder",
|
||||
@ -3335,7 +3335,7 @@ version = "0.1.0"
|
||||
[[package]]
|
||||
name = "mp4parse_capi"
|
||||
version = "0.11.5"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=3011a2b923c8b0f1b392bcdd008cd8b95ffd846b#3011a2b923c8b0f1b392bcdd008cd8b95ffd846b"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=ccbe4eb8a96d64e58414ec70d2479c7f363e6763#ccbe4eb8a96d64e58414ec70d2479c7f363e6763"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fallible_collections",
|
||||
|
@ -306,6 +306,9 @@ MP4Metadata::ResultAndTrackInfo MP4Metadata::GetTrackInfo(
|
||||
case MP4PARSE_CODEC_ALAC:
|
||||
codecString = "alac";
|
||||
break;
|
||||
case MP4PARSE_CODEC_H263:
|
||||
codecString = "h.263";
|
||||
break;
|
||||
case MP4PARSE_CODEC_AVC:
|
||||
codecString = "h.264";
|
||||
break;
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"20d60a51a713582d285ab994d13014f101450a359f5ada589b82ea97615ae2e8","benches/avif_benchmark.rs":"e4bdd69c7b434448ef7080bbf488b2f64c2c88121fe1c1f7e9d9c8def3d648ae","src/boxes.rs":"756a3d3638d91fc8e2e58a3e41e663b46d6381539ec12b2e7b6980b205ef4ed2","src/lib.rs":"5cc2731dff15507d7b9a3c2e88ea1682dc40ca75901b69f35c9a6e71898c323b","src/macros.rs":"76c840f9299797527fe71aa5b378ffb01312767372b45cc62deddb19775400ae","src/tests.rs":"7598fba59c47dc0f713c5a71fa477d046b595ba6362c6e32d775e33197770055","tests/bug-1661347.avif":"a4741189d897401c746492d780bccf4c42dddde8f46d01a791f9656aac2ab164","tests/corrupt/bad-ipma-flags.avif":"ecde7997b97db1910b9dcc7ca8e3c8957da0e83681ea9008c66dc9f12b78ad19","tests/corrupt/bad-ipma-version.avif":"7f9a1a0b4ebbf8d800d22eaae5ff78970cc6b811317db6c1467c6883952b7c9b","tests/corrupt/bug-1655846.avif":"e0a5a06225800fadf05f5352503a4cec11af73eef705c43b4acab5f4a99dea50","tests/corrupt/bug-1661347.avif":"31c26561e1d9eafb60f7c5968b82a0859d203d73f17f26b29276256acee12966","tests/kodim-extents.avif":"e4de6d124535206c3daca797e64cccc6a5b439f93733af52a95b1e82d581a78b","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"bee907c7183040b3a2842312d13e20ac005e880d33d2b2c9067d5a48db3d6514"},"package":null}
|
||||
{"files":{"Cargo.toml":"20d60a51a713582d285ab994d13014f101450a359f5ada589b82ea97615ae2e8","benches/avif_benchmark.rs":"e4bdd69c7b434448ef7080bbf488b2f64c2c88121fe1c1f7e9d9c8def3d648ae","src/boxes.rs":"f6e44b9ce634817a3ab46ba991747b92b228d404d0c3396b9f52eeb6087d87ab","src/lib.rs":"7724b3224ae56135eed3c41c42a7fa06659da127e61f9baedbf62452d2125214","src/macros.rs":"76c840f9299797527fe71aa5b378ffb01312767372b45cc62deddb19775400ae","src/tests.rs":"7598fba59c47dc0f713c5a71fa477d046b595ba6362c6e32d775e33197770055","tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp":"03e5b1264d0a188d77b9e676ba3ce23a801b17aaa11c0343dfd851d6ea4e3a40","tests/bug-1661347.avif":"a4741189d897401c746492d780bccf4c42dddde8f46d01a791f9656aac2ab164","tests/corrupt/bad-ipma-flags.avif":"ecde7997b97db1910b9dcc7ca8e3c8957da0e83681ea9008c66dc9f12b78ad19","tests/corrupt/bad-ipma-version.avif":"7f9a1a0b4ebbf8d800d22eaae5ff78970cc6b811317db6c1467c6883952b7c9b","tests/corrupt/bug-1655846.avif":"e0a5a06225800fadf05f5352503a4cec11af73eef705c43b4acab5f4a99dea50","tests/corrupt/bug-1661347.avif":"31c26561e1d9eafb60f7c5968b82a0859d203d73f17f26b29276256acee12966","tests/kodim-extents.avif":"e4de6d124535206c3daca797e64cccc6a5b439f93733af52a95b1e82d581a78b","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"07d4a2a0b94007b85b8e581c3d3f0e49e1598980a502dd2577e4da600c9275fa"},"package":null}
|
2
third_party/rust/mp4parse/src/boxes.rs
vendored
2
third_party/rust/mp4parse/src/boxes.rs
vendored
@ -133,6 +133,8 @@ box_database!(
|
||||
AVCSampleEntry 0x6176_6331, // "avc1"
|
||||
AVC3SampleEntry 0x6176_6333, // "avc3" - Need to check official name in spec.
|
||||
AVCConfigurationBox 0x6176_6343, // "avcC"
|
||||
H263SampleEntry 0x7332_3633, // "s263"
|
||||
H263SpecificBox 0x6432_3633, // "d263"
|
||||
MP4AudioSampleEntry 0x6d70_3461, // "mp4a"
|
||||
MP4VideoSampleEntry 0x6d70_3476, // "mp4v"
|
||||
ESDBox 0x6573_6473, // "esds"
|
||||
|
49
third_party/rust/mp4parse/src/lib.rs
vendored
49
third_party/rust/mp4parse/src/lib.rs
vendored
@ -418,6 +418,7 @@ pub enum VideoCodecSpecific {
|
||||
VPxConfig(VPxConfigBox),
|
||||
AV1Config(AV1ConfigBox),
|
||||
ESDSConfig(TryVec<u8>),
|
||||
H263Config(TryVec<u8>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -470,7 +471,18 @@ pub struct AV1ConfigBox {
|
||||
pub chroma_sample_position: u8,
|
||||
pub initial_presentation_delay_present: bool,
|
||||
pub initial_presentation_delay_minus_one: u8,
|
||||
pub config_obus: TryVec<u8>,
|
||||
// The raw config contained in the av1c box. Because some decoders accept this data as a binary
|
||||
// blob, rather than as structured data, we store the blob here for convenience.
|
||||
pub raw_config: TryVec<u8>,
|
||||
}
|
||||
|
||||
impl AV1ConfigBox {
|
||||
/// See https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax
|
||||
const CONFIG_OBUS_OFFSET: usize = 4;
|
||||
|
||||
pub fn config_obus(&self) -> &[u8] {
|
||||
&self.raw_config[Self::CONFIG_OBUS_OFFSET..]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1111,6 +1123,7 @@ pub enum CodecType {
|
||||
EncryptedAudio,
|
||||
LPCM, // QT
|
||||
ALAC,
|
||||
H263,
|
||||
}
|
||||
|
||||
impl Default for CodecType {
|
||||
@ -3015,17 +3028,21 @@ fn read_vpcc<T: Read>(src: &mut BMFFBox<T>) -> Result<VPxConfigBox> {
|
||||
}
|
||||
|
||||
fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
|
||||
let marker_byte = src.read_u8()?;
|
||||
// We want to store the raw config as well as a structured (parsed) config, so create a copy of
|
||||
// the raw config so we have it later, and then parse the structured data from that.
|
||||
let raw_config = src.read_into_try_vec()?;
|
||||
let mut raw_config_slice = raw_config.as_slice();
|
||||
let marker_byte = raw_config_slice.read_u8()?;
|
||||
if marker_byte & 0x80 != 0x80 {
|
||||
return Err(Error::Unsupported("missing av1C marker bit"));
|
||||
}
|
||||
if marker_byte & 0x7f != 0x01 {
|
||||
return Err(Error::Unsupported("missing av1C marker bit"));
|
||||
}
|
||||
let profile_byte = src.read_u8()?;
|
||||
let profile_byte = raw_config_slice.read_u8()?;
|
||||
let profile = (profile_byte & 0xe0) >> 5;
|
||||
let level = profile_byte & 0x1f;
|
||||
let flags_byte = src.read_u8()?;
|
||||
let flags_byte = raw_config_slice.read_u8()?;
|
||||
let tier = (flags_byte & 0x80) >> 7;
|
||||
let bit_depth = match flags_byte & 0x60 {
|
||||
0x60 => 12,
|
||||
@ -3036,7 +3053,7 @@ fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
|
||||
let chroma_subsampling_x = (flags_byte & 0x08) >> 3;
|
||||
let chroma_subsampling_y = (flags_byte & 0x04) >> 2;
|
||||
let chroma_sample_position = flags_byte & 0x03;
|
||||
let delay_byte = src.read_u8()?;
|
||||
let delay_byte = raw_config_slice.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
|
||||
@ -3044,9 +3061,6 @@ fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
|
||||
0
|
||||
};
|
||||
|
||||
let config_obus_size = src.bytes_left();
|
||||
let config_obus = read_buf(src, config_obus_size)?;
|
||||
|
||||
Ok(AV1ConfigBox {
|
||||
profile,
|
||||
level,
|
||||
@ -3058,7 +3072,7 @@ fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
|
||||
chroma_sample_position,
|
||||
initial_presentation_delay_present,
|
||||
initial_presentation_delay_minus_one,
|
||||
config_obus,
|
||||
raw_config,
|
||||
})
|
||||
}
|
||||
|
||||
@ -3550,6 +3564,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
BoxType::VP9SampleEntry => CodecType::VP9,
|
||||
BoxType::AV1SampleEntry => CodecType::AV1,
|
||||
BoxType::ProtectedVisualSampleEntry => CodecType::EncryptedVideo,
|
||||
BoxType::H263SampleEntry => CodecType::H263,
|
||||
_ => {
|
||||
debug!("Unsupported video codec, box {:?} found", name);
|
||||
CodecType::Unknown
|
||||
@ -3594,6 +3609,20 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
// TODO(kinetik): Parse avcC box? For now we just stash the data.
|
||||
codec_specific = Some(VideoCodecSpecific::AVCConfig(avcc));
|
||||
}
|
||||
BoxType::H263SpecificBox => {
|
||||
if (name != BoxType::H263SampleEntry) || codec_specific.is_some() {
|
||||
return Err(Error::InvalidData("malformed video sample entry"));
|
||||
}
|
||||
let h263_dec_spec_struc_size = b
|
||||
.head
|
||||
.size
|
||||
.checked_sub(b.head.offset)
|
||||
.expect("offset invalid");
|
||||
let h263_dec_spec_struc = read_buf(&mut b.content, h263_dec_spec_struc_size)?;
|
||||
debug!("{:?} (h263DecSpecStruc)", h263_dec_spec_struc);
|
||||
|
||||
codec_specific = Some(VideoCodecSpecific::H263Config(h263_dec_spec_struc));
|
||||
}
|
||||
BoxType::VPCodecConfigurationBox => {
|
||||
// vpcC
|
||||
if (name != BoxType::VP8SampleEntry
|
||||
@ -3607,7 +3636,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
codec_specific = Some(VideoCodecSpecific::VPxConfig(vpcc));
|
||||
}
|
||||
BoxType::AV1CodecConfigurationBox => {
|
||||
if name != BoxType::AV1SampleEntry {
|
||||
if name != BoxType::AV1SampleEntry && name != BoxType::ProtectedVisualSampleEntry {
|
||||
return Err(Error::InvalidData("malformed video sample entry"));
|
||||
}
|
||||
let av1c = read_av1c(&mut b)?;
|
||||
|
BIN
third_party/rust/mp4parse/tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp
vendored
Normal file
BIN
third_party/rust/mp4parse/tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp
vendored
Normal file
Binary file not shown.
32
third_party/rust/mp4parse/tests/public.rs
vendored
32
third_party/rust/mp4parse/tests/public.rs
vendored
@ -41,6 +41,9 @@ static IMAGE_AVIF_CORRUPT_4: &str = "tests/corrupt/bad-ipma-flags.avif";
|
||||
static IMAGE_AVIF_GRID: &str = "av1-avif/testFiles/Microsoft/Summer_in_Tomsk_720p_5x4_grid.avif";
|
||||
static AVIF_TEST_DIRS: &[&str] = &["tests", "av1-avif/testFiles"];
|
||||
static AVIF_CORRUPT_IMAGES: &str = "tests/corrupt";
|
||||
// The 1 frame h263 3gp file can be generated by ffmpeg with command
|
||||
// "ffmpeg -i [input file] -f 3gp -vcodec h263 -vf scale=176x144 -frames:v 1 -an output.3gp"
|
||||
static VIDEO_H263_3GP: &str = "tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp";
|
||||
|
||||
// Adapted from https://github.com/GuillaumeGomez/audio-video-metadata/blob/9dff40f565af71d5502e03a2e78ae63df95cfd40/src/metadata.rs#L53
|
||||
#[test]
|
||||
@ -97,6 +100,9 @@ fn public_api() {
|
||||
mp4::VideoCodecSpecific::AV1Config(ref _av1c) => {
|
||||
"AV1"
|
||||
}
|
||||
mp4::VideoCodecSpecific::H263Config(ref _h263) => {
|
||||
"H263"
|
||||
}
|
||||
},
|
||||
"AVC"
|
||||
);
|
||||
@ -765,3 +771,29 @@ fn public_avif_read_samples() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_video_h263() {
|
||||
let mut fd = File::open(VIDEO_H263_3GP).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::H263);
|
||||
assert_eq!(v.width, 176);
|
||||
assert_eq!(v.height, 144);
|
||||
let _codec_specific = match v.codec_specific {
|
||||
mp4::VideoCodecSpecific::H263Config(_) => true,
|
||||
_ => {
|
||||
panic!("expected a H263Config",);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"9f188cfbdda3daf4dc36638f136f3640c21cad5eef8df60f66826f06cf2cc0e0","cbindgen.toml":"5c9429f271d6e914d81b63e6509c04ffe84cab11ed3a53a2ed4715e5d5ace80e","examples/dump.rs":"83462422315c22e496960bae922edb23105c0aa272d2b106edd7574ff068513a","src/lib.rs":"d25c2e010186ada3524801e8f1ecdbe42cc4f961880ccca11ba9bdddd42363f7","tests/test_chunk_out_of_range.rs":"b5da583218d98027ed973a29c67434a91a1306f2d2fb39ec4d640d4824c308ce","tests/test_encryption.rs":"f1b4dc5a726f067f6a6049ec43bc93733131e7e25b0d7344251e1fdd02dcbbcd","tests/test_fragment.rs":"e90eb5a4418d30002655466c0c4b3125c7fd70a74b6871471eaa172f1def9db8","tests/test_rotation.rs":"fb43c2f2dfa496d151c33bdd46c0fd3252387c23cc71e2cac9ed0234de715a81","tests/test_sample_table.rs":"185755909b2f4e0ea99604bb423a07623d614a180accdaebd1c98aef2c2e3ae6","tests/test_workaround_stsc.rs":"7dd419f3d55b9a3a039cac57e58a9240a9c8166bcd4356c24f69f731c3ced83b"},"package":null}
|
||||
{"files":{"Cargo.toml":"9f188cfbdda3daf4dc36638f136f3640c21cad5eef8df60f66826f06cf2cc0e0","cbindgen.toml":"5c9429f271d6e914d81b63e6509c04ffe84cab11ed3a53a2ed4715e5d5ace80e","examples/dump.rs":"04db9535bcdd36b0d1371a6b99d573128bf457444a41b06a8acb8b5402127c1e","src/lib.rs":"6bae865477eae9b12300f53627844fa7d63bf50b94858a378f3622f7cc753c4e","tests/test_chunk_out_of_range.rs":"b5da583218d98027ed973a29c67434a91a1306f2d2fb39ec4d640d4824c308ce","tests/test_encryption.rs":"77c71a954ca3f54120b852641dc699994d6024aa13a955450fa4cf913a88b7b4","tests/test_fragment.rs":"e90eb5a4418d30002655466c0c4b3125c7fd70a74b6871471eaa172f1def9db8","tests/test_rotation.rs":"fb43c2f2dfa496d151c33bdd46c0fd3252387c23cc71e2cac9ed0234de715a81","tests/test_sample_table.rs":"185755909b2f4e0ea99604bb423a07623d614a180accdaebd1c98aef2c2e3ae6","tests/test_workaround_stsc.rs":"7dd419f3d55b9a3a039cac57e58a9240a9c8166bcd4356c24f69f731c3ced83b"},"package":null}
|
18
third_party/rust/mp4parse_capi/examples/dump.rs
vendored
18
third_party/rust/mp4parse_capi/examples/dump.rs
vendored
@ -20,6 +20,20 @@ extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_avif(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,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let mut parser = std::ptr::null_mut();
|
||||
let rv = mp4parse_avif_new(&io, &mut parser);
|
||||
println!("mp4parse_avif_new -> {:?}", rv);
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_file(filename: &str) {
|
||||
let mut file = File::open(filename).expect("Unknown file");
|
||||
let io = Mp4parseIo {
|
||||
@ -33,6 +47,10 @@ fn dump_file(filename: &str) {
|
||||
|
||||
match rv {
|
||||
Mp4parseStatus::Ok => (),
|
||||
Mp4parseStatus::Invalid => {
|
||||
println!("-- failed to parse as mp4 video, trying AVIF");
|
||||
dump_avif(filename);
|
||||
}
|
||||
_ => {
|
||||
println!("-- fail to parse: {:?}, '-v' for more info", rv);
|
||||
return;
|
||||
|
15
third_party/rust/mp4parse_capi/src/lib.rs
vendored
15
third_party/rust/mp4parse_capi/src/lib.rs
vendored
@ -51,8 +51,6 @@ use std::ops::Neg;
|
||||
use std::ops::{Add, Sub};
|
||||
|
||||
// Symbols we need from our rust api.
|
||||
use mp4parse::read_avif;
|
||||
use mp4parse::read_mp4;
|
||||
use mp4parse::serialize_opus_header;
|
||||
use mp4parse::AudioCodecSpecific;
|
||||
use mp4parse::AvifContext;
|
||||
@ -125,6 +123,7 @@ pub enum Mp4parseCodec {
|
||||
Ac3,
|
||||
Ec3,
|
||||
Alac,
|
||||
H263,
|
||||
}
|
||||
|
||||
impl Default for Mp4parseCodec {
|
||||
@ -479,7 +478,9 @@ impl ContextParser for Mp4parseParser {
|
||||
}
|
||||
|
||||
fn read<T: Read>(io: &mut T) -> mp4parse::Result<Self::Context> {
|
||||
read_mp4(io)
|
||||
let r = mp4parse::read_mp4(io);
|
||||
log::debug!("mp4parse::read_mp4 -> {:?}", r);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,7 +502,9 @@ impl ContextParser for Mp4parseAvifParser {
|
||||
}
|
||||
|
||||
fn read<T: Read>(io: &mut T) -> mp4parse::Result<Self::Context> {
|
||||
read_avif(io)
|
||||
let r = mp4parse::read_avif(io);
|
||||
log::debug!("mp4parse::read_avif -> {:?}", r);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
@ -1103,6 +1106,7 @@ fn mp4parse_get_track_video_info_safe(
|
||||
VideoCodecSpecific::VPxConfig(_) => Mp4parseCodec::Vp9,
|
||||
VideoCodecSpecific::AV1Config(_) => Mp4parseCodec::Av1,
|
||||
VideoCodecSpecific::AVCConfig(_) => Mp4parseCodec::Avc,
|
||||
VideoCodecSpecific::H263Config(_) => Mp4parseCodec::H263,
|
||||
VideoCodecSpecific::ESDSConfig(_) =>
|
||||
// MP4V (14496-2) video is unsupported.
|
||||
{
|
||||
@ -1113,6 +1117,9 @@ fn mp4parse_get_track_video_info_safe(
|
||||
sample_info.image_height = video.height;
|
||||
|
||||
match video.codec_specific {
|
||||
VideoCodecSpecific::AV1Config(ref config) => {
|
||||
sample_info.extra_data.set_data(&config.raw_config);
|
||||
}
|
||||
VideoCodecSpecific::AVCConfig(ref data) | VideoCodecSpecific::ESDSConfig(ref data) => {
|
||||
sample_info.extra_data.set_data(data);
|
||||
}
|
||||
|
@ -210,3 +210,87 @@ fn parse_unencrypted() {
|
||||
assert_eq!(protected_data.constant_iv.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_encrypted_av1() {
|
||||
// For reference, this file was created from the av1.mp4 in mozilla's media tests using
|
||||
// shaka-packager. The following command was used to produce the file:
|
||||
// ```
|
||||
// packager-win.exe in=av1.mp4,stream=video,output=av1-clearkey-cbcs-video.mp4
|
||||
// --protection_scheme cbcs --enable_raw_key_encryption
|
||||
// --keys label=:key_id=00112233445566778899AABBCCDDEEFF:key=00112233445566778899AABBCCDDEEFF
|
||||
// --iv 11223344556677889900112233445566
|
||||
// ```
|
||||
let mut file = std::fs::File::open("tests/av1-clearkey-cbcs-video.mp4").expect("Unknown file");
|
||||
let io = Mp4parseIo {
|
||||
read: Some(buf_read),
|
||||
userdata: &mut file as *mut _ as *mut std::os::raw::c_void,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let mut parser = std::ptr::null_mut();
|
||||
let mut rv = mp4parse_new(&io, &mut parser);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert!(!parser.is_null());
|
||||
let mut counts: u32 = 0;
|
||||
rv = mp4parse_get_track_count(parser, &mut counts);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(counts, 1);
|
||||
|
||||
// Make sure we have a video track
|
||||
let mut video_track_info = Mp4parseTrackInfo::default();
|
||||
rv = mp4parse_get_track_info(parser, 0, &mut video_track_info);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(video_track_info.track_type, Mp4parseTrackType::Video);
|
||||
|
||||
// Verify video track and crypto information
|
||||
let mut video = Mp4parseTrackVideoInfo::default();
|
||||
rv = mp4parse_get_track_video_info(parser, 0, &mut video);
|
||||
assert_eq!(rv, Mp4parseStatus::Ok);
|
||||
assert_eq!(video.sample_info_count, 2);
|
||||
assert_eq!((*video.sample_info).codec_type, Mp4parseCodec::Av1);
|
||||
assert_eq!((*video.sample_info).image_width, 160);
|
||||
assert_eq!((*video.sample_info).image_height, 90);
|
||||
|
||||
// Check that extra data binary blob.
|
||||
let expected_extra_data = [
|
||||
0x81, 0x00, 0x0c, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x03, 0xb4, 0xfd, 0x97, 0xff,
|
||||
0xe6, 0x01,
|
||||
];
|
||||
let extra_data = &(*video.sample_info).extra_data;
|
||||
assert_eq!(extra_data.length, 16);
|
||||
for (i, expected_byte) in expected_extra_data.iter().enumerate() {
|
||||
assert_eq!(&(*extra_data.data.add(i)), expected_byte);
|
||||
}
|
||||
|
||||
let protected_data = &(*video.sample_info).protected_data;
|
||||
assert_eq!(
|
||||
protected_data.original_format,
|
||||
OptionalFourCC::Some(*b"av01")
|
||||
);
|
||||
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 = [
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
|
||||
0xee, 0xff,
|
||||
];
|
||||
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,
|
||||
];
|
||||
for (i, expected_byte) in expected_iv.iter().enumerate() {
|
||||
assert_eq!(&(*protected_data.constant_iv.data.add(i)), expected_byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ description = "Shared Rust code for libxul"
|
||||
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 = "3011a2b923c8b0f1b392bcdd008cd8b95ffd846b" }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "ccbe4eb8a96d64e58414ec70d2479c7f363e6763" }
|
||||
nserror = { path = "../../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring" }
|
||||
netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
|
||||
|
Loading…
Reference in New Issue
Block a user