1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-12-22 03:56:28 +00:00

Support profiles > 31 in DecoderSpecificDescriptor (#69)

This commit is contained in:
Alex 2022-03-25 23:02:50 -04:00 committed by GitHub
parent 49f9ed0432
commit 12ba304023
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 14 deletions

View file

@ -53,11 +53,11 @@ impl Mp4aBox {
impl Mp4Box for Mp4aBox {
fn box_type(&self) -> BoxType {
return self.get_type();
self.get_type()
}
fn box_size(&self) -> u64 {
return self.get_size();
self.get_size()
}
fn to_json(&self) -> Result<String> {
@ -159,8 +159,7 @@ impl Mp4Box for EsdsBox {
}
fn summary(&self) -> Result<String> {
let s = format!("");
Ok(s)
Ok(String::new())
}
}
@ -471,13 +470,45 @@ impl Descriptor for DecoderSpecificDescriptor {
}
}
fn get_audio_object_type(byte_a: u8, byte_b: u8) -> u8 {
let mut profile = byte_a >> 3;
if profile == 31 {
profile = 32 + ((byte_a & 7) | (byte_b >> 5));
}
profile
}
fn get_chan_conf<R: Read + Seek>(reader: &mut R, byte_b: u8, freq_index: u8, extended_profile: bool) -> Result<u8> {
let chan_conf;
if freq_index == 15 {
// Skip the 24 bit sample rate
let sample_rate = reader.read_u24::<BigEndian>()?;
chan_conf = ((sample_rate >> 4) & 0x0F) as u8;
} else if extended_profile {
let byte_c = reader.read_u8()?;
chan_conf = (byte_b & 1) | (byte_c & 0xE0);
} else {
chan_conf = (byte_b >> 3) & 0x0F;
}
Ok(chan_conf)
}
impl<R: Read + Seek> ReadDesc<&mut R> for DecoderSpecificDescriptor {
fn read_desc(reader: &mut R, _size: u32) -> Result<Self> {
let byte_a = reader.read_u8()?;
let byte_b = reader.read_u8()?;
let profile = byte_a >> 3;
let freq_index = ((byte_a & 0x07) << 1) + (byte_b >> 7);
let chan_conf = (byte_b >> 3) & 0x0F;
let profile = get_audio_object_type(byte_a, byte_b);
let freq_index;
let chan_conf;
if profile > 31 {
freq_index = (byte_b >> 1) & 0x0F;
chan_conf = get_chan_conf(reader, byte_b, freq_index, true)?;
} else {
freq_index = ((byte_a & 0x07) << 1) + (byte_b >> 7);
chan_conf = get_chan_conf(reader, byte_b, freq_index, false)?;
}
Ok(DecoderSpecificDescriptor {
profile,

View file

@ -1,16 +1,11 @@
use mp4::{AudioObjectType, AvcProfile, ChannelConfig, MediaType, SampleFreqIndex, TrackType};
use mp4::{AudioObjectType, AvcProfile, ChannelConfig, MediaType, Mp4Reader, SampleFreqIndex, TrackType};
use std::fs::File;
use std::io::BufReader;
use std::time::Duration;
#[test]
fn test_read_mp4() {
let filename = "tests/samples/minimal.mp4";
let f = File::open(filename).unwrap();
let size = f.metadata().unwrap().len();
let reader = BufReader::new(f);
let mut mp4 = mp4::Mp4Reader::read_header(reader, size).unwrap();
let mut mp4 = get_reader("tests/samples/minimal.mp4");
assert_eq!(2591, mp4.size());
@ -119,3 +114,31 @@ fn test_read_mp4() {
assert_eq!(track2.channel_config().unwrap(), ChannelConfig::Mono);
assert_eq!(track2.bitrate(), 67695);
}
#[test]
fn test_read_extended_audio_object_type() {
// Extended audio object type and sample rate index of 15
let mp4 = get_reader("tests/samples/extended_audio_object_type.mp4");
let track = mp4.tracks().get(&1).unwrap();
assert_eq!(track.track_type().unwrap(), TrackType::Audio);
assert_eq!(track.media_type().unwrap(), MediaType::AAC);
assert_eq!(
track.audio_profile().unwrap(),
AudioObjectType::AudioLosslessCoding
);
assert_eq!(
track.trak.mdia.minf.stbl.stsd.mp4a.as_ref().unwrap().esds.as_ref().unwrap().es_desc.dec_config.dec_specific.freq_index,
15
);
assert_eq!(track.channel_config().unwrap(), ChannelConfig::Stereo);
assert_eq!(track.bitrate(), 839250);
}
fn get_reader(path: &str) -> Mp4Reader<BufReader<File>> {
let f = File::open(path).unwrap();
let f_size = f.metadata().unwrap().len();
let reader = BufReader::new(f);
mp4::Mp4Reader::read_header(reader, f_size).unwrap()
}

Binary file not shown.