pub struct VideoEncodeContext {
pub encoder: Box<dyn NAEncoder>,
+ pub vinfo: NAVideoInfo,
pub scaler: Option<NAScale>,
pub scaler_buf: NABufferType,
pub tb_num: u32,
impl EncoderInterface for VideoEncodeContext {
fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue, dbg: &mut Option<DebugLog>) -> EncoderResult<bool> {
let buf = frm.get_buffer();
+ if let Some(vinfo) = buf.get_video_info() {
+ if self.scaler.is_none() && vinfo != self.vinfo {
+ let ifmt = get_scale_fmt_from_pic(&buf);
+ let ofmt = ScaleInfo {
+ width: self.vinfo.width,
+ height: self.vinfo.height,
+ fmt: self.vinfo.format,
+ };
+ if let Some(ref mut dlog) = dbg {
+ dlog.log(DebugLog::ENCODE, &format!("Input for the output stream {dst_id} differs in format, inserting scaler"));
+ }
+ if let Ok(scaler) = NAScale::new_with_options(ifmt, ofmt, scale_opts) {
+ self.scaler = Some(scaler);
+ self.scaler_buf = if let Ok(buf) = alloc_video_buffer(self.vinfo, 4) {
+ buf
+ } else {
+ println!("cannot create scaler buffer");
+ return Err(EncoderError::AllocError);
+ };
+ } else {
+ println!("error re-initialising scaler for {ifmt} -> {ofmt}");
+ return Err(EncoderError::InvalidParameters);
+ }
+ }
+ }
let cbuf = if let NABufferType::None = buf {
if (self.encoder.get_capabilities() & ENC_CAPS_SKIPFRAME) == 0 {
if let NABufferType::None = self.scaler_buf {
if svinfo == dvinfo && !forced_out {
Box::new(VideoEncodeContext {
encoder,
+ vinfo: *dvinfo,
scaler: None,
scaler_buf: NABufferType::None,
cfr: force_cfr,
let scaler_buf = ret.unwrap();
Box::new(VideoEncodeContext {
encoder,
+ vinfo: *dvinfo,
scaler: Some(scaler),
scaler_buf,
cfr: force_cfr,
if svinfo == dvinfo {
Box::new(VideoEncodeContext {
encoder,
+ vinfo: *dvinfo,
scaler: None,
scaler_buf: NABufferType::None,
cfr: force_cfr,
let scaler_buf = ret.unwrap();
Box::new(VideoEncodeContext {
encoder,
+ vinfo: *dvinfo,
scaler: Some(scaler),
scaler_buf,
cfr: force_cfr,