use NAPacketiser::attach_stream() where appropriate
[nihav-encoder.git] / src / acvt.rs
index 349e10b383a32f5a8e0dc5eab1e0a1e9bf7608f2..254bed692c0056371bc116b7c31da08b307832eb 100644 (file)
@@ -10,6 +10,37 @@ struct AudioQueue<T> {
     ileaved:    bool,
 }
 
+fn copy_audio<T:Clone+Copy>(dst: &mut [T], dstride: usize,
+                            src: &[T], sstride: usize,
+                            len: usize, channels: usize)
+{
+    match (sstride == 1, dstride == 1) {
+        (false, false) => {
+            for (dchan, schan) in dst.chunks_mut(dstride).zip(
+                        src.chunks(sstride)).take(channels) {
+                dchan[..len].copy_from_slice(&schan[..len]);
+            }
+        },
+        (false, true) => {
+            for (ch, schan) in src.chunks(sstride).take(channels).enumerate() {
+                for (dchunk, &samp) in dst[ch..].chunks_mut(channels).zip(schan.iter()).take(len / channels) {
+                    dchunk[0] = samp;
+                }
+            }
+        },
+        (true, false) => {
+            for (i, frame) in src.chunks_exact(channels).take(len).enumerate() {
+                for (&samp, dchan) in frame.iter().zip(dst[i..].chunks_mut(dstride)) {
+                    dchan[0] = samp;
+                }
+            }
+        },
+        (true, true) => {
+            dst[..len].copy_from_slice(&src[..len]);
+        },
+    }
+}
+
 impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
     fn new(channels: usize, rec_size: usize, ileaved: bool) -> Self {
         Self {
@@ -22,6 +53,14 @@ impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
         }
     }
     fn get_cur_size(&self) -> usize { self.end - self.start }
+    fn get_length(&self) -> usize {
+        let size = self.get_cur_size();
+        if !self.ileaved {
+            size
+        } else {
+            size / self.channels
+        }
+    }
     fn get_cur_avail(&self) -> usize { self.stride - self.end }
     fn get_potentially_avail(&self) -> usize { self.stride - self.get_cur_size() }
     fn read(&mut self, src: &NAAudioBuffer<T>) {
@@ -40,17 +79,19 @@ impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
                 let old_len = self.get_cur_size();
                 let new_len = src.get_length();
                 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]);
+                    if !self.ileaved {
+                        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 {
+                        new_buf[..old_len].copy_from_slice(&self.data[self.start..self.end]);
+                        copy_audio(&mut new_buf[old_len..], 1, src.get_data(), src.get_stride(), new_len, self.channels);
                     }
                 } 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]);
-                    }
+                    copy_audio(&mut new_buf, if !self.ileaved { new_stride } else { 1 }, src.get_data(), src.get_stride(), new_len, self.channels);
                 }
                 self.data = new_buf;
                 self.stride = new_stride;
@@ -59,19 +100,20 @@ impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
                 return;
             }
         }
-        for (dst, src) in self.data.chunks_exact_mut(self.stride).zip(src.get_data().chunks_exact(src.get_stride())) {
-            dst[self.end..][..to_copy].copy_from_slice(&src[..to_copy]);
-        }
+        copy_audio(&mut self.data[self.end..], if !self.ileaved { self.stride } else { 1 }, src.get_data(), src.get_stride(),
+                   to_copy, self.channels);
         self.end += to_copy;
     }
     fn write(&mut self, dbuf: &mut NAAudioBuffer<T>) {
-        let dst_len = dbuf.get_length();
+        let mut dst_len = dbuf.get_length();
         let dst_stride = dbuf.get_stride();
         let dst = dbuf.get_data_mut().unwrap();
 
-        for (dst, src) in dst.chunks_mut(dst_stride).zip(self.data.chunks_exact(self.stride)) {
-            dst[..dst_len].copy_from_slice(&src[self.start..][..dst_len]);
+        if dst_stride == 1 {
+            dst_len *= self.channels;
         }
+        copy_audio(dst, dst_stride, &self.data[self.start..], if !self.ileaved { self.stride } else { 1 },
+                   dst_len, self.channels);
         self.start += dst_len;
     }
     fn renorm(&mut self) {
@@ -103,11 +145,11 @@ enum AudioDataType {
 impl AudioDataType {
     fn get_length(&self) -> usize {
         match self {
-            AudioDataType::U8(ref queue) => queue.get_cur_size(),
-            AudioDataType::I16(ref queue) => queue.get_cur_size(),
-            AudioDataType::I32(ref queue) => queue.get_cur_size(),
-            AudioDataType::F32(ref queue) => queue.get_cur_size(),
-            AudioDataType::Packed(ref queue) => queue.get_cur_size(),
+            AudioDataType::U8(ref queue) => queue.get_length(),
+            AudioDataType::I16(ref queue) => queue.get_length(),
+            AudioDataType::I32(ref queue) => queue.get_length(),
+            AudioDataType::F32(ref queue) => queue.get_length(),
+            AudioDataType::Packed(ref queue) => queue.get_length(),
         }
     }
 }