From 9c3cd867ce7645f6f828675bd5d383033d6263f7 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 4 Jul 2022 18:23:34 +0200 Subject: [PATCH] aac: support Program Config Element a bit --- nihav-mpeg/src/codecs/aac/info.rs | 61 ++++++++++++++++++++++++++++++- nihav-mpeg/src/codecs/aac/mod.rs | 2 +- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/nihav-mpeg/src/codecs/aac/info.rs b/nihav-mpeg/src/codecs/aac/info.rs index e6e021b..648b356 100644 --- a/nihav-mpeg/src/codecs/aac/info.rs +++ b/nihav-mpeg/src/codecs/aac/info.rs @@ -168,7 +168,11 @@ impl M4AInfo { } let extension_flag = br.read_bool()?; if self.channels == 0 { - unimplemented!("program config element"); + let (channels, sf_code) = skimp_through_program_config_element(&mut br)?; + validate!(channels > 0); + self.channels = channels; + validate!(AAC_SAMPLE_RATES[sf_code] != 0); + self.srate = AAC_SAMPLE_RATES[sf_code]; } if (self.otype == M4AType::Scalable) || (self.otype == M4AType::ER_AAC_Scalable) { let _layer = br.read(3)?; @@ -260,6 +264,61 @@ impl M4AInfo { } } +pub fn skimp_through_program_config_element(br: &mut BitReader) -> DecoderResult<(usize, usize)> { + let _id = br.read(4)?; + let _object_type = br.read(2)?; + let sampling_frequency_index = br.read(4)? as usize; + let num_front_channel_elements = br.read(4)? as usize; + let num_side_channel_elements = br.read(4)? as usize; + let num_back_channel_elements = br.read(4)? as usize; + let num_lfe_channel_elements = br.read(2)? as usize; + let num_assoc_data_elements = br.read(3)? as usize; + let num_valid_cc_elements = br.read(4)? as usize; + let mono_mixdown_present = br.read_bool()?; + if mono_mixdown_present { + let _mono_mixdown_element_number = br.read(4)?; + } + let stereo_mixdown_present = br.read_bool()?; + if stereo_mixdown_present { + let _stereo_mixdown_element_number = br.read(4)?; + } + let matrix_mixdown_idx_present = br.read_bool()?; + if matrix_mixdown_idx_present { + let _matrix_mixdown_idx = br.read(2)?; + let _pseudo_surround_enable = br.read_bool()?; + } + for _i in 0..num_front_channel_elements { + let _front_element_is_cpe = br.read_bool()?; + let _front_element_tag_select = br.read(4)?; + } + for _i in 0..num_side_channel_elements { + let _side_element_is_cpe = br.read_bool()?; + let _side_element_tag_select = br.read(4)?; + } + for _i in 0..num_back_channel_elements { + let _back_element_is_cpe = br.read_bool()?; + let _back_element_tag_select = br.read(4)?; + } + for _i in 0..num_lfe_channel_elements { + let _lfe_element_tag_select = br.read(4)?; + } + for _i in 0..num_assoc_data_elements { + let _assoc_data_element_tag_select = br.read(4)?; + } + for _i in 0..num_valid_cc_elements { + let _cc_element_is_ind_sw = br.read_bool()?; + let _valid_cc_element_tag_select = br.read(4)?; + } + br.align(); + let comment_field_bytes = br.read(8)?; + br.skip(comment_field_bytes * 8)?; + + Ok((num_front_channel_elements + + num_side_channel_elements + + num_back_channel_elements + + num_lfe_channel_elements, sampling_frequency_index)) +} + impl fmt::Display for M4AInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "MPEG 4 Audio {}, {} Hz, {} channels, {} samples per frame", diff --git a/nihav-mpeg/src/codecs/aac/mod.rs b/nihav-mpeg/src/codecs/aac/mod.rs index 795464b..de9fbe5 100644 --- a/nihav-mpeg/src/codecs/aac/mod.rs +++ b/nihav-mpeg/src/codecs/aac/mod.rs @@ -570,7 +570,7 @@ impl AACDecoder { br.skip(count * 8)?; // no SBR payload or such }, 5 => { // ID_PCE - unimplemented!("program config"); + skimp_through_program_config_element(br)?; }, 6 => { // ID_FIL let mut count = br.read(4)? as usize; -- 2.30.2