From ca3a553a5eabbcbfe1422a1c6183ab9d9a5f6590 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 19 Mar 2025 18:54:29 +0100 Subject: [PATCH] handle possible encoding errors instead of panicking on .unwrap() --- src/main.rs | 20 +++++++++++++++----- src/transcoder.rs | 28 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index 92ee64c..f3f0be5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -638,8 +638,13 @@ fn main() { let frm = ret.unwrap(); dec_ctx.reorderer.add_frame(frm); while let Some(frm) = dec_ctx.reorderer.get_frame() { - if !encoder.encode_frame(dst_id, frm, &transcoder.scale_opts, &mut transcoder.queue) { - break; + match encoder.encode_frame(dst_id, frm, &transcoder.scale_opts, &mut transcoder.queue) { + Ok(true) => {}, + Ok(false) => break, + Err(err) => { + println!("encoder error {err:?}"); + break 'main_loop; + } } } } else { @@ -653,13 +658,18 @@ fn main() { break; } } - /*'reord_flush_loop:*/ for stream in ism.iter() { + 'reord_flush_loop: for stream in ism.iter() { let src_id = stream.get_num(); if let OutputMode::Encode(dst_id, ref mut encoder) = transcoder.encoders[src_id] { if let Some(ref mut dec_ctx) = transcoder.decoders[src_id] { while let Some(frm) = dec_ctx.reorderer.get_last_frames() { - if !encoder.encode_frame(dst_id, frm, &transcoder.scale_opts, &mut transcoder.queue) { - break; + match encoder.encode_frame(dst_id, frm, &transcoder.scale_opts, &mut transcoder.queue) { + Ok(true) => {}, + Ok(false) => break, + Err(err) => { + println!("encoder error {err:?}"); + break 'reord_flush_loop; + } } } } diff --git a/src/transcoder.rs b/src/transcoder.rs index ad2a096..cee575f 100644 --- a/src/transcoder.rs +++ b/src/transcoder.rs @@ -121,7 +121,7 @@ pub struct DecodeContext { } pub trait EncoderInterface { - fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue) -> bool; + fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue) -> EncoderResult; fn flush(&mut self, queue: &mut OutputQueue) -> EncoderResult<()>; fn get_packet(&mut self) -> EncoderResult>; } @@ -132,35 +132,35 @@ pub struct AudioEncodeContext { } impl EncoderInterface for AudioEncodeContext { - fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, _scale_opts: &[(String, String)], queue: &mut OutputQueue) -> bool { + fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, _scale_opts: &[(String, String)], queue: &mut OutputQueue) -> EncoderResult { let buf = frm.get_buffer(); let cbuf = if let NABufferType::None = buf { buf } else if let Some(ref mut acvt) = self.cvt { if !acvt.queue_frame(buf, frm.get_time_information()) { println!("error converting audio for stream {}", dst_id); - return false; + return Ok(false); } while let Some(ofrm) = acvt.get_frame(frm.get_info().clone()) { if self.encoder.encode(&ofrm).is_err() { - return false; + return Ok(false); } while let Ok(Some(pkt)) = self.encoder.get_packet() { queue.queue_packet(pkt); } } - return true; + return Ok(true); } else { buf }; let cfrm = NAFrame::new(frm.get_time_information(), frm.frame_type, frm.key, frm.get_info(), cbuf); - self.encoder.encode(&cfrm).unwrap(); + self.encoder.encode(&cfrm)?; while let Ok(Some(pkt)) = self.encoder.get_packet() { queue.queue_packet(pkt); } - true + Ok(true) } fn flush(&mut self, queue: &mut OutputQueue) -> EncoderResult<()> { self.encoder.flush()?; @@ -185,13 +185,13 @@ pub struct VideoEncodeContext { } impl EncoderInterface for VideoEncodeContext { - fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue) -> bool { + fn encode_frame(&mut self, dst_id: u32, frm: NAFrameRef, scale_opts: &[(String, String)], queue: &mut OutputQueue) -> EncoderResult { let buf = frm.get_buffer(); let cbuf = if let NABufferType::None = buf { if (self.encoder.get_capabilities() & ENC_CAPS_SKIPFRAME) == 0 { if let NABufferType::None = self.scaler_buf { println!("encoder does not support skip frames, skipping"); - return true; + return Ok(true); } else { self.scaler_buf.clone() } @@ -206,14 +206,14 @@ impl EncoderInterface for VideoEncodeContext { let ret = NAScale::new_with_options(cur_ifmt, ofmt, scale_opts); if ret.is_err() { println!("error re-initialising scaler for {} -> {}", cur_ifmt, ofmt); - return false; + return Err(EncoderError::InvalidParameters); } *scaler = ret.unwrap(); } let ret = scaler.convert(&buf, &mut self.scaler_buf); if ret.is_err() { println!("error converting frame for encoding stream {dst_id}"); - return false; + return Err(EncoderError::Bug); } self.scaler_buf.clone() } else { @@ -245,7 +245,7 @@ impl EncoderInterface for VideoEncodeContext { let mut had_frame = false; while cur_ts >= cur_lts { cfrm.ts.pts = Some(cur_lts); - self.encoder.encode(&cfrm).unwrap(); + self.encoder.encode(&cfrm)?; while let Ok(Some(pkt)) = self.encoder.get_packet() { queue.queue_packet(pkt); } @@ -260,13 +260,13 @@ impl EncoderInterface for VideoEncodeContext { } } if !converted { - self.encoder.encode(&cfrm).unwrap(); + self.encoder.encode(&cfrm)?; while let Ok(Some(pkt)) = self.encoder.get_packet() { queue.queue_packet(pkt); } } - true + Ok(true) } fn flush(&mut self, queue: &mut OutputQueue) -> EncoderResult<()> { self.encoder.flush()?; -- 2.39.5