Skip to content

Commit 642e741

Browse files
committed
Questionable implementation of ccxr_dtvcc_free
1 parent 3629c88 commit 642e741

File tree

2 files changed

+76
-27
lines changed

2 files changed

+76
-27
lines changed

src/rust/src/decoder/mod.rs

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ mod timing;
99
mod tv_screen;
1010
mod window;
1111

12-
use crate::{bindings::*, utils::is_true};
12+
use crate::{
13+
bindings::*,
14+
utils::{is_false, is_true},
15+
};
1316

1417
use log::{debug, warn};
1518

@@ -20,6 +23,7 @@ const CCX_DTVCC_SCREENGRID_COLUMNS: u8 = 210;
2023
const CCX_DTVCC_MAX_ROWS: u8 = 15;
2124
const CCX_DTVCC_MAX_COLUMNS: u8 = 32 * 2;
2225
const CCX_DTVCC_MAX_SERVICES: usize = 63;
26+
const CCX_DTVCC_MAX_WINDOWS: usize = 8;
2327

2428
/// Context required for processing 708 data
2529
pub struct Dtvcc<'a> {
@@ -28,7 +32,7 @@ pub struct Dtvcc<'a> {
2832
pub services_active: [i32; CCX_DTVCC_MAX_SERVICES],
2933
pub report_enabled: bool,
3034
pub report: &'a mut ccx_decoder_dtvcc_report,
31-
pub decoders: [Option<&'a mut dtvcc_service_decoder>; CCX_DTVCC_MAX_SERVICES],
35+
pub decoders: [Option<dtvcc_service_decoder>; CCX_DTVCC_MAX_SERVICES],
3236
pub packet: [u8; CCX_DTVCC_MAX_SERVICES],
3337
pub packet_length: u8,
3438
pub is_header_parsed: bool,
@@ -40,34 +44,39 @@ pub struct Dtvcc<'a> {
4044

4145
impl<'a> Dtvcc<'a> {
4246
/// Create a new dtvcc context
43-
pub fn new(opts: &'a mut ccx_decoder_dtvcc_settings) -> Self {
47+
pub fn new<'b>(opts: &'b mut ccx_decoder_dtvcc_settings) -> Self {
4448
let report = unsafe { &mut *opts.report };
4549
report.reset_count = 0;
4650

47-
const INIT: Option<&mut dtvcc_service_decoder> = None;
48-
let decoders = [INIT; CCX_DTVCC_MAX_SERVICES];
49-
decoders.iter_mut().enumerate().for_each(|(i, val)| {
50-
if !is_true(opts.services_enabled[i]) {
51-
return;
52-
}
51+
let decoders = {
52+
const INIT: Option<dtvcc_service_decoder> = None;
53+
let val = [INIT; CCX_DTVCC_MAX_SERVICES];
54+
55+
for i in 0..CCX_DTVCC_MAX_SERVICES {
56+
if !is_true(opts.services_enabled[i]) {
57+
continue;
58+
}
59+
60+
let decoder = dtvcc_service_decoder {
61+
tv: Box::into_raw(Box::new(dtvcc_tv_screen {
62+
cc_count: 0,
63+
service_number: i as i32 + 1,
64+
..dtvcc_tv_screen::default()
65+
})),
66+
..dtvcc_service_decoder::default()
67+
};
5368

54-
let decoder = Box::leak(Box::new(dtvcc_service_decoder {
55-
tv: Box::leak(Box::new(dtvcc_tv_screen {
56-
cc_count: 0,
57-
service_number: i as i32 + 1,
58-
..dtvcc_tv_screen::default()
59-
})),
60-
..dtvcc_service_decoder::default()
61-
}));
69+
decoder.windows.iter_mut().for_each(|w| {
70+
w.memory_reserved = 0;
71+
});
6272

63-
decoder.windows.iter_mut().for_each(|w| {
64-
w.memory_reserved = 0;
65-
});
73+
unsafe { dtvcc_windows_reset(&mut decoder) };
6674

67-
unsafe { dtvcc_windows_reset(decoder) };
75+
val[i] = Some(decoder);
76+
}
6877

69-
val = &mut Some(decoder);
70-
});
78+
val
79+
};
7180

7281
for i in 0..CCX_DTVCC_MAX_SERVICES {
7382
if !is_true(opts.services_enabled[i]) {
@@ -92,9 +101,8 @@ impl<'a> Dtvcc<'a> {
92101
timing: unsafe { &mut *opts.timing },
93102
encoder: None,
94103
}
95-
96-
// notes: import CCX_DTVCC_MAX_SERVICES, initialize the decoders
97104
}
105+
98106
/// Process cc data and add it to the dtvcc packet
99107
pub fn process_cc_data(&mut self, cc_valid: u8, cc_type: u8, data1: u8, data2: u8) {
100108
if !self.is_active && !self.report_enabled {
@@ -202,9 +210,9 @@ impl<'a> Dtvcc<'a> {
202210

203211
if service_number > 0 && is_true(self.services_active[(service_number - 1) as usize]) {
204212
let decoder = &mut self.decoders[(service_number - 1) as usize];
205-
decoder.process_service_block(
213+
decoder.unwrap().process_service_block(
206214
&self.packet[pos as usize..(pos + block_length) as usize],
207-
self.encoder,
215+
self.encoder.unwrap(),
208216
self.timing,
209217
self.no_rollup,
210218
);
@@ -228,6 +236,37 @@ impl<'a> Dtvcc<'a> {
228236
}
229237
}
230238

239+
impl<'a> Drop for Dtvcc<'a> {
240+
fn drop(&mut self) {
241+
for i in 0..CCX_DTVCC_MAX_SERVICES {
242+
match self.decoders[i] {
243+
Some(decoder) => {
244+
if !is_true(self.services_active[i]) {
245+
continue;
246+
}
247+
248+
decoder.windows.iter().for_each(|window| {
249+
if is_false(window.memory_reserved) {
250+
return;
251+
}
252+
253+
window.rows.iter().for_each(|symbol_ptr| unsafe {
254+
symbol_ptr.drop_in_place();
255+
});
256+
257+
window.memory_reserved = 0;
258+
});
259+
260+
unsafe {
261+
decoder.tv.drop_in_place();
262+
}
263+
}
264+
None => {}
265+
}
266+
}
267+
}
268+
}
269+
231270
/// A single character symbol
232271
///
233272
/// sym stores the symbol

src/rust/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ pub extern "C" fn ccxr_init_logger() {
4444
.init();
4545
}
4646

47+
#[no_mangle]
48+
extern "C" fn ccxr_dtvcc_init<'a>(opts: *mut ccx_decoder_dtvcc_settings) -> *mut Dtvcc<'a> {
49+
Box::into_raw(Box::new(Dtvcc::new(unsafe { opts.as_mut() }.unwrap())))
50+
}
51+
52+
#[no_mangle]
53+
extern "C" fn ccxr_dtvcc_free(dtvcc: *mut Dtvcc) {
54+
unsafe { dtvcc.drop_in_place() };
55+
}
56+
4757
/// Process cc_data
4858
///
4959
/// # Safety

0 commit comments

Comments
 (0)