]> git.nihav.org Git - nihav-encoder.git/commitdiff
handle possible encoding errors instead of panicking on .unwrap()
authorKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 19 Mar 2025 17:54:29 +0000 (18:54 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 19 Mar 2025 17:54:29 +0000 (18:54 +0100)
src/main.rs
src/transcoder.rs

index 92ee64c7c87eb615d1aacdec45245942bf9f8e55..f3f0be51d1aebc5ff017b62ce5e8029e47afb5b5 100644 (file)
@@ -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;
+                        }
                     }
                 }
             }
index ad2a096f4a75f5085f1db7d9267581e2584b401f..cee575f84a2f268592062a8a83e0b7dbc9c7f79a 100644 (file)
@@ -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<bool>;
     fn flush(&mut self, queue: &mut OutputQueue) -> EncoderResult<()>;
     fn get_packet(&mut self) -> EncoderResult<Option<NAPacket>>;
 }
@@ -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<bool> {
         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<bool> {
         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()?;