Skip to content

Commit 9822e41

Browse files
feat: Create ccxr_dtvcc_init & ccxr_dtvcc_free
1 parent 08d70e7 commit 9822e41

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

src/rust/src/lib.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,57 @@ pub extern "C" fn ccxr_init_logger() {
4545
.init();
4646
}
4747

48+
/// Create a `dtvcc_rust`
49+
///
50+
/// SAFETY:
51+
/// The following should not be `NULL`:
52+
/// - opts
53+
/// - opts.report
54+
/// - opts.timing
55+
#[no_mangle]
56+
extern "C" fn ccxr_dtvcc_init<'a>(opts_ptr: *const ccx_decoder_dtvcc_settings) -> *mut Dtvcc<'a> {
57+
let opts = unsafe { opts_ptr.as_ref() }.unwrap();
58+
Box::into_raw(Box::new(Dtvcc::new(opts)))
59+
}
60+
61+
/// Frees `dtvcc_rust`
62+
///
63+
/// SAFETY:
64+
/// The following should not be `NULL`:
65+
/// - dtvcc_rust
66+
/// - dtvcc_rust.decoders[i] if dtvcc_rust.services_active[i] is true
67+
/// - dtvcc_rust.decoders[i].windows[j].rows[k] if
68+
/// dtvcc_rust.decoders[i].windows[j].memory_reserved is true
69+
/// - dtvcc_rust.decoders[i].tv
70+
#[no_mangle]
71+
extern "C" fn ccxr_dtvcc_free(dtvcc_rust: *mut Dtvcc) {
72+
let dtvcc = unsafe { dtvcc_rust.read() };
73+
74+
// closely follows `dtvcc_free` at `src/lib_ccx/ccx_dtvcc.c:126`
75+
for i in 0..decoder::CCX_DTVCC_MAX_SERVICES {
76+
if utils::is_false(dtvcc.services_active[i]) {
77+
continue;
78+
}
79+
80+
let decoder = unsafe { &mut dtvcc.decoders[i].read() };
81+
82+
decoder.windows.iter_mut().for_each(|window| {
83+
if utils::is_false(window.memory_reserved) {
84+
return;
85+
}
86+
87+
// Drop all windows row
88+
window.rows.iter().for_each(|symbol_ptr| unsafe {
89+
symbol_ptr.drop_in_place();
90+
});
91+
92+
window.memory_reserved = 0;
93+
});
94+
95+
unsafe { decoder.tv.drop_in_place() };
96+
}
97+
}
98+
4899
/// Process cc_data
49100
///
50101
/// # Safety
@@ -61,13 +112,11 @@ extern "C" fn ccxr_process_cc_data(
61112
.map(|x| unsafe { *data.add(x as usize) })
62113
.collect();
63114
let dec_ctx = unsafe { &mut *dec_ctx };
64-
let dtvcc_ctx = unsafe { &mut *dec_ctx.dtvcc };
65-
let mut dtvcc = Dtvcc::new(dtvcc_ctx);
66115
for cc_block in cc_data.chunks_exact_mut(3) {
67116
if !validate_cc_pair(cc_block) {
68117
continue;
69118
}
70-
let success = do_cb(dec_ctx, &mut dtvcc, cc_block);
119+
let success = do_cb(dec_ctx, cc_block);
71120
if success {
72121
ret = 0;
73122
}
@@ -111,7 +160,8 @@ pub fn verify_parity(data: u8) -> bool {
111160
}
112161

113162
/// Process CC data according to its type
114-
pub fn do_cb(ctx: &mut lib_cc_decode, dtvcc: &mut Dtvcc, cc_block: &[u8]) -> bool {
163+
pub fn do_cb(ctx: &mut lib_cc_decode, cc_block: &[u8]) -> bool {
164+
let dtvcc = unsafe { &mut *(ctx.dtvcc_rust as *mut Dtvcc) };
115165
let cc_valid = (cc_block[0] & 4) >> 2;
116166
let cc_type = cc_block[0] & 3;
117167
let mut timeok = true;

0 commit comments

Comments
 (0)