]> git.nihav.org Git - nihav.git/blobdiff - nihav-mpeg/src/codecs/aac/mod.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-mpeg / src / codecs / aac / mod.rs
index d4b776872bdd2549dced87725b4e9263bd2ef6fc..192b4e333b77a901d4fdafad757a0a5e179cea9d 100644 (file)
@@ -11,6 +11,7 @@ mod coeff_read;
 use coeff_read::*;
 mod info;
 use info::*;
+#[allow(clippy::needless_range_loop)]
 mod sbr;
 use sbr::{SBRHeader, SBRCodebooks, SBRState, SBRChannel, SBRDSP, sbr_read_sce, sbr_read_cpe};
 #[allow(clippy::excessive_precision)]
@@ -19,6 +20,9 @@ use tables::*;
 mod tools;
 use tools::*;
 
+mod packetiser;
+pub use packetiser::get_packetiser_adts;
+
 const MAX_WINDOWS:  usize = 8;
 const MAX_SFBS:     usize = 64;
 
@@ -183,6 +187,9 @@ impl ICS {
     fn get_intensity_dir(&self, g: usize, sfb: usize) -> bool {
         self.sfb_cb[g][sfb] == INTENSITY_HCB
     }
+    fn is_noise(&self, g: usize, sfb: usize) -> bool {
+        self.sfb_cb[g][sfb] == NOISE_HCB
+    }
     fn decode_scale_factor_data(&mut self, br: &mut BitReader, codebooks: &Codebooks) -> DecoderResult<()> {
         decode_scale_factor_data(br, &mut self.scales, self.global_gain, &self.info, &self.sfb_cb, codebooks)
     }
@@ -327,12 +334,14 @@ impl ChannelPair {
                         self.ms_used[g][sfb]            = br.read_bool()?;
                     }
                 }
+            } else {
+                self.ms_used = [[false; MAX_SFBS]; MAX_WINDOWS];
             }
             self.ics[1].info = self.ics[0].info;
         }
         self.ics[0].decode_ics(br, codebooks, m4atype, common_window, true)?;
         self.ics[1].decode_ics(br, codebooks, m4atype, common_window, true)?;
-        if common_window && self.ms_mask_present != 0 {
+        if common_window {
             let mut g = 0;
             for w in 0..self.ics[0].info.num_windows {
                 if w > 0 && !self.ics[0].info.scale_factor_grouping[w - 1] {
@@ -341,11 +350,11 @@ impl ChannelPair {
                 for sfb in 0..self.ics[0].info.max_sfb {
                     let start = w * 128 + self.ics[0].get_band_start(sfb);
                     let end   = w * 128 + self.ics[0].get_band_start(sfb + 1);
-                    if self.ics[0].is_intensity(g, sfb) {
+                    if self.ics[1].is_intensity(g, sfb) {
                         let invert = (self.ms_mask_present == 1) && self.ms_used[g][sfb];
-                        let dir = self.ics[0].get_intensity_dir(g, sfb) ^ invert;
-                        let scale = 0.5f32.powf(0.25 * (f32::from(self.ics[0].scales[g][sfb]) + f32::from(INTENSITY_SCALE_MIN)));
-                        if !dir {
+                        let dir = self.ics[1].get_intensity_dir(g, sfb) ^ invert;
+                        let scale = 0.5f32.powf(0.25 * (f32::from(self.ics[1].scales[g][sfb]) + f32::from(INTENSITY_SCALE_MIN)));
+                        if dir {
                             for i in start..end {
                                 self.ics[1].coeffs[i] = scale * self.ics[0].coeffs[i];
                             }
@@ -354,7 +363,7 @@ impl ChannelPair {
                                 self.ics[1].coeffs[i] = -scale * self.ics[0].coeffs[i];
                             }
                         }
-                    } else if (self.ms_mask_present == 2) || self.ms_used[g][sfb] {
+                    } else if ((self.ms_mask_present == 2) || self.ms_used[g][sfb]) && !self.ics[0].is_noise(g, sfb) {
                         for i in start..end {
                             let tmp = self.ics[0].coeffs[i] - self.ics[1].coeffs[i];
                             self.ics[0].coeffs[i] += self.ics[1].coeffs[i];
@@ -476,9 +485,7 @@ impl DSP {
                         self.ew_buf[w * 128 + i] += src[i] * short_win[i];
                     }
                 } else { // to be left-windowed
-                    for i in 0..128 {
-                        self.ew_buf[i] = src[i];
-                    }
+                    self.ew_buf[..128].copy_from_slice(&src[..128]);
                 }
                 for i in 0..128 {
                     self.ew_buf[w * 128 + i + 128] += src[i + 128] * short_win[127 - i];
@@ -500,55 +507,45 @@ impl DSP {
                     }
                 },
             EIGHT_SHORT_SEQUENCE => {
-                    for i in 0..SHORT_WIN_POINT0 {
-                        dst[i] = delay[i];
-                    }
+                    dst[..SHORT_WIN_POINT0].copy_from_slice(&delay[..SHORT_WIN_POINT0]);
                     for i in SHORT_WIN_POINT0..SHORT_WIN_POINT1 {
                         let j = i - SHORT_WIN_POINT0;
                         dst[i] = delay[i] + self.ew_buf[j] * left_short_win[j];
                     }
-                    for i in SHORT_WIN_POINT1..1024 {
-                        let j = i - SHORT_WIN_POINT0;
-                        dst[i] = self.ew_buf[j];
-                    }
+                    dst[SHORT_WIN_POINT1..1024].copy_from_slice(
+                        &self.ew_buf[SHORT_WIN_POINT1-SHORT_WIN_POINT0..1024-SHORT_WIN_POINT0]);
                 },
             LONG_STOP_SEQUENCE => {
-                    for i in 0..SHORT_WIN_POINT0 {
-                        dst[i] = delay[i];
-                    }
+                    dst[..SHORT_WIN_POINT0].copy_from_slice(&delay[..SHORT_WIN_POINT0]);
                     for i in SHORT_WIN_POINT0..SHORT_WIN_POINT1 {
                         dst[i] = delay[i] + self.tmp[i] * left_short_win[i - SHORT_WIN_POINT0];
                     }
-                    for i in SHORT_WIN_POINT1..1024 {
-                        dst[i] = self.tmp[i];
-                    }
+                    dst[SHORT_WIN_POINT1..1024].copy_from_slice(&self.tmp[SHORT_WIN_POINT1..1024]);
                 },
             _ => unreachable!(""),
         };
         // save delay
         match seq {
             ONLY_LONG_SEQUENCE | LONG_STOP_SEQUENCE => {
-                    for i in 0..1024 {
-                        delay[i] = self.tmp[i + 1024] * long_win[1023 - i];
+                    for (dst, (&src, &win)) in delay.iter_mut()
+                            .zip(self.tmp[1024..].iter().zip(long_win.iter().rev())) {
+                        *dst = src * win;
                     }
                 },
             EIGHT_SHORT_SEQUENCE => {
-                    for i in 0..SHORT_WIN_POINT1 { // last part is already windowed
-                        delay[i] = self.ew_buf[i + 512+64];
-                    }
-                    for i in SHORT_WIN_POINT1..1024 {
-                        delay[i] = 0.0;
+                    // last part is already windowed
+                    delay[..SHORT_WIN_POINT1].copy_from_slice(&self.ew_buf[512+64..][..SHORT_WIN_POINT1]);
+                    for el in delay[SHORT_WIN_POINT1..].iter_mut() {
+                        *el = 0.0;
                     }
                 },
             LONG_START_SEQUENCE   => {
-                    for i in 0..SHORT_WIN_POINT0 {
-                        delay[i] = self.tmp[i + 1024];
-                    }
+                    delay[..SHORT_WIN_POINT0].copy_from_slice(&self.tmp[1024..][..SHORT_WIN_POINT0]);
                     for i in SHORT_WIN_POINT0..SHORT_WIN_POINT1 {
                         delay[i] = self.tmp[i + 1024] * short_win[127 - (i - SHORT_WIN_POINT0)];
                     }
-                    for i in SHORT_WIN_POINT1..1024 {
-                        delay[i] = 0.0;
+                    for el in delay[SHORT_WIN_POINT1..].iter_mut() {
+                        *el = 0.0;
                     }
                 },
             _ => unreachable!(""),
@@ -625,8 +622,8 @@ impl AACDecoder {
                 4 => { // ID_DSE
                         let _id                         = br.read(4)?;
                         let align                       = br.read_bool()?;
-                        let mut count                   = br.read(8)? as u32;
-                        if count == 255 { count        += br.read(8)? as u32; }
+                        let mut count                   = br.read(8)?;
+                        if count == 255 { count        += br.read(8)?; }
                         if align {                        br.align(); }
                                                           br.skip(count * 8)?; // no SBR payload or such
                     },
@@ -813,6 +810,8 @@ mod test {
     use nihav_codec_support::test::dec_video::test_decode_audio;
     use crate::mpeg_register_all_decoders;
     use nihav_realmedia::realmedia_register_all_demuxers;
+    use std::io::Read;
+
     #[test]
     fn test_aac() {
         let mut dmx_reg = RegisteredDemuxers::new();
@@ -834,6 +833,24 @@ mod test {
         let file = "assets/MPEG/SBRtestStereoAot29Sig0.mp4";
         test_decode_audio("mov", file, Some(400), None/*Some("aacsbr")*/, &dmx_reg, &dec_reg);
     }
+    #[test]
+    fn test_adts_packetiser() {
+        let mut buf = [0; 4096];
+        // sample obtained with yt-dlp -f 234
+        let mut file = std::fs::File::open("assets/MPEG/Vf9Lvifxwk4.adts").unwrap();
+
+        let mut pkts = super::get_packetiser_adts();
+        file.read_exact(&mut buf).unwrap();
+        pkts.add_data(&buf);
+        let stream = pkts.parse_stream(0).unwrap();
+        let mut frame_sizes = Vec::with_capacity(15);
+        while let Some(pkt) = pkts.get_packet(stream.clone()).unwrap() {
+            let frame_size = pkt.get_buffer().len();
+            println!("pkt size {}", frame_size);
+            frame_sizes.push(frame_size);
+        }
+        assert_eq!(&frame_sizes, &[371, 372, 394, 402, 474, 400, 407, 399, 385]);
+    }
 }
 
 const DEFAULT_CHANNEL_MAP: [&str; 9] = [