void xds_debug_test() { process_xds_bytes (0x05,0x02); process_xds_bytes (0x20,0x20); do_end_of_xds (0x2a); }
void xds_debug_test(struct ccx_decoders_xds_context *ctx, struct cc_subtitle *sub) { process_xds_bytes (ctx, 0x05, 0x02); process_xds_bytes (ctx, 0x20, 0x20); do_end_of_xds (sub, ctx, 0x2a); }
void xds_cea608_test() { /* This test is the sample data that comes in CEA-608. It sets the program name to be "Star Trek". The checksum is 0x1d and the validation must succeed. */ process_xds_bytes (0x01,0x03); process_xds_bytes (0x53,0x74); process_xds_bytes (0x61,0x72); process_xds_bytes (0x20,0x54); process_xds_bytes (0x72,0x65); process_xds_bytes (0x02,0x03); process_xds_bytes (0x02,0x03); process_xds_bytes (0x6b,0x00); do_end_of_xds (0x1d); }
void xds_cea608_test(struct ccx_decoders_xds_context *ctx, struct cc_subtitle *sub) { /* This test is the sample data that comes in CEA-608. It sets the program name to be "Star Trek". The checksum is 0x1d and the validation must succeed. */ process_xds_bytes (ctx, 0x01,0x03); process_xds_bytes (ctx, 0x53,0x74); process_xds_bytes (ctx, 0x61,0x72); process_xds_bytes (ctx, 0x20,0x54); process_xds_bytes (ctx, 0x72,0x65); process_xds_bytes (ctx, 0x02,0x03); process_xds_bytes (ctx, 0x02,0x03); process_xds_bytes (ctx, 0x6b,0x00); do_end_of_xds (sub, ctx, 0x1d); }
/* If wb is NULL, then only XDS will be processed */ int process608(const unsigned char *data, int length, void *private_data, struct cc_subtitle *sub) { struct ccx_decoder_608_report *report = NULL; ccx_decoder_608_context *context = private_data; static int textprinted = 0; int i; if (context) { report = &context->report; context->bytes_processed_608 += length; } if (!data) { return -1; } for (i=0; i < length; i=i+2) { unsigned char hi, lo; int wrote_to_screen=0; hi = data[i] & 0x7F; // Get rid of parity bit lo = data[i+1] & 0x7F; // Get rid of parity bit if (hi==0 && lo==0) // Just padding continue; // printf ("\r[%02X:%02X]\n",hi,lo); if (hi>=0x10 && hi<=0x1e) { int ch = (hi<=0x17)? 1 : 2; if (context == NULL || context->my_field == 2) // Originally: current_field from sequencing.c. Seems to be just to change channel, so context->my_field seems good. ch+=2; if(report) report->cc_channels[ch - 1] = 1; } if (hi >= 0x01 && hi <= 0x0E && (context == NULL || context->my_field == 2)) // XDS can only exist in field 2. { if (context) context->channel = 3; if (!in_xds_mode) { ts_start_of_xds=get_fts(); in_xds_mode=1; } if(report) report->xds=1; } if (hi == 0x0F && in_xds_mode && (context == NULL || context->my_field == 2)) // End of XDS block { in_xds_mode=0; do_end_of_xds (sub, lo); if (context) context->channel = context->new_channel; // Switch from channel 3 continue; } if (hi>=0x10 && hi<=0x1F) // Non-character code or special/extended char // http://www.geocities.com/mcpoodle43/SCC_TOOLS/DOCS/CC_CODES.HTML // http://www.geocities.com/mcpoodle43/SCC_TOOLS/DOCS/CC_CHARS.HTML { // We were writing characters before, start a new line for // diagnostic output from disCommand() if (textprinted == 1 ) { ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\n"); textprinted = 0; } if (!context || context->my_field == 2) in_xds_mode=0; // Back to normal (CEA 608-8.6.2) if (!context) // Not XDS and we don't have a writebuffer, nothing else would have an effect continue; if (context->last_c1 == hi && context->last_c2 == lo) { // Duplicate dual code, discard. Correct to do it only in // non-XDS, XDS codes shall not be repeated. ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "Skipping command %02X,%02X Duplicate\n", hi, lo); // Ignore only the first repetition context->last_c1=-1; context->last_c2 = -1; continue; } context->last_c1 = hi; context->last_c2 = lo; wrote_to_screen = disCommand(hi, lo, context, sub); if(sub->got_output) break; } else { if (in_xds_mode && (context == NULL || context->my_field == 2)) { process_xds_bytes (hi,lo); continue; } if (!context) // No XDS code after this point, and user doesn't want captions. continue; context->last_c1 = -1; context->last_c2 = -1; if (hi>=0x20) // Standard characters (always in pairs) { // Only print if the channel is active if (context->channel != context->my_channel) continue; if( textprinted == 0 ) { ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\n"); textprinted = 1; } handle_single(hi, context); handle_single(lo, context); wrote_to_screen=1; context->last_c1 = 0; context->last_c2 = 0; } if (!textprinted && context->channel == context->my_channel) { // Current FTS information after the characters are shown ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "Current FTS: %s\n", print_mstime(get_fts())); //printf(" N:%u", unsigned(fts_now) ); //printf(" G:%u", unsigned(fts_global) ); //printf(" F:%d %d %d %d\n", // current_field, cb_field1, cb_field2, cb_708 ); } if (wrote_to_screen && context->settings->direct_rollup && // If direct_rollup is enabled and (context->mode == MODE_FAKE_ROLLUP_1 || // we are in rollup mode, write now. context->mode == MODE_ROLLUP_2 || context->mode == MODE_ROLLUP_3 || context->mode == MODE_ROLLUP_4)) { // We don't increase screenfuls_counter here. write_cc_buffer(context, sub); context->current_visible_start_ms = get_visible_start(); } } if (wrote_to_screen && context->cc_to_stdout) fflush (stdout); } // for return i; }