void _dtvcc_window_update_time_hide(ccx_dtvcc_window *window, struct ccx_common_timing_ctx *timing) { char buf[128]; window->time_ms_hide = get_visible_end(timing, 3); print_mstime2buf(window->time_ms_hide, buf); ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] " "[W-%d] hide time updated to %s\n", window->number, buf); }
int write_cc_buffer_as_smptett (struct eia608_screen *data, struct s_write *wb) { unsigned h1,m1,s1,ms1; unsigned h2,m2,s2,ms2; int wrote_something=0; LLONG startms = wb->data608->current_visible_start_ms; startms+=subs_delay; if (startms<0) // Drop screens that because of subs_delay start too early return 0; LLONG endms = get_visible_end()+subs_delay; endms--; // To prevent overlapping with next line. mstotime (startms,&h1,&m1,&s1,&ms1); mstotime (endms-1,&h2,&m2,&s2,&ms2); sprintf ((char *) str,"<p begin=\"%02u:%02u:%02u,%03u\" end=\"%02u:%02u:%02u,%03u\">\n",h1,m1,s1,ms1, h2,m2,s2,ms2); if (encoding!=ENC_UNICODE) { dbg_print(DMT_608, "\r%s\n", str); } enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); write (wb->fh, enc_buffer,enc_buffer_used); for (int i=0;i<15;i++) { if (data->row_used[i]) { int length = get_decoder_line_encoded (subline, i, data); if (encoding!=ENC_UNICODE) { dbg_print(DMT_608, "\r"); dbg_print(DMT_608, "%s\n",subline); } write (wb->fh, subline, length); wrote_something=1; //if (i!=14) //write (wb->fh, encoded_br, encoded_br_length); write (wb->fh,encoded_crlf, encoded_crlf_length); } } sprintf ((char *) str,"</p>\n"); if (encoding!=ENC_UNICODE) { dbg_print(DMT_608, "\r%s\n", str); } enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); write (wb->fh, enc_buffer,enc_buffer_used); if (encoding!=ENC_UNICODE) { dbg_print(DMT_608, "\r%s\n", str); } enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); //write (wb->fh, enc_buffer,enc_buffer_used); return wrote_something; }
void _dtvcc_screen_print(ccx_dtvcc_ctx *dtvcc, ccx_dtvcc_service_decoder *decoder) { //TODO use priorities to solve windows overlap (with a video sample, please) //qsort(wnd, visible, sizeof(ccx_dtvcc_window *), _dtvcc_compare_win_priorities); ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] _dtvcc_screen_print\n"); _dtvcc_screen_update_time_hide(decoder->tv, get_visible_end(dtvcc->timing, 3)); #ifdef DTVCC_PRINT_DEBUG //ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "[CEA-708] TV dump:\n"); //ccx_dtvcc_write_debug(decoder->tv); #endif decoder->cc_count++; decoder->tv->cc_count++; struct encoder_ctx *encoder = (struct encoder_ctx *) dtvcc->encoder; int sn = decoder->tv->service_number; ccx_dtvcc_writer_ctx *writer = &encoder->dtvcc_writers[sn - 1]; ccx_dtvcc_writer_output(writer, decoder->tv, encoder); _dtvcc_tv_clear(decoder); }
int write_cc_buffer(ccx_decoder_608_context *context, struct cc_subtitle *sub) { struct eia608_screen *data; int wrote_something=0; LLONG start_time; LLONG end_time; if (context->settings->screens_to_process != -1 && context->screenfuls_counter >= context->settings->screens_to_process) { // We are done. *context->halt=1; return 0; } data = get_current_visible_buffer(context); if (context->mode == MODE_FAKE_ROLLUP_1 && // Use the actual start of data instead of last buffer change context->ts_start_of_current_line != -1) context->current_visible_start_ms = context->ts_start_of_current_line; start_time = context->current_visible_start_ms; end_time = get_visible_end() + context->subs_delay; sub->type = CC_608; data->format = SFORMAT_CC_SCREEN; data->start_time = 0; data->end_time = 0; data->mode = context->mode; data->channel = context->channel; data->my_field = context->my_field; if (!data->empty) { sub->data = (struct eia608_screen *) realloc(sub->data,( sub->nb_data + 1 ) * sizeof(*data)); if (!sub->data) { ccx_common_logging.log_ftn("No Memory left"); return 0; } memcpy(((struct eia608_screen *)sub->data) + sub->nb_data, data, sizeof(*data)); sub->nb_data++; wrote_something = 1; if(start_time < end_time) { int i = 0; int nb_data = sub->nb_data; data = (struct eia608_screen *)sub->data; for(i = 0;(unsigned) i < sub->nb_data; i++) { if(!data->start_time) break; nb_data--; data++; } for(i = 0; i < nb_data; i++) { data->start_time = start_time + ( ( (end_time - start_time)/nb_data ) * i ); data->end_time = start_time + ( ( (end_time - start_time)/nb_data ) * (i + 1) ); data++; } sub->got_output = 1; } } return wrote_something; }
int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb) { unsigned h1,m1,s1,ms1; unsigned h2,m2,s2,ms2; int wrote_something = 0; LLONG ms_start= wb->data608->current_visible_start_ms; int empty_buf=1; for (int i=0;i<15;i++) { if (data->row_used[i]) { empty_buf=0; break; } } if (empty_buf) // Prevent writing empty screens. Not needed in .srt return 0; ms_start+=subs_delay; if (ms_start<0) // Drop screens that because of subs_delay start too early return 0; LLONG ms_end = get_visible_end()+subs_delay; mstotime (ms_start,&h1,&m1,&s1,&ms1); mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. char timeline[128]; wb->data608->srt_counter++; sprintf (timeline,"%u\r\n",wb->data608->srt_counter); enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); write (wb->fh, enc_buffer,enc_buffer_used); sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", h1,m1,s1,ms1, h2,m2,s2,ms2); enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); dbg_print(DMT_608, "\n- - - SRT caption - - -\n"); dbg_print(DMT_608, "%s",timeline); write (wb->fh, enc_buffer,enc_buffer_used); for (int i=0;i<15;i++) { if (data->row_used[i]) { if (sentence_cap) { capitalize (i,data); correct_case(i,data); } int length = get_decoder_line_encoded (subline, i, data); if (encoding!=ENC_UNICODE) { dbg_print(DMT_608, "\r"); dbg_print(DMT_608, "%s\n",subline); } write (wb->fh, subline, length); write (wb->fh, encoded_crlf, encoded_crlf_length); wrote_something=1; // fprintf (wb->fh,encoded_crlf); } } dbg_print(DMT_608, "- - - - - - - - - - - -\r\n"); // fprintf (wb->fh, encoded_crlf); write (wb->fh, encoded_crlf, encoded_crlf_length); return wrote_something; }
int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *context) { unsigned h1,m1,s1,ms1; unsigned h2,m2,s2,ms2; LLONG ms_start, ms_end; int wrote_something = 0; ms_start = context->current_visible_start_ms; int prev_line_start=-1, prev_line_end=-1; // Column in which the previous line started and ended, for autodash int prev_line_center1=-1, prev_line_center2=-1; // Center column of previous line text int empty_buf=1; for (int i=0;i<15;i++) { if (data->row_used[i]) { empty_buf=0; break; } } if (empty_buf) // Prevent writing empty screens. Not needed in .srt return 0; ms_start+=subs_delay; if (ms_start<0) // Drop screens that because of subs_delay start too early return 0; ms_end=get_visible_end()+subs_delay; mstotime (ms_start,&h1,&m1,&s1,&ms1); mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. char timeline[128]; context->srt_counter++; sprintf(timeline, "%u\r\n", context->srt_counter); enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); write(context->out->fh, enc_buffer, enc_buffer_used); sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", h1,m1,s1,ms1, h2,m2,s2,ms2); enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); dbg_print(CCX_DMT_608, "\n- - - SRT caption ( %d) - - -\n", context->srt_counter); dbg_print(CCX_DMT_608, "%s",timeline); write (context->out->fh, enc_buffer,enc_buffer_used); for (int i=0;i<15;i++) { if (data->row_used[i]) { if (ccx_options.sentence_cap) { capitalize (i,data); correct_case(i,data); } if (ccx_options.autodash && ccx_options.trim_subs) { int first=0, last=31, center1=-1, center2=-1; unsigned char *line = data->characters[i]; int do_dash=1, colon_pos=-1; find_limit_characters(line,&first,&last); if (first==-1 || last==-1) // Probably a bug somewhere though break; // Is there a speaker named, for example: TOM: What are you doing? for (int j=first;j<=last;j++) { if (line[j]==':') { colon_pos=j; break; } if (!isupper (line[j])) break; } if (prev_line_start==-1) do_dash=0; if (first==prev_line_start) // Case of left alignment do_dash=0; if (last==prev_line_end) // Right align do_dash=0; if (first>prev_line_start && last<prev_line_end) // Fully contained do_dash=0; if ((first>prev_line_start && first<prev_line_end) || // Overlap (last>prev_line_start && last<prev_line_end)) do_dash=0; center1=(first+last)/2; if (colon_pos!=-1) { while (colon_pos<CC608_SCREEN_WIDTH && (line[colon_pos]==':' || line[colon_pos]==' ' || line[colon_pos]==0x89)) colon_pos++; // Find actual text center2=(colon_pos+last)/2; } else center2=center1; if (center1>=prev_line_center1-1 && center1<=prev_line_center1+1 && center1!=-1) // Center align do_dash=0; if (center2>=prev_line_center2-2 && center1<=prev_line_center2+2 && center1!=-1) // Center align do_dash=0; if (do_dash) write(context->out->fh, "- ", 2); prev_line_start=first; prev_line_end=last; prev_line_center1=center1; prev_line_center2=center2; } int length = get_decoder_line_encoded (subline, i, data); if (ccx_options.encoding!=CCX_ENC_UNICODE) { dbg_print(CCX_DMT_608, "\r"); dbg_print(CCX_DMT_608, "%s\n",subline); } write(context->out->fh, subline, length); write(context->out->fh, encoded_crlf, encoded_crlf_length); wrote_something=1; // fprintf (wb->fh,encoded_crlf); } } dbg_print(CCX_DMT_608, "- - - - - - - - - - - -\r\n"); // fprintf (wb->fh, encoded_crlf); write (context->out->fh, encoded_crlf, encoded_crlf_length); return wrote_something; }