@@ -45,6 +45,57 @@ pub extern "C" fn ccxr_init_logger() {
45
45
. init ( ) ;
46
46
}
47
47
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
+
48
99
/// Process cc_data
49
100
///
50
101
/// # Safety
@@ -61,13 +112,11 @@ extern "C" fn ccxr_process_cc_data(
61
112
. map ( |x| unsafe { * data. add ( x as usize ) } )
62
113
. collect ( ) ;
63
114
let dec_ctx = unsafe { & mut * dec_ctx } ;
64
- let dtvcc_ctx = unsafe { & mut * dec_ctx. dtvcc } ;
65
- let mut dtvcc = Dtvcc :: new ( dtvcc_ctx) ;
66
115
for cc_block in cc_data. chunks_exact_mut ( 3 ) {
67
116
if !validate_cc_pair ( cc_block) {
68
117
continue ;
69
118
}
70
- let success = do_cb ( dec_ctx, & mut dtvcc , cc_block) ;
119
+ let success = do_cb ( dec_ctx, cc_block) ;
71
120
if success {
72
121
ret = 0 ;
73
122
}
@@ -111,7 +160,8 @@ pub fn verify_parity(data: u8) -> bool {
111
160
}
112
161
113
162
/// 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 ) } ;
115
165
let cc_valid = ( cc_block[ 0 ] & 4 ) >> 2 ;
116
166
let cc_type = cc_block[ 0 ] & 3 ;
117
167
let mut timeok = true ;
0 commit comments