diff --git a/docs/CHANGES.TXT b/docs/CHANGES.TXT index 8e96d0b23..8e4b455d8 100644 --- a/docs/CHANGES.TXT +++ b/docs/CHANGES.TXT @@ -1,5 +1,6 @@ 0.96 (2025-12-23) ----------------- +- Fix: Prevent CEA-708 decoder panic when using --stdout on Windows by safely handling writer output errors - New: Multi-page teletext extraction support (#665) - Extract multiple teletext pages simultaneously with separate output files - Use --tpage multiple times (e.g., --tpage 100 --tpage 200) diff --git a/src/rust/src/decoder/service_decoder.rs b/src/rust/src/decoder/service_decoder.rs index 3ce528b32..4e84d9d24 100644 --- a/src/rust/src/decoder/service_decoder.rs +++ b/src/rust/src/decoder/service_decoder.rs @@ -860,19 +860,27 @@ impl dtvcc_service_decoder { /// Print the contents of tv screen to the output file pub fn screen_print(&mut self, encoder: &mut encoder_ctx, timing: &mut ccx_common_timing_ctx) { - debug!("dtvcc_screen_print rust"); + debug!("dtvcc::screen_print rust"); + self.cc_count += 1; + unsafe { - let tv = &mut (*self.tv); + let tv = &mut *self.tv; tv.cc_count += 1; + let sn = tv.service_number; let writer_ctx = &mut encoder.dtvcc_writers[(sn - 1) as usize]; + tv.update_time_hide(timing.get_visible_end(3)); - let transcript_settings = if !encoder.transcript_settings.is_null() { - &*encoder.transcript_settings - } else { - &ccx_encoders_transcript_format::default() + + let transcript_settings = match encoder.transcript_settings.as_ref() { + Some(ts) => ts, + None => { + // No transcript settings => transcript output disabled + return; + } }; + let mut writer = Writer::new( &mut encoder.cea_708_counter, encoder.subs_delay, @@ -882,7 +890,10 @@ impl dtvcc_service_decoder { transcript_settings, encoder.no_bom, ); - tv.writer_output(&mut writer).unwrap(); + + if let Err(e) = tv.writer_output(&mut writer) { + warn!("dtvcc::screen_print: writer_output failed: {}", e); + } tv.clear(); } } @@ -1190,18 +1201,17 @@ impl dtvcc_service_decoder { } /// Flush the decoder of any remaining subtitles pub fn flush(&self, encoder: &mut encoder_ctx) { - let transcript_settings = unsafe { - if !encoder.transcript_settings.is_null() { - &*encoder.transcript_settings - } else { - &ccx_encoders_transcript_format::default() - } - }; unsafe { - let tv = &mut (*self.tv); + let tv = &mut *self.tv; let sn = tv.service_number; let writer_ctx = &mut encoder.dtvcc_writers[(sn - 1) as usize]; + // If transcript output is disabled, do nothing + let transcript_settings = match encoder.transcript_settings.as_ref() { + Some(ts) => ts, + None => return, + }; + let mut writer = Writer::new( &mut encoder.cea_708_counter, encoder.subs_delay, @@ -1211,6 +1221,7 @@ impl dtvcc_service_decoder { transcript_settings, encoder.no_bom, ); + writer.write_done(); } }