@@ -9,7 +9,10 @@ mod timing;
9
9
mod tv_screen;
10
10
mod window;
11
11
12
- use crate :: { bindings:: * , utils:: is_true} ;
12
+ use crate :: {
13
+ bindings:: * ,
14
+ utils:: { is_false, is_true} ,
15
+ } ;
13
16
14
17
use log:: { debug, warn} ;
15
18
@@ -20,6 +23,7 @@ const CCX_DTVCC_SCREENGRID_COLUMNS: u8 = 210;
20
23
const CCX_DTVCC_MAX_ROWS : u8 = 15 ;
21
24
const CCX_DTVCC_MAX_COLUMNS : u8 = 32 * 2 ;
22
25
const CCX_DTVCC_MAX_SERVICES : usize = 63 ;
26
+ const CCX_DTVCC_MAX_WINDOWS : usize = 8 ;
23
27
24
28
/// Context required for processing 708 data
25
29
pub struct Dtvcc < ' a > {
@@ -28,7 +32,7 @@ pub struct Dtvcc<'a> {
28
32
pub services_active : [ i32 ; CCX_DTVCC_MAX_SERVICES ] ,
29
33
pub report_enabled : bool ,
30
34
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 ] ,
32
36
pub packet : [ u8 ; CCX_DTVCC_MAX_SERVICES ] ,
33
37
pub packet_length : u8 ,
34
38
pub is_header_parsed : bool ,
@@ -40,34 +44,39 @@ pub struct Dtvcc<'a> {
40
44
41
45
impl < ' a > Dtvcc < ' a > {
42
46
/// 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 {
44
48
let report = unsafe { & mut * opts. report } ;
45
49
report. reset_count = 0 ;
46
50
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
+ } ;
53
68
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
+ } ) ;
62
72
63
- decoder. windows . iter_mut ( ) . for_each ( |w| {
64
- w. memory_reserved = 0 ;
65
- } ) ;
73
+ unsafe { dtvcc_windows_reset ( & mut decoder) } ;
66
74
67
- unsafe { dtvcc_windows_reset ( decoder) } ;
75
+ val[ i] = Some ( decoder) ;
76
+ }
68
77
69
- val = & mut Some ( decoder ) ;
70
- } ) ;
78
+ val
79
+ } ;
71
80
72
81
for i in 0 ..CCX_DTVCC_MAX_SERVICES {
73
82
if !is_true ( opts. services_enabled [ i] ) {
@@ -92,9 +101,8 @@ impl<'a> Dtvcc<'a> {
92
101
timing : unsafe { & mut * opts. timing } ,
93
102
encoder : None ,
94
103
}
95
-
96
- // notes: import CCX_DTVCC_MAX_SERVICES, initialize the decoders
97
104
}
105
+
98
106
/// Process cc data and add it to the dtvcc packet
99
107
pub fn process_cc_data ( & mut self , cc_valid : u8 , cc_type : u8 , data1 : u8 , data2 : u8 ) {
100
108
if !self . is_active && !self . report_enabled {
@@ -202,9 +210,9 @@ impl<'a> Dtvcc<'a> {
202
210
203
211
if service_number > 0 && is_true ( self . services_active [ ( service_number - 1 ) as usize ] ) {
204
212
let decoder = & mut self . decoders [ ( service_number - 1 ) as usize ] ;
205
- decoder. process_service_block (
213
+ decoder. unwrap ( ) . process_service_block (
206
214
& self . packet [ pos as usize ..( pos + block_length) as usize ] ,
207
- self . encoder ,
215
+ self . encoder . unwrap ( ) ,
208
216
self . timing ,
209
217
self . no_rollup ,
210
218
) ;
@@ -228,6 +236,37 @@ impl<'a> Dtvcc<'a> {
228
236
}
229
237
}
230
238
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
+
231
270
/// A single character symbol
232
271
///
233
272
/// sym stores the symbol
0 commit comments