From 125e74036c6349eb57062a9d3cd2ed3bb9d39819 Mon Sep 17 00:00:00 2001 From: Archit Bhonsle Date: Mon, 20 Mar 2023 14:39:58 +0530 Subject: [PATCH] Storing pointers over references and `Box`ing the decoders --- src/lib_ccx/ccx_decoders_common.c | 4 +-- src/rust/src/decoder/mod.rs | 56 +++++++++++++++---------------- src/rust/src/lib.rs | 9 ++--- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/lib_ccx/ccx_decoders_common.c b/src/lib_ccx/ccx_decoders_common.c index 4bde0ac0b..5200482c2 100644 --- a/src/lib_ccx/ccx_decoders_common.c +++ b/src/lib_ccx/ccx_decoders_common.c @@ -18,7 +18,7 @@ made to reuse, not duplicate, as many functions as possible */ #ifndef DISABLE_RUST extern int ccxr_process_cc_data(struct lib_cc_decode *dec_ctx, unsigned char *cc_data, int cc_count); extern void ccxr_flush_decoder(struct dtvcc_ctx *dtvcc, struct dtvcc_service_decoder *decoder); -extern void *ccxr_dtvcc_init(struct ccx_decoder_dtvcc_settings *decoder_settings); +extern void *ccxr_dtvcc_init(struct ccx_decoder_dtvcc_settings *settings_dtvcc); extern void ccxr_dtvcc_free(void *dtvcc_rust); #endif @@ -267,7 +267,7 @@ struct lib_cc_decode *init_cc_decode(struct ccx_decoders_common_settings_t *sett ctx->noscte20 = setting->noscte20; #ifndef DISABLE_RUST - ctx->dtvcc = ccxr_dtvcc_init(setting->settings_dtvcc); + ctx->dtvcc_rust = ccxr_dtvcc_init(setting->settings_dtvcc); #endif ctx->dtvcc = dtvcc_init(setting->settings_dtvcc); ctx->dtvcc->is_active = setting->settings_dtvcc->enabled; diff --git a/src/rust/src/decoder/mod.rs b/src/rust/src/decoder/mod.rs index c4c35f4c4..0077f645f 100644 --- a/src/rust/src/decoder/mod.rs +++ b/src/rust/src/decoder/mod.rs @@ -26,33 +26,35 @@ const CCX_DTVCC_MAX_SERVICES: usize = 63; // const CCX_DTVCC_MAX_WINDOWS: usize = 8; /// Context required for processing 708 data -pub struct Dtvcc<'a> { +pub struct Dtvcc { pub is_active: bool, pub active_services_count: u8, pub services_active: [i32; CCX_DTVCC_MAX_SERVICES], pub report_enabled: bool, - pub report: &'a mut ccx_decoder_dtvcc_report, - pub decoders: [Option; CCX_DTVCC_MAX_SERVICES], + pub report: *mut ccx_decoder_dtvcc_report, + pub decoders: [Option>; CCX_DTVCC_MAX_SERVICES], pub packet: [u8; CCX_DTVCC_MAX_SERVICES], pub packet_length: u8, pub is_header_parsed: bool, pub last_sequence: i32, - pub encoder: Option<&'a mut encoder_ctx>, + pub encoder: *mut encoder_ctx, pub no_rollup: bool, - pub timing: &'a mut ccx_common_timing_ctx, + pub timing: *mut ccx_common_timing_ctx, } -impl<'a> Dtvcc<'a> { +impl Dtvcc { /// Create a new dtvcc context - pub fn new(opts: &'_ mut ccx_decoder_dtvcc_settings) -> Self { + pub fn new(opts: &ccx_decoder_dtvcc_settings) -> Self { // closely follows `dtvcc_init` at `src/lib_ccx/ccx_dtvcc.c:76` - let report = unsafe { opts.report.as_mut().unwrap() }; - report.reset_count = 0; + let report = opts.report; + unsafe { + (*report).reset_count = 0; + } let is_active = false; - let _no_rollup = is_true(opts.no_rollup); - let _active_services_count = opts.active_services_count as u8; + let no_rollup = is_true(opts.no_rollup); + let active_services_count = opts.active_services_count as u8; let services_active = opts.services_enabled; // `dtvcc_clear_packet` does the following @@ -63,11 +65,11 @@ impl<'a> Dtvcc<'a> { let last_sequence = CCX_DTVCC_NO_LAST_SEQUENCE; let report_enabled = is_true(opts.print_file_reports); - let timing = unsafe { opts.timing.as_mut() }.unwrap(); + let timing = opts.timing; // unlike C, here the decoders are allocated on the stack as an array. let decoders = { - const INIT: Option = None; + const INIT: Option> = None; let mut decoders = [INIT; CCX_DTVCC_MAX_SERVICES]; decoders @@ -79,7 +81,7 @@ impl<'a> Dtvcc<'a> { return; } - let mut decoder = dtvcc_service_decoder { + let mut decoder = Box::new(dtvcc_service_decoder { // we cannot allocate this on the stack as `dtvcc_service_decoder` is a C // struct cannot be changed trivially tv: Box::into_raw(Box::new(dtvcc_tv_screen { @@ -88,13 +90,13 @@ impl<'a> Dtvcc<'a> { ..dtvcc_tv_screen::default() })), ..dtvcc_service_decoder::default() - }; + }); decoder.windows.iter_mut().for_each(|w| { w.memory_reserved = 0; }); - unsafe { dtvcc_windows_reset(&mut decoder) }; + unsafe { dtvcc_windows_reset(decoder.as_mut()) }; *d = Some(decoder); }); @@ -102,13 +104,13 @@ impl<'a> Dtvcc<'a> { decoders }; - let encoder = None; // Unlike C, does not mention `encoder` and is initialised to `null` by default + let encoder = std::ptr::null_mut(); // Unlike C, does not mention `encoder` and is initialised to `null` by default Self { report, is_active, - no_rollup: _no_rollup, - active_services_count: _active_services_count, + no_rollup, + active_services_count, services_active, packet_length, is_header_parsed, @@ -227,15 +229,15 @@ impl<'a> Dtvcc<'a> { } if block_length != 0 { - self.report.services[service_number as usize] = 1; + unsafe { (*self.report).services[service_number as usize] = 1 }; } if service_number > 0 && is_true(self.services_active[(service_number - 1) as usize]) { let decoder = &mut self.decoders[(service_number - 1) as usize]; - decoder.unwrap().process_service_block( + decoder.as_mut().unwrap().process_service_block( &self.packet[pos as usize..(pos + block_length) as usize], - self.encoder.as_mut().unwrap(), - self.timing, + unsafe { self.encoder.as_mut().unwrap() }, + unsafe { self.timing.as_mut().unwrap() }, self.no_rollup, ); } @@ -258,11 +260,11 @@ impl<'a> Dtvcc<'a> { } } -impl<'a> Drop for Dtvcc<'a> { +impl Drop for Dtvcc { fn drop(&mut self) { // closely follows `dtvcc_free` at `src/lib_ccx/ccx_dtvcc.c:126` for i in 0..CCX_DTVCC_MAX_SERVICES { - if let Some(mut decoder) = self.decoders[i] { + if let Some(decoder) = self.decoders[i].as_mut() { if !is_true(self.services_active[i]) { continue; } @@ -279,9 +281,7 @@ impl<'a> Drop for Dtvcc<'a> { window.memory_reserved = 0; }); - unsafe { - decoder.tv.drop_in_place(); - } + unsafe { decoder.tv.drop_in_place() }; } } } diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 7241454f2..e69a707d7 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -52,8 +52,9 @@ pub extern "C" fn ccxr_init_logger() { /// - opts.report /// - opts.timing #[no_mangle] -extern "C" fn ccxr_dtvcc_init<'a>(opts: *mut ccx_decoder_dtvcc_settings) -> *mut Dtvcc<'a> { - Box::into_raw(Box::new(Dtvcc::new(unsafe { opts.as_mut() }.unwrap()))) +extern "C" fn ccxr_dtvcc_init(opts_ptr: *const ccx_decoder_dtvcc_settings) -> *mut Dtvcc { + let opts = unsafe { opts_ptr.as_ref() }.unwrap(); + Box::into_raw(Box::new(Dtvcc::new(opts))) } /// Frees `dtvcc_rust` @@ -72,7 +73,7 @@ extern "C" fn ccxr_dtvcc_free(dtvcc_rust: *mut Dtvcc) { #[no_mangle] extern "C" fn ccxr_dtvcc_set_encoder(dtvcc_rust: *mut Dtvcc, encoder: *mut encoder_ctx) { - unsafe { dtvcc_rust.as_mut() }.unwrap().encoder = Some(unsafe { encoder.as_mut() }.unwrap()); + unsafe { (*dtvcc_rust).encoder = encoder }; } /// Process cc_data @@ -140,7 +141,7 @@ pub fn verify_parity(data: u8) -> bool { /// Process CC data according to its type pub fn do_cb(ctx: &mut lib_cc_decode, cc_block: &[u8]) -> bool { - let dtvcc = unsafe { &mut *(ctx.dtvcc_rust as *mut decoder::Dtvcc<'_>) }; + let dtvcc = unsafe { &mut *(ctx.dtvcc_rust as *mut decoder::Dtvcc) }; let cc_valid = (cc_block[0] & 4) >> 2; let cc_type = cc_block[0] & 3; let mut timeok = true;