+ cc_AppendData( c, i_field, &cc[1] );
+ }
+ c->b_reorder = true;
+ }
+ else if( !memcmp( p_cc_dvd, p_src, 4 ) && i_src > 4+1 )
+ {
+ /* DVD CC */
+ const int b_truncate = p_src[4] & 0x01;
+ const int i_field_first = (p_src[4] & 0x80) ? 0 : 1;
+ const int i_count_cc2 = (p_src[4] >> 1) & 0xf;
+ const uint8_t *cc = &p_src[5];
+ int i;
+
+ if( i_src < 4+1+6*i_count_cc2 - ( b_truncate ? 3 : 0) )
+ return;
+ for( i = 0; i < i_count_cc2; i++ )
+ {
+ int j;
+ for( j = 0; j < 2; j++, cc += 3 )
+ {
+ const int i_field = j == i_field_first ? 0 : 1;
+
+ if( b_truncate && i == i_count_cc2 - 1 && j == 1 )
+ break;
+ if( cc[0] != 0xff && cc[0] != 0xfe )
+ continue;
+ if( c->i_data + 3 > CC_MAX_DATA_SIZE )
+ continue;
+
+ cc_AppendData( c, i_field, &cc[1] );
+ }
+ }
+ c->b_reorder = false;
+ }
+ else if( i_src >= 2+2 + 2+2 &&
+ ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
+ ( !memcmp( p_cc_replaytv5a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv5b, &p_src[4], 2 ) ) ) )
+ {
+ /* ReplayTV CC */
+ const uint8_t *cc = &p_src[0];
+ int i;
+ if( c->i_data + 2*3 > CC_MAX_DATA_SIZE )
+ return;
+
+ for( i = 0; i < 2; i++, cc += 4 )
+ {
+ const int i_field = i == 0 ? 1 : 0;
+
+ cc_AppendData( c, i_field, &cc[2] );
+ }
+ c->b_reorder = false;
+ }
+ else if( !memcmp( p_cc_scte20, p_src, 2 ) && i_src > 2 )
+ {
+ /* SCTE-20 CC */
+ bs_t s;
+ bs_init( &s, &p_src[2], i_src - 2 );
+ const int i_cc_count = bs_read( &s, 5 );
+ for( int i = 0; i < i_cc_count; i++ )
+ {
+ bs_skip( &s, 2 );
+ const int i_field_idx = bs_read( &s, 2 );
+ bs_skip( &s, 5 );
+ uint8_t cc[2];
+ for( int j = 0; j < 2; j++ )
+ {
+ cc[j] = 0;
+ for( int k = 0; k < 8; k++ )
+ cc[j] |= bs_read( &s, 1 ) << k;
+ }
+ bs_skip( &s, 1 );
+
+ if( i_field_idx != 1 && i_field_idx != 2 )
+ continue;
+ if( c->i_data + 2*3 > CC_MAX_DATA_SIZE )
+ continue;
+
+ const int i_field = i_field_idx - 1;