Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept M4A files with invalid dependsOnCoreCoder flag in GASpecificConfig. #320

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions mp4parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3697,7 +3697,7 @@ fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
read_dc_descriptor(descriptor, esds)?;
}
DECODER_SPECIFIC_TAG => {
read_ds_descriptor(descriptor, esds)?;
read_ds_descriptor(descriptor, esds, ParseStrictness::Permissive)?;
}
_ => {
debug!("Unsupported descriptor, tag {}", tag);
Expand All @@ -3723,7 +3723,11 @@ fn get_audio_object_type(bit_reader: &mut BitReader) -> Result<u16> {
}

/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.7 and probably 14496-3 somewhere?
fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
fn read_ds_descriptor(
data: &[u8],
esds: &mut ES_Descriptor,
strictness: ParseStrictness,
) -> Result<()> {
#[cfg(feature = "mp4v")]
// Check if we are in a Visual esda Box.
if esds.video_codec != CodecType::Unknown {
Expand Down Expand Up @@ -3823,9 +3827,18 @@ fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
};

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
let depends_on_core_coder: u8 = ReadInto::read(bit_reader, 1)?;
if depends_on_core_coder > 0 {
if bit_reader.remaining() < 14 {
fail_if(
strictness != ParseStrictness::Permissive,
"The GASpecificConfig 'coreCoderDelay' field shall be present \
if 'dependsOnCoreCoder' is set per MPEG-4 Audio (ISO 14496-3:2019) § 4.4.1",
)?;
debug!("Insufficient bits for coreCoderDelay, ignoring dependsOnCoreCoder");
} else {
bit_reader.skip(14)?; // coreCoderDelay
}
}
bit_reader.skip(1)?; // extensionFlag

Expand Down
24 changes: 24 additions & 0 deletions mp4parse/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,30 @@ fn read_esds_invalid_descriptor() {
}
}

#[test]
fn read_esds_depends_on_core_coder_invalid() {
// dependsOnCoreCoder flag is set, but coreCoderDelay bits are not present.
// Extracted from BMO #1709329 audio-stripped.m4a using Bento4.
// "mp4extract --payload-only moov/trak/mdia/minf/stbl/stsd/mp4a/esds audio-stripped.m4a /dev/stdout | xxd -i -c 15"
let esds = vec![
0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x01, 0x00, 0x04, 0x80, 0x80, 0x80, 0x14, 0x40, 0x15,
0x00, 0x02, 0x15, 0x00, 0x02, 0x04, 0x88, 0x00, 0x01, 0xea, 0x64, 0x05, 0x80, 0x80, 0x80,
0x02, 0x12, 0x12, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02,
];

let mut stream = make_box(BoxSize::Auto, b"esds", |s| {
s.B32(0) // reserved
.append_bytes(esds.as_slice())
});
let mut iter = super::BoxIter::new(&mut stream);
let mut stream = iter.next_box().unwrap().unwrap();

match super::read_esds(&mut stream) {
Ok(esds) => assert_eq!(esds.audio_codec, super::CodecType::AAC),
_ => panic!("unexpected result with invalid descriptor"),
}
}

#[test]
fn read_esds_redundant_descriptor() {
// the '2' at the end is redundant data.
Expand Down