@@ -367,6 +367,7 @@ pub extern "C" fn ccxr_dtvcc_is_active(dtvcc_ptr: *mut std::ffi::c_void) -> i32
367367/// # Safety
368368/// dec_ctx should not be a null pointer
369369/// data should point to cc_data of length cc_count
370+ /// dec_ctx.dtvcc_rust must point to a valid DtvccRust instance
370371#[ no_mangle]
371372extern "C" fn ccxr_process_cc_data (
372373 dec_ctx : * mut lib_cc_decode ,
@@ -378,13 +379,20 @@ extern "C" fn ccxr_process_cc_data(
378379 . map ( |x| unsafe { * data. add ( x as usize ) } )
379380 . collect ( ) ;
380381 let dec_ctx = unsafe { & mut * dec_ctx } ;
381- let dtvcc_ctx = unsafe { & mut * dec_ctx. dtvcc } ;
382- let mut dtvcc = Dtvcc :: new ( dtvcc_ctx) ;
382+
383+ // Use the persistent DtvccRust context from dtvcc_rust
384+ let dtvcc_rust = dec_ctx. dtvcc_rust as * mut DtvccRust ;
385+ if dtvcc_rust. is_null ( ) {
386+ warn ! ( "ccxr_process_cc_data: dtvcc_rust is null" ) ;
387+ return ret;
388+ }
389+ let dtvcc = unsafe { & mut * dtvcc_rust } ;
390+
383391 for cc_block in cc_data. chunks_exact_mut ( 3 ) {
384392 if !validate_cc_pair ( cc_block) {
385393 continue ;
386394 }
387- let success = do_cb_dtvcc ( dec_ctx, & mut dtvcc, cc_block) ;
395+ let success = do_cb_dtvcc_rust ( dec_ctx, dtvcc, cc_block) ;
388396 if success {
389397 ret = 0 ;
390398 }
@@ -427,7 +435,7 @@ pub fn verify_parity(data: u8) -> bool {
427435 false
428436}
429437
430- /// Process CC data according to its type
438+ /// Process CC data according to its type (using Dtvcc)
431439pub fn do_cb_dtvcc ( ctx : & mut lib_cc_decode , dtvcc : & mut Dtvcc , cc_block : & [ u8 ] ) -> bool {
432440 let cc_valid = ( cc_block[ 0 ] & 4 ) >> 2 ;
433441 let cc_type = cc_block[ 0 ] & 3 ;
@@ -478,6 +486,57 @@ pub fn do_cb_dtvcc(ctx: &mut lib_cc_decode, dtvcc: &mut Dtvcc, cc_block: &[u8])
478486 true
479487}
480488
489+ /// Process CC data according to its type (using DtvccRust - persistent context)
490+ pub fn do_cb_dtvcc_rust ( ctx : & mut lib_cc_decode , dtvcc : & mut DtvccRust , cc_block : & [ u8 ] ) -> bool {
491+ let cc_valid = ( cc_block[ 0 ] & 4 ) >> 2 ;
492+ let cc_type = cc_block[ 0 ] & 3 ;
493+ let mut timeok = true ;
494+
495+ if ctx. write_format != ccx_output_format:: CCX_OF_DVDRAW
496+ && ctx. write_format != ccx_output_format:: CCX_OF_RAW
497+ && ( cc_block[ 0 ] == 0xFA || cc_block[ 0 ] == 0xFC || cc_block[ 0 ] == 0xFD )
498+ && ( cc_block[ 1 ] & 0x7F ) == 0
499+ && ( cc_block[ 2 ] & 0x7F ) == 0
500+ {
501+ return true ;
502+ }
503+
504+ if cc_valid == 1 || cc_type == 3 {
505+ ctx. cc_stats [ cc_type as usize ] += 1 ;
506+ match cc_type {
507+ // Type 0 and 1 are for CEA-608 data. Handled by C code, do nothing
508+ 0 | 1 => { }
509+ // Type 2 and 3 are for CEA-708 data.
510+ 2 | 3 => {
511+ let current_time = if ctx. timing . is_null ( ) {
512+ 0
513+ } else {
514+ unsafe { ( * ctx. timing ) . get_fts ( ctx. current_field as u8 ) }
515+ } ;
516+ ctx. current_field = 3 ;
517+
518+ // Check whether current time is within start and end bounds
519+ if is_true ( ctx. extraction_start . set )
520+ && current_time < ctx. extraction_start . time_in_ms
521+ {
522+ timeok = false ;
523+ }
524+ if is_true ( ctx. extraction_end . set ) && current_time > ctx. extraction_end . time_in_ms {
525+ timeok = false ;
526+ ctx. processed_enough = 1 ;
527+ }
528+
529+ if timeok && ctx. write_format != ccx_output_format:: CCX_OF_RAW {
530+ dtvcc. process_cc_data ( cc_valid, cc_type, cc_block[ 1 ] , cc_block[ 2 ] ) ;
531+ }
532+ unsafe { cb_708 += 1 }
533+ }
534+ _ => warn ! ( "Invalid cc_type" ) ,
535+ }
536+ }
537+ true
538+ }
539+
481540#[ cfg( windows) ]
482541#[ no_mangle]
483542extern "C" fn ccxr_close_handle ( handle : RawHandle ) {
0 commit comments