pub struct AudioEncodeContext {
pub encoder: Box<dyn NAEncoder>,
pub cvt: Option<AudioConverter>,
+ pub sainfo: NAAudioInfo,
+ pub dainfo: NAAudioInfo,
+}
+
+// todo better channel map generation
+fn generate_channel_map(info: &NAAudioInfo) -> Option<NAChannelMap> {
+ match info.channels {
+ 1 => Some(NAChannelMap::from_ms_mapping(0x4)),
+ 2 => Some(NAChannelMap::from_ms_mapping(0x3)),
+ _ => {
+println!("can't generate default channel map for {} channels", info.channels);
+ None
+ },
+ }
}
impl EncoderInterface for AudioEncodeContext {
fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, _scale_opts: &[(String, String)], queue: &mut OutputQueue) -> EncoderResult<bool> {
let buf = frm.get_buffer();
+ // check for possible input parameters mismatch and create audio converter if needed
+ if self.cvt.is_none() {
+ let cur_info = buf.get_audio_info().unwrap();
+ if cur_info != self.sainfo {
+ let dchmap = generate_channel_map(&self.dainfo).ok_or(EncoderError::FormatError)?;
+ self.cvt = Some(AudioConverter::new(&cur_info, &self.dainfo, dchmap));
+ self.sainfo = cur_info;
+ }
+ }
let cbuf = if let NABufferType::None = buf {
buf
} else if let Some(ref mut acvt) = self.cvt {
(NACodecTypeInfo::Audio(sainfo), NACodecTypeInfo::Audio(dainfo)) => {
let icodec = istr.get_info().get_name();
if (sainfo == dainfo) && (icodec != "pcm" || oopts.enc_name.as_str() == "pcm") {
- Box::new(AudioEncodeContext { encoder, cvt: None })
+ Box::new(AudioEncodeContext { encoder, cvt: None, sainfo: *sainfo, dainfo: *dainfo })
} else {
- let dchmap = match dainfo.channels {
- 1 => NAChannelMap::from_ms_mapping(0x4),
- 2 => NAChannelMap::from_ms_mapping(0x3),
- _ => {
-println!("can't generate default channel map for {} channels", dainfo.channels);
- return RegisterResult::Failed;
- },
+ let dchmap = if let Some(ret) = generate_channel_map(dainfo) {
+ ret
+ } else {
+ return RegisterResult::Failed;
};
let acvt = AudioConverter::new(sainfo, dainfo, dchmap);
-//todo channelmap
- Box::new(AudioEncodeContext { encoder, cvt: Some(acvt) })
+ Box::new(AudioEncodeContext { encoder, cvt: Some(acvt), sainfo: *sainfo, dainfo: *dainfo })
}
},
_ => unreachable!(),
}
}
if sainfo == &dainfo {
- Box::new(AudioEncodeContext { encoder, cvt: None })
+ Box::new(AudioEncodeContext { encoder, cvt: None, sainfo: *sainfo, dainfo })
} else {
- let dchmap = match dainfo.channels {
- 1 => NAChannelMap::from_ms_mapping(0x4),
- 2 => NAChannelMap::from_ms_mapping(0x3),
- _ => {
-println!("can't generate default channel map for {} channels", dainfo.channels);
- return RegisterResult::Failed;
- },
+ let dchmap = if let Some(ret) = generate_channel_map(&dainfo) {
+ ret
+ } else {
+ return RegisterResult::Failed;
};
-
-//todo channelmap
let acvt = AudioConverter::new(sainfo, &dainfo, dchmap);
- Box::new(AudioEncodeContext { encoder, cvt: Some(acvt) })
+ Box::new(AudioEncodeContext { encoder, cvt: Some(acvt), sainfo: *sainfo, dainfo })
}
},
_ => unreachable!(),