void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number) { int ret = 0; unsigned int h1,m1,s1,ms1; unsigned int h2,m2,s2,ms2; LLONG start_time = data->start_time; LLONG end_time = data->end_time; if (context->sentence_cap) { capitalize (line_number,data); correct_case(line_number,data); } int length = get_decoder_str_basic (context->subline, data->characters[line_number], context->trim_subs, context->encoding); if (context->encoding!=CCX_ENC_UNICODE) { dbg_print(CCX_DMT_DECODER_608, "\r"); dbg_print(CCX_DMT_DECODER_608, "%s\n",context->subline); } if (length>0) { if (data->start_time == -1) { // CFS: Means that the line has characters but we don't have a timestamp for the first one. Since the timestamp // is set for example by the write_char function, it possible that we don't have one in empty lines (unclear) // For now, let's not consider this a bug as before and just return. // fatal (EXIT_BUG_BUG, "Bug in timedtranscript (ts_start_of_current_line==-1). Please report."); return; } if (context->transcript_settings->showStartTime){ char buf1[80]; if (context->transcript_settings->relativeTimestamp){ millis_to_date(start_time + context->subs_delay, buf1, context->date_format, context->millis_separator); fdprintf(context->out->fh, "%s|", buf1); } else { mstotime(start_time + context->subs_delay, &h1, &m1, &s1, &ms1); time_t start_time_int = (start_time + context->subs_delay) / 1000; int start_time_dec = (start_time + context->subs_delay) % 1000; struct tm *start_time_struct = gmtime(&start_time_int); strftime(buf1, sizeof(buf1), "%Y%m%d%H%M%S", start_time_struct); fdprintf(context->out->fh, "%s%c%03d|", buf1,context->millis_separator,start_time_dec); } } if (context->transcript_settings->showEndTime){ char buf2[80]; if (context->transcript_settings->relativeTimestamp){ millis_to_date(end_time, buf2, context->date_format, context->millis_separator); fdprintf(context->out->fh, "%s|", buf2); } else { mstotime(get_fts() + context->subs_delay, &h2, &m2, &s2, &ms2); time_t end_time_int = (end_time + context->subs_delay) / 1000; int end_time_dec = (end_time + context->subs_delay) % 1000; struct tm *end_time_struct = gmtime(&end_time_int); strftime(buf2, sizeof(buf2), "%Y%m%d%H%M%S", end_time_struct); fdprintf(context->out->fh, "%s%c%03d|", buf2,context->millis_separator,end_time_dec); } } if (context->transcript_settings->showCC){ fdprintf(context->out->fh, "CC%d|", data->my_field == 1 ? data->channel : data->channel + 2); // Data from field 2 is CC3 or 4 } if (context->transcript_settings->showMode){ const char *mode = "???"; switch (data->mode) { case MODE_POPON: mode = "POP"; break; case MODE_FAKE_ROLLUP_1: mode = "RU1"; break; case MODE_ROLLUP_2: mode = "RU2"; break; case MODE_ROLLUP_3: mode = "RU3"; break; case MODE_ROLLUP_4: mode = "RU4"; break; case MODE_TEXT: mode = "TXT"; break; case MODE_PAINTON: mode = "PAI"; break; } fdprintf(context->out->fh, "%s|", mode); } ret = write(context->out->fh, context->subline, length); if(ret < length) { mprint("Warning:Loss of data\n"); } ret = write(context->out->fh, encoded_crlf, encoded_crlf_length); if(ret < encoded_crlf_length) { mprint("Warning:Loss of data\n"); } } // fprintf (wb->fh,encoded_crlf); }
status_t read_cdtext(int fd, struct cdtext &cdtext) { uint8 *buffer = (uint8 *)malloc(kBufferSize); if (buffer == NULL) return B_NO_MEMORY; // do it twice, just in case... // (at least my CD-ROM sometimes returned broken data on first try) read_table_of_contents(fd, 1, SCSI_TOC_FORMAT_CD_TEXT, buffer, kBufferSize); if (read_table_of_contents(fd, 1, SCSI_TOC_FORMAT_CD_TEXT, buffer, kBufferSize) != B_OK) { free(buffer); return B_ERROR; } scsi_toc_general *header = (scsi_toc_general *)buffer; size_t packLength = B_BENDIAN_TO_HOST_INT16(header->data_length) - 2; cdtext_pack_data *pack = (cdtext_pack_data *)(header + 1); cdtext_pack_data *lastPack = NULL; uint8 state = 0; char text[256]; while (true) { size_t length = sizeof(text); uint8 id = 0, track = 0; if (!parse_pack_data(pack, packLength, lastPack, id, track, state, text, length)) break; switch (id) { case kTrackID: if (track == 0) { if (cdtext.album == NULL) cdtext.album = copy_string(text); } else if (track <= kMaxTracks) { if (cdtext.titles[track - 1] == NULL) cdtext.titles[track - 1] = copy_string(text); if (track > cdtext.track_count) cdtext.track_count = track; } break; case kArtistID: if (track == 0) { if (cdtext.artist == NULL) cdtext.artist = copy_string(text); } else if (track <= kMaxTracks) { if (cdtext.artists[track - 1] == NULL) cdtext.artists[track - 1] = copy_string(text); } break; default: if (is_string_id(id)) dprintf("UNKNOWN %u: \"%s\"\n", id, text); break; } } free(buffer); if (cdtext.artist == NULL || cdtext.album == NULL) return B_ERROR; for (int i = 0; i < cdtext.track_count; i++) { if (cdtext.titles[i] == NULL) return B_ERROR; } sanitize_string(cdtext.artist); sanitize_album(cdtext); sanitize_titles(cdtext); correct_case(cdtext); dump_cdtext(cdtext); return B_OK; }
int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *context) { int used; unsigned h1,m1,s1,ms1; unsigned h2,m2,s2,ms2; LLONG ms_start, ms_end; int wrote_something = 0; ms_start = data->start_time; 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+=context->subs_delay; if (ms_start<0) // Drop screens that because of subs_delay start too early return 0; ms_end = data->end_time; 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%s", context->srt_counter, context->encoded_crlf); used = encode_line(context, context->buffer,(unsigned char *) timeline); write(context->out->fh, context->buffer, used); sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u%s", h1, m1, s1, ms1, h2, m2, s2, ms2, context->encoded_crlf); used = encode_line(context, context->buffer,(unsigned char *) timeline); dbg_print(CCX_DMT_DECODER_608, "\n- - - SRT caption ( %d) - - -\n", context->srt_counter); dbg_print(CCX_DMT_DECODER_608, "%s",timeline); write (context->out->fh, context->buffer, used); for (int i=0;i<15;i++) { if (data->row_used[i]) { if (context->sentence_cap) { capitalize (i,data); correct_case(i,data); } if (context->autodash && context->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<CCX_DECODER_608_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 (context, context->subline, i, data); if (context->encoding!=CCX_ENC_UNICODE) { dbg_print(CCX_DMT_DECODER_608, "\r"); dbg_print(CCX_DMT_DECODER_608, "%s\n",context->subline); } write(context->out->fh, context->subline, length); write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length); wrote_something=1; // fprintf (wb->fh,context->encoded_crlf); } } dbg_print(CCX_DMT_DECODER_608, "- - - - - - - - - - - -\r\n"); // fprintf (wb->fh, context->encoded_crlf); write (context->out->fh, context->encoded_crlf, context->encoded_crlf_length); 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; }