aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/acvt.rs25
-rw-r--r--src/main.rs41
2 files changed, 53 insertions, 13 deletions
diff --git a/src/acvt.rs b/src/acvt.rs
index 5343039..349e10b 100644
--- a/src/acvt.rs
+++ b/src/acvt.rs
@@ -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();
diff --git a/src/main.rs b/src/main.rs
index 1958bed..e033dfd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -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