12
12
13
13
use std:: collections:: VecDeque ;
14
14
15
- use tables:: { Channel , Code , MidRow , PreambleAddressCode } ;
15
+ use tables:: { Channel , Code , Field , MidRow , PreambleAddressCode } ;
16
16
17
17
#[ macro_use]
18
18
extern crate log;
@@ -147,10 +147,13 @@ impl Cea608 {
147
147
/// Helper struct that has two purposes:
148
148
/// 1. Tracks the previous data for control code de-duplication
149
149
/// 2. Adds the last received channel to non control codes.
150
+ ///
151
+ /// This object only keeps data for a single [`Field`]
150
152
#[ derive( Debug , Default ) ]
151
153
pub struct Cea608State {
152
154
last_data : Option < [ u8 ; 2 ] > ,
153
155
last_channel : Option < Channel > ,
156
+ last_received_field : Option < Field > ,
154
157
}
155
158
156
159
impl Cea608State {
@@ -173,6 +176,9 @@ impl Cea608State {
173
176
[ Code :: Control ( control_code) , _] => {
174
177
let channel = control_code. channel ( ) ;
175
178
self . last_channel = Some ( channel) ;
179
+ if let Some ( field) = control_code. field ( ) {
180
+ self . last_received_field = Some ( field) ;
181
+ }
176
182
Ok ( Some ( match control_code. code ( ) {
177
183
tables:: Control :: MidRow ( midrow) => Cea608 :: MidRowChange ( channel, midrow) ,
178
184
tables:: Control :: PreambleAddress ( preamble) => {
@@ -229,6 +235,12 @@ impl Cea608State {
229
235
}
230
236
}
231
237
238
+ /// The [`Field`] that some specific [`tables::Control`] codes referenced. Can be used to detect field
239
+ /// reversal of the incoming data.
240
+ pub fn last_received_field ( & self ) -> Option < Field > {
241
+ self . last_received_field
242
+ }
243
+
232
244
/// Reset the state to that of an initially constructed object.
233
245
pub fn reset ( & mut self ) {
234
246
* self = Self :: default ( ) ;
@@ -307,6 +319,55 @@ impl Cea608Writer {
307
319
}
308
320
}
309
321
322
+ /// A CEA-608 caption identifier unique within a CEA-608 stream
323
+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
324
+ pub enum Id {
325
+ CC1 ,
326
+ CC2 ,
327
+ CC3 ,
328
+ CC4 ,
329
+ // TODO: add Text1/2
330
+ }
331
+
332
+ impl Id {
333
+ /// The [`Field`] that this [`Id`] is contained within
334
+ pub fn field ( & self ) -> Field {
335
+ match self {
336
+ Self :: CC1 | Self :: CC2 => Field :: ONE ,
337
+ Self :: CC3 | Self :: CC4 => Field :: TWO ,
338
+ }
339
+ }
340
+
341
+ /// The caption [`Channel`] that this [`Id`] references
342
+ pub fn channel ( & self ) -> Channel {
343
+ match self {
344
+ Self :: CC1 | Self :: CC3 => Channel :: ONE ,
345
+ Self :: CC2 | Self :: CC4 => Channel :: TWO ,
346
+ }
347
+ }
348
+
349
+ /// Construct an [`Id`] from a [`Field`] and [`Channel`]
350
+ pub fn from_caption_field_channel ( field : Field , channel : Channel ) -> Self {
351
+ match ( field, channel) {
352
+ ( Field :: ONE , Channel :: ONE ) => Self :: CC1 ,
353
+ ( Field :: ONE , Channel :: TWO ) => Self :: CC2 ,
354
+ ( Field :: TWO , Channel :: ONE ) => Self :: CC3 ,
355
+ ( Field :: TWO , Channel :: TWO ) => Self :: CC4 ,
356
+ }
357
+ }
358
+
359
+ /// Construct an [`Id`] from its integer value in the range [1, 4]
360
+ pub fn from_value ( value : i8 ) -> Self {
361
+ match value {
362
+ 1 => Self :: CC1 ,
363
+ 2 => Self :: CC2 ,
364
+ 3 => Self :: CC3 ,
365
+ 4 => Self :: CC4 ,
366
+ _ => unreachable ! ( ) ,
367
+ }
368
+ }
369
+ }
370
+
310
371
#[ cfg( test) ]
311
372
mod test {
312
373
use self :: tables:: ControlCode ;
@@ -319,17 +380,20 @@ mod test {
319
380
test_init_log ( ) ;
320
381
let mut data = vec ! [ ] ;
321
382
Code :: Control ( ControlCode :: new (
322
- Channel ( true ) ,
383
+ Field :: ONE ,
384
+ Channel :: ONE ,
323
385
tables:: Control :: EraseDisplayedMemory ,
324
386
) )
325
387
. write ( & mut data)
326
388
. unwrap ( ) ;
327
389
let mut state = Cea608State :: default ( ) ;
328
390
assert_eq ! (
329
- Ok ( Some ( Cea608 :: EraseDisplay ( Channel ( true ) ) ) ) ,
391
+ Ok ( Some ( Cea608 :: EraseDisplay ( Channel :: ONE ) ) ) ,
330
392
state. decode( [ data[ 0 ] , data[ 1 ] ] )
331
393
) ;
394
+ assert_eq ! ( state. last_received_field( ) , Some ( Field :: ONE ) ) ;
332
395
assert_eq ! ( Ok ( None ) , state. decode( [ data[ 0 ] , data[ 1 ] ] ) ) ;
396
+ assert_eq ! ( state. last_received_field( ) , Some ( Field :: ONE ) ) ;
333
397
}
334
398
335
399
#[ test]
@@ -338,13 +402,18 @@ mod test {
338
402
let mut state = Cea608State :: default ( ) ;
339
403
340
404
let mut data = vec ! [ ] ;
341
- Code :: Control ( ControlCode :: new ( Channel :: ONE , tables:: Control :: RollUp2 ) )
342
- . write ( & mut data)
343
- . unwrap ( ) ;
405
+ Code :: Control ( ControlCode :: new (
406
+ Field :: ONE ,
407
+ Channel :: ONE ,
408
+ tables:: Control :: RollUp2 ,
409
+ ) )
410
+ . write ( & mut data)
411
+ . unwrap ( ) ;
344
412
assert_eq ! (
345
413
Ok ( Some ( Cea608 :: NewMode ( Channel :: ONE , Mode :: RollUp2 ) ) ) ,
346
414
state. decode( [ data[ 0 ] , data[ 1 ] ] )
347
415
) ;
416
+ assert_eq ! ( state. last_received_field( ) , Some ( Field :: ONE ) ) ;
348
417
349
418
let mut data = vec ! [ ] ;
350
419
Code :: LatinCapitalA . write ( & mut data) . unwrap ( ) ;
@@ -357,15 +426,21 @@ mod test {
357
426
} ) ) ) ,
358
427
state. decode( [ data[ 0 ] , 0x80 ] )
359
428
) ;
429
+ assert_eq ! ( state. last_received_field( ) , Some ( Field :: ONE ) ) ;
360
430
361
431
let mut data = vec ! [ ] ;
362
- Code :: Control ( ControlCode :: new ( Channel :: TWO , tables:: Control :: RollUp2 ) )
363
- . write ( & mut data)
364
- . unwrap ( ) ;
432
+ Code :: Control ( ControlCode :: new (
433
+ Field :: TWO ,
434
+ Channel :: TWO ,
435
+ tables:: Control :: RollUp2 ,
436
+ ) )
437
+ . write ( & mut data)
438
+ . unwrap ( ) ;
365
439
assert_eq ! (
366
440
Ok ( Some ( Cea608 :: NewMode ( Channel :: TWO , Mode :: RollUp2 ) ) ) ,
367
441
state. decode( [ data[ 0 ] , data[ 1 ] ] )
368
442
) ;
443
+ assert_eq ! ( state. last_received_field( ) , Some ( Field :: TWO ) ) ;
369
444
370
445
let mut data = vec ! [ ] ;
371
446
Code :: LatinCapitalA . write ( & mut data) . unwrap ( ) ;
@@ -412,6 +487,7 @@ mod test {
412
487
let mut writer = Cea608Writer :: default ( ) ;
413
488
writer. push ( Code :: LatinLowerA ) ;
414
489
writer. push ( Code :: Control ( ControlCode :: new (
490
+ Field :: ONE ,
415
491
Channel :: ONE ,
416
492
tables:: Control :: DegreeSign ,
417
493
) ) ) ;
@@ -426,6 +502,7 @@ mod test {
426
502
let mut writer = Cea608Writer :: default ( ) ;
427
503
writer. push ( Code :: LatinLowerA ) ;
428
504
writer. push ( Code :: Control ( ControlCode :: new (
505
+ Field :: ONE ,
429
506
Channel :: ONE ,
430
507
tables:: Control :: Tilde ,
431
508
) ) ) ;
@@ -439,6 +516,7 @@ mod test {
439
516
test_init_log ( ) ;
440
517
let mut writer = Cea608Writer :: default ( ) ;
441
518
writer. push ( Code :: Control ( ControlCode :: new (
519
+ Field :: ONE ,
442
520
Channel :: ONE ,
443
521
tables:: Control :: Tilde ,
444
522
) ) ) ;
@@ -452,6 +530,7 @@ mod test {
452
530
test_init_log ( ) ;
453
531
let mut writer = Cea608Writer :: default ( ) ;
454
532
writer. push ( Code :: Control ( ControlCode :: new (
533
+ Field :: ONE ,
455
534
Channel :: ONE ,
456
535
tables:: Control :: DegreeSign ,
457
536
) ) ) ;
0 commit comments