From 54a7fecf63dc75d2ba4a6616aa812e8284e45ae4 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Tue, 31 Mar 2026 17:46:02 +0200 Subject: [PATCH] Create scaler when input video format differs from the expected output format --- src/transcoder.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/transcoder.rs b/src/transcoder.rs index a90484b..4a164b2 100644 --- a/src/transcoder.rs +++ b/src/transcoder.rs @@ -226,6 +226,7 @@ impl EncoderInterface for AudioEncodeContext { pub struct VideoEncodeContext { pub encoder: Box, + pub vinfo: NAVideoInfo, pub scaler: Option, pub scaler_buf: NABufferType, pub tb_num: u32, @@ -237,6 +238,31 @@ pub struct VideoEncodeContext { impl EncoderInterface for VideoEncodeContext { fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue, dbg: &mut Option) -> EncoderResult { 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 { @@ -963,6 +989,7 @@ impl Transcoder { if svinfo == dvinfo && !forced_out { Box::new(VideoEncodeContext { encoder, + vinfo: *dvinfo, scaler: None, scaler_buf: NABufferType::None, cfr: force_cfr, @@ -986,6 +1013,7 @@ impl Transcoder { let scaler_buf = ret.unwrap(); Box::new(VideoEncodeContext { encoder, + vinfo: *dvinfo, scaler: Some(scaler), scaler_buf, cfr: force_cfr, @@ -1144,6 +1172,7 @@ println!("encoder {} is not supported by output (expected {})", istr.id, istr.ge if svinfo == dvinfo { Box::new(VideoEncodeContext { encoder, + vinfo: *dvinfo, scaler: None, scaler_buf: NABufferType::None, cfr: force_cfr, @@ -1167,6 +1196,7 @@ println!("encoder {} is not supported by output (expected {})", istr.id, istr.ge let scaler_buf = ret.unwrap(); Box::new(VideoEncodeContext { encoder, + vinfo: *dvinfo, scaler: Some(scaler), scaler_buf, cfr: force_cfr, -- 2.39.5