Skip to content

Commit

Permalink
Storing pointers over references and Boxing the decoders
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchitBhonsle committed Apr 10, 2023
1 parent 44141b1 commit 125e740
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/lib_ccx/ccx_decoders_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down
56 changes: 28 additions & 28 deletions src/rust/src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<dtvcc_service_decoder>; CCX_DTVCC_MAX_SERVICES],
pub report: *mut ccx_decoder_dtvcc_report,
pub decoders: [Option<Box<dtvcc_service_decoder>>; 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
Expand All @@ -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<dtvcc_service_decoder> = None;
const INIT: Option<Box<dtvcc_service_decoder>> = None;
let mut decoders = [INIT; CCX_DTVCC_MAX_SERVICES];

decoders
Expand All @@ -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 {
Expand All @@ -88,27 +90,27 @@ 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);
});

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,
Expand Down Expand Up @@ -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,
);
}
Expand All @@ -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;
}
Expand All @@ -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() };
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 125e740

Please sign in to comment.