]> git.nihav.org Git - nihav.git/commitdiff
aac: support Program Config Element a bit
authorKostya Shishkov <kostya.shishkov@gmail.com>
Mon, 4 Jul 2022 16:23:34 +0000 (18:23 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Mon, 4 Jul 2022 16:23:34 +0000 (18:23 +0200)
nihav-mpeg/src/codecs/aac/info.rs
nihav-mpeg/src/codecs/aac/mod.rs

index e6e021b3761c793253555ac5dc3da667eda20679..648b3562d47d4895f75164d7c4b78ef9ba8f351f 100644 (file)
@@ -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",
index 795464b2582d4a796760844cb21c3ec843438035..de9fbe5e1882f901d8b917bc43545c89870bba83 100644 (file)
@@ -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;