improve audio conversion
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 25 May 2023 15:46:15 +0000 (17:46 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 25 May 2023 15:46:15 +0000 (17:46 +0200)
src/acvt.rs
src/main.rs

index 5343039d1fb62e8fc8249ebf77d88660fe8cdd81..349e10b383a32f5a8e0dc5eab1e0a1e9bf7608f2 100644 (file)
@@ -39,11 +39,18 @@ impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
 
                 let old_len = self.get_cur_size();
                 let new_len = src.get_length();
-                for (dst, (old, new)) in new_buf.chunks_exact_mut(new_stride).zip(
-                        self.data.chunks_exact(self.stride).zip(
-                            src.get_data().chunks(src.get_stride()))) {
-                    dst[..old_len].copy_from_slice(&old[self.start..self.end]);
-                    dst[old_len..][..new_len].copy_from_slice(&new[..new_len]);
+                if old_len > 0 {
+                    for (dst, (old, new)) in new_buf.chunks_exact_mut(new_stride).zip(
+                            self.data.chunks_exact(self.stride).zip(
+                                src.get_data().chunks(src.get_stride()))) {
+                        dst[..old_len].copy_from_slice(&old[self.start..self.end]);
+                        dst[old_len..][..new_len].copy_from_slice(&new[..new_len]);
+                    }
+                } else {
+                    for (dst, new) in new_buf.chunks_exact_mut(new_stride).zip(
+                                src.get_data().chunks(src.get_stride())) {
+                        dst[..new_len].copy_from_slice(&new[..new_len]);
+                    }
                 }
                 self.data = new_buf;
                 self.stride = new_stride;
@@ -110,10 +117,11 @@ pub struct AudioConverter {
     dst_fmt:    NAAudioInfo,
     dst_chmap:  NAChannelMap,
     apts:       Option<u64>,
+    resampler:  NAResample,
 }
 
 impl AudioConverter {
-    pub fn new(_sinfo: &NAAudioInfo, dinfo: &NAAudioInfo, dst_chmap: NAChannelMap) -> Self {
+    pub fn new(sinfo: &NAAudioInfo, dinfo: &NAAudioInfo, dst_chmap: NAChannelMap) -> Self {
         let ch = usize::from(dinfo.channels);
         let size = dinfo.block_len * 2;
         let il = !dinfo.format.planar;
@@ -124,15 +132,18 @@ impl AudioConverter {
                 (32, true, _)      => AudioDataType::F32(AudioQueue::new(ch, size, il)),
                 _ => AudioDataType::Packed(AudioQueue::new(ch, size, il)),
             };
+        const RESAMPLE_FILTER_ORDER: usize = 16;
+        let resampler = NAResample::new(sinfo.sample_rate, dinfo, &dst_chmap, RESAMPLE_FILTER_ORDER);
         Self {
             queue,
             dst_fmt:    *dinfo,
             dst_chmap,
             apts:       None,
+            resampler,
         }
     }
     pub fn queue_frame(&mut self, buf: NABufferType, tinfo: NATimeInfo) -> bool {
-        let ret = convert_audio_frame(&buf, &self.dst_fmt, &self.dst_chmap);
+        let ret = self.resampler.convert_audio_frame(&buf);
         if let Ok(dbuf) = ret {
             if self.apts.is_none() && tinfo.get_pts().is_some() {
                 self.apts = tinfo.get_pts();
index 1958bedc7ac40d31be12bf095721d11461958be0..e033dfd1040cd3d7b5eb965b351e1c8d926ce309 100644 (file)
@@ -24,6 +24,8 @@ mod null;
 mod acvt;
 use crate::acvt::*;
 
+const SND_NO_FORMAT: NASoniton = NASoniton { bits: 0, be: false, packed: false, planar: false, float: false, signed: false };
+
 fn format_time(ms: u64) -> String {
     let s = ms / 1000;
     let ds = (ms % 1000) / 100;
@@ -316,7 +318,7 @@ impl Transcoder {
                     },
                     "srate" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<u32>();
@@ -331,7 +333,7 @@ impl Transcoder {
                     },
                     "channels" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<u8>();
@@ -346,7 +348,7 @@ impl Transcoder {
                     },
                     "block_len" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<usize>();
@@ -361,7 +363,7 @@ impl Transcoder {
                     },
                     "sfmt" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<NASoniton>();
@@ -377,7 +379,7 @@ impl Transcoder {
 // todo channel map negotiation
                     /*"chmap" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<NAChannelMap>();
@@ -502,8 +504,35 @@ impl Transcoder {
                 }
                 let mut encoder = (enc_create.unwrap())();
                 let forced_out = oopts.enc_params.format != NACodecTypeInfo::None;
+                let iformat = istr.get_info().get_properties();
                 if oopts.enc_params.format == NACodecTypeInfo::None {
                     oopts.enc_params.format = istr.get_info().get_properties();
+                } else {
+                    match (&iformat, &mut oopts.enc_params.format) {
+                        (NACodecTypeInfo::Video(svinfo), NACodecTypeInfo::Video(ref mut dvinfo)) => {
+                            if dvinfo.width == 0 {
+                                dvinfo.width = svinfo.width;
+                            }
+                            if dvinfo.height == 0 {
+                                dvinfo.height = svinfo.height;
+                            }
+                        },
+                        (NACodecTypeInfo::Audio(sainfo), NACodecTypeInfo::Audio(ref mut dainfo)) => {
+                            if dainfo.sample_rate == 0 {
+                                dainfo.sample_rate = sainfo.sample_rate;
+                            }
+                            if dainfo.format == SND_NO_FORMAT {
+                                dainfo.format = sainfo.format;
+                            }
+                            if dainfo.channels == 0 {
+                                dainfo.channels = sainfo.channels;
+                            }
+                            if dainfo.block_len == 0 {
+                                dainfo.block_len = sainfo.block_len;
+                            }
+                        },
+                        _ => {},
+                    };
                 }
                 if oopts.enc_params.tb_num == 0 {
                     oopts.enc_params.tb_num = istr.tb_num;
@@ -517,7 +546,7 @@ impl Transcoder {
                 let ret_eparams = ret_eparams.unwrap();
 
 //todo check for params mismatch
-                let cvt = match (&oopts.enc_params.format, &ret_eparams.format) {
+                let cvt = match (&iformat, &ret_eparams.format) {
                         (NACodecTypeInfo::Video(svinfo), NACodecTypeInfo::Video(dvinfo)) => {
                             if svinfo == dvinfo && !forced_out {
                                 OutputConvert::None