Skip to content

Commit c83d88b

Browse files
committed
Storing pointers over references and Boxing the decoders
1 parent 33ac6c3 commit c83d88b

File tree

3 files changed

+35
-34
lines changed

3 files changed

+35
-34
lines changed

src/lib_ccx/ccx_decoders_common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ made to reuse, not duplicate, as many functions as possible */
1818
#ifndef DISABLE_RUST
1919
extern int ccxr_process_cc_data(struct lib_cc_decode *dec_ctx, unsigned char *cc_data, int cc_count);
2020
extern void ccxr_flush_decoder(struct dtvcc_ctx *dtvcc, struct dtvcc_service_decoder *decoder);
21-
extern void *ccxr_dtvcc_init(struct ccx_decoder_dtvcc_settings *decoder_settings);
21+
extern void *ccxr_dtvcc_init(struct ccx_decoder_dtvcc_settings *settings_dtvcc);
2222
extern void ccxr_dtvcc_free(void *dtvcc_rust);
2323
#endif
2424

@@ -267,7 +267,7 @@ struct lib_cc_decode *init_cc_decode(struct ccx_decoders_common_settings_t *sett
267267
ctx->noscte20 = setting->noscte20;
268268

269269
#ifndef DISABLE_RUST
270-
ctx->dtvcc = ccxr_dtvcc_init(setting->settings_dtvcc);
270+
ctx->dtvcc_rust = ccxr_dtvcc_init(setting->settings_dtvcc);
271271
#endif
272272
ctx->dtvcc = dtvcc_init(setting->settings_dtvcc);
273273
ctx->dtvcc->is_active = setting->settings_dtvcc->enabled;

src/rust/src/decoder/mod.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,35 @@ const CCX_DTVCC_MAX_SERVICES: usize = 63;
2626
// const CCX_DTVCC_MAX_WINDOWS: usize = 8;
2727

2828
/// Context required for processing 708 data
29-
pub struct Dtvcc<'a> {
29+
pub struct Dtvcc {
3030
pub is_active: bool,
3131
pub active_services_count: u8,
3232
pub services_active: [i32; CCX_DTVCC_MAX_SERVICES],
3333
pub report_enabled: bool,
34-
pub report: &'a mut ccx_decoder_dtvcc_report,
35-
pub decoders: [Option<dtvcc_service_decoder>; CCX_DTVCC_MAX_SERVICES],
34+
pub report: *mut ccx_decoder_dtvcc_report,
35+
pub decoders: [Option<Box<dtvcc_service_decoder>>; CCX_DTVCC_MAX_SERVICES],
3636
pub packet: [u8; CCX_DTVCC_MAX_SERVICES],
3737
pub packet_length: u8,
3838
pub is_header_parsed: bool,
3939
pub last_sequence: i32,
40-
pub encoder: Option<&'a mut encoder_ctx>,
40+
pub encoder: *mut encoder_ctx,
4141
pub no_rollup: bool,
42-
pub timing: &'a mut ccx_common_timing_ctx,
42+
pub timing: *mut ccx_common_timing_ctx,
4343
}
4444

45-
impl<'a> Dtvcc<'a> {
45+
impl Dtvcc {
4646
/// Create a new dtvcc context
47-
pub fn new(opts: &'_ mut ccx_decoder_dtvcc_settings) -> Self {
47+
pub fn new(opts: &ccx_decoder_dtvcc_settings) -> Self {
4848
// closely follows `dtvcc_init` at `src/lib_ccx/ccx_dtvcc.c:76`
4949

50-
let report = unsafe { opts.report.as_mut().unwrap() };
51-
report.reset_count = 0;
50+
let report = opts.report;
51+
unsafe {
52+
(*report).reset_count = 0;
53+
}
5254

5355
let is_active = false;
54-
let _no_rollup = is_true(opts.no_rollup);
55-
let _active_services_count = opts.active_services_count as u8;
56+
let no_rollup = is_true(opts.no_rollup);
57+
let active_services_count = opts.active_services_count as u8;
5658
let services_active = opts.services_enabled;
5759

5860
// `dtvcc_clear_packet` does the following
@@ -63,11 +65,11 @@ impl<'a> Dtvcc<'a> {
6365
let last_sequence = CCX_DTVCC_NO_LAST_SEQUENCE;
6466

6567
let report_enabled = is_true(opts.print_file_reports);
66-
let timing = unsafe { opts.timing.as_mut() }.unwrap();
68+
let timing = opts.timing;
6769

6870
// unlike C, here the decoders are allocated on the stack as an array.
6971
let decoders = {
70-
const INIT: Option<dtvcc_service_decoder> = None;
72+
const INIT: Option<Box<dtvcc_service_decoder>> = None;
7173
let mut decoders = [INIT; CCX_DTVCC_MAX_SERVICES];
7274

7375
decoders
@@ -79,7 +81,7 @@ impl<'a> Dtvcc<'a> {
7981
return;
8082
}
8183

82-
let mut decoder = dtvcc_service_decoder {
84+
let mut decoder = Box::new(dtvcc_service_decoder {
8385
// we cannot allocate this on the stack as `dtvcc_service_decoder` is a C
8486
// struct cannot be changed trivially
8587
tv: Box::into_raw(Box::new(dtvcc_tv_screen {
@@ -88,27 +90,27 @@ impl<'a> Dtvcc<'a> {
8890
..dtvcc_tv_screen::default()
8991
})),
9092
..dtvcc_service_decoder::default()
91-
};
93+
});
9294

9395
decoder.windows.iter_mut().for_each(|w| {
9496
w.memory_reserved = 0;
9597
});
9698

97-
unsafe { dtvcc_windows_reset(&mut decoder) };
99+
unsafe { dtvcc_windows_reset(decoder.as_mut()) };
98100

99101
*d = Some(decoder);
100102
});
101103

102104
decoders
103105
};
104106

105-
let encoder = None; // Unlike C, does not mention `encoder` and is initialised to `null` by default
107+
let encoder = std::ptr::null_mut(); // Unlike C, does not mention `encoder` and is initialised to `null` by default
106108

107109
Self {
108110
report,
109111
is_active,
110-
no_rollup: _no_rollup,
111-
active_services_count: _active_services_count,
112+
no_rollup,
113+
active_services_count,
112114
services_active,
113115
packet_length,
114116
is_header_parsed,
@@ -223,15 +225,15 @@ impl<'a> Dtvcc<'a> {
223225
}
224226

225227
if block_length != 0 {
226-
self.report.services[service_number as usize] = 1;
228+
unsafe { (*self.report).services[service_number as usize] = 1 };
227229
}
228230

229231
if service_number > 0 && is_true(self.services_active[(service_number - 1) as usize]) {
230232
let decoder = &mut self.decoders[(service_number - 1) as usize];
231-
decoder.unwrap().process_service_block(
233+
decoder.as_mut().unwrap().process_service_block(
232234
&self.packet[pos as usize..(pos + block_length) as usize],
233-
self.encoder.as_mut().unwrap(),
234-
self.timing,
235+
unsafe { self.encoder.as_mut().unwrap() },
236+
unsafe { self.timing.as_mut().unwrap() },
235237
self.no_rollup,
236238
);
237239
}
@@ -254,11 +256,11 @@ impl<'a> Dtvcc<'a> {
254256
}
255257
}
256258

257-
impl<'a> Drop for Dtvcc<'a> {
259+
impl Drop for Dtvcc {
258260
fn drop(&mut self) {
259261
// closely follows `dtvcc_free` at `src/lib_ccx/ccx_dtvcc.c:126`
260262
for i in 0..CCX_DTVCC_MAX_SERVICES {
261-
if let Some(mut decoder) = self.decoders[i] {
263+
if let Some(decoder) = self.decoders[i].as_mut() {
262264
if !is_true(self.services_active[i]) {
263265
continue;
264266
}
@@ -275,9 +277,7 @@ impl<'a> Drop for Dtvcc<'a> {
275277
window.memory_reserved = 0;
276278
});
277279

278-
unsafe {
279-
decoder.tv.drop_in_place();
280-
}
280+
unsafe { decoder.tv.drop_in_place() };
281281
}
282282
}
283283
}

src/rust/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ pub extern "C" fn ccxr_init_logger() {
5252
/// - opts.report
5353
/// - opts.timing
5454
#[no_mangle]
55-
extern "C" fn ccxr_dtvcc_init<'a>(opts: *mut ccx_decoder_dtvcc_settings) -> *mut Dtvcc<'a> {
56-
Box::into_raw(Box::new(Dtvcc::new(unsafe { opts.as_mut() }.unwrap())))
55+
extern "C" fn ccxr_dtvcc_init(opts_ptr: *const ccx_decoder_dtvcc_settings) -> *mut Dtvcc {
56+
let opts = unsafe { opts_ptr.as_ref() }.unwrap();
57+
Box::into_raw(Box::new(Dtvcc::new(opts)))
5758
}
5859

5960
/// Frees `dtvcc_rust`
@@ -72,7 +73,7 @@ extern "C" fn ccxr_dtvcc_free(dtvcc_rust: *mut Dtvcc) {
7273

7374
#[no_mangle]
7475
extern "C" fn ccxr_dtvcc_set_encoder(dtvcc_rust: *mut Dtvcc, encoder: *mut encoder_ctx) {
75-
unsafe { dtvcc_rust.as_mut() }.unwrap().encoder = Some(unsafe { encoder.as_mut() }.unwrap());
76+
unsafe { (*dtvcc_rust).encoder = encoder };
7677
}
7778

7879
/// Process cc_data
@@ -140,7 +141,7 @@ pub fn verify_parity(data: u8) -> bool {
140141

141142
/// Process CC data according to its type
142143
pub fn do_cb(ctx: &mut lib_cc_decode, cc_block: &[u8]) -> bool {
143-
let dtvcc = unsafe { &mut *(ctx.dtvcc_rust as *mut decoder::Dtvcc<'_>) };
144+
let dtvcc = unsafe { &mut *(ctx.dtvcc_rust as *mut decoder::Dtvcc) };
144145
let cc_valid = (cc_block[0] & 4) >> 2;
145146
let cc_type = cc_block[0] & 3;
146147
let mut timeok = true;

0 commit comments

Comments
 (0)