diff options
-rw-r--r-- | libhb/deccc608sub.c | 138 | ||||
-rw-r--r-- | libhb/deccc608sub.h | 3 | ||||
-rw-r--r-- | libhb/decmpeg2.c | 13 | ||||
-rw-r--r-- | libhb/muxmp4.c | 15 |
4 files changed, 99 insertions, 70 deletions
diff --git a/libhb/deccc608sub.c b/libhb/deccc608sub.c index dbbc2d3e5..5cfe238db 100644 --- a/libhb/deccc608sub.c +++ b/libhb/deccc608sub.c @@ -11,7 +11,7 @@ * ccextractor static configuration variables. */ static int debug_608 = 0; -static int trim_subs = 0; +static int trim_subs = 1; static int nofontcolor = 0; static enum encoding_type encoding = ENC_UTF_8; static int cc_channel = 1; @@ -24,6 +24,9 @@ static int gui_mode_reports = 0; static int norollup = 1; static int direct_rollup = 0; +/* + * Get the time of the last buffer that we have received. + */ static LLONG get_fts(struct s_write *wb) { return wb->last_pts; @@ -39,14 +42,11 @@ int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10}; // we need to bring it into the swrite struct. Same for "str". #define INITIAL_ENC_BUFFER_CAPACITY 2048 -unsigned char *enc_buffer=NULL; // Generic general purpose buffer unsigned char str[2048]; // Another generic general purpose buffer -unsigned enc_buffer_used; -unsigned enc_buffer_capacity; -#define GUARANTEE(length) if (length>enc_buffer_capacity) \ -{enc_buffer_capacity*=2; enc_buffer=(unsigned char*) realloc (enc_buffer, enc_buffer_capacity); \ - if (enc_buffer==NULL) { fatal (EXIT_NOT_ENOUGH_MEMORY, "Not enough memory, bailing out\n"); } \ +#define GUARANTEE(wb, length) if (length>wb->enc_buffer_capacity) \ +{wb->enc_buffer_capacity*=2; wb->enc_buffer=(unsigned char*) realloc (wb->enc_buffer, wb->enc_buffer_capacity); \ + if (wb->enc_buffer==NULL) { fatal (EXIT_NOT_ENOUGH_MEMORY, "Not enough memory, bailing out\n"); } \ } const unsigned char pac2_attribs[][3]= // Color, font, ident @@ -153,17 +153,13 @@ const char *color_text[][2]= int general_608_init (struct s_write *wb) { - /* - * Not currently used. - * - if( !enc_buffer ) + if( !wb->enc_buffer ) { - enc_buffer=(unsigned char *) malloc (INITIAL_ENC_BUFFER_CAPACITY); - if (enc_buffer==NULL) + wb->enc_buffer=(unsigned char *) malloc (INITIAL_ENC_BUFFER_CAPACITY); + if (wb->enc_buffer==NULL) return -1; - enc_buffer_capacity=INITIAL_ENC_BUFFER_CAPACITY; + wb->enc_buffer_capacity=INITIAL_ENC_BUFFER_CAPACITY; } - */ if( !wb->subline) { wb->subline = malloc(2048); @@ -191,10 +187,10 @@ int general_608_init (struct s_write *wb) */ void general_608_close (struct s_write *wb) { - if( enc_buffer ) { - free(enc_buffer); - enc_buffer_capacity = 0; - enc_buffer_used = 0; + if( wb->enc_buffer ) { + free(wb->enc_buffer); + wb->enc_buffer_capacity = 0; + wb->enc_buffer_used = 0; } if( wb->subline ) { free(wb->subline); @@ -1439,9 +1435,9 @@ void write_subtitle_file_footer (struct s_write *wb) { hb_log ("\r%s\n", str); } - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); + wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str); //fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); break; default: // Nothing to do. Only SAMI has a footer break; @@ -1450,9 +1446,9 @@ void write_subtitle_file_footer (struct s_write *wb) void fhb_log_encoded (FILE *fh, const char *string) { - GUARANTEE(strlen (string)*3); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) string); - fwrite (enc_buffer,enc_buffer_used,1,fh); + //GUARANTEE(wb, strlen (string)*3); + //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) string); + //fwrite (wb->enc_buffer,wb->enc_buffer_used,1,fh); } void write_subtitle_file_header (struct s_write *wb) @@ -1463,10 +1459,10 @@ void write_subtitle_file_header (struct s_write *wb) break; case OF_SAMI: // This header brought to you by McPoodle's CCASDI //fhb_log_encoded (wb->fh, sami_header); - GUARANTEE(strlen (sami_header)*3); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) sami_header); + GUARANTEE(wb, strlen (sami_header)*3); + wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) sami_header); //fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); break; case OF_RCWT: // Write header //fwrite (rcwt_header, sizeof(rcwt_header),1,wb->fh); @@ -1600,19 +1596,26 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb) 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); - //fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) timeline); + //fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh); + XMLRPC_APPEND(wb->enc_buffer,wb->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); + //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) timeline); if (debug_608) { hb_log ("\n- - - SRT caption - - -\n"); hb_log (timeline); } //fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); + + /* + * Write all the lines into enc_buffer, and then write that out at the end + * ensure that we only have two lines, insert a newline after the first one, + * and have a big bottom line (strip spaces from any joined lines). + */ + int line = 1; for (i=0;i<15;i++) { if (data->row_used[i]) @@ -1622,35 +1625,40 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb) capitalize(i,data, &wb->new_sentence); correct_case(i,data); } - int length = get_decoder_line_encoded (wb->subline, i, data); - if (debug_608 && encoding!=ENC_UNICODE) - { - hb_log ("\r"); - hb_log ("%s\n",wb->subline); - } - if (length > 0) - { - hb_buffer_t *buffer = hb_buffer_init( length + 1 ); - buffer->start = ms_start; - buffer->stop = ms_end; - memcpy( buffer->data, wb->subline, length + 1 ); - - if (wb->hb_last_buffer) { - wb->hb_last_buffer->next = buffer; + /* + * The intention was to use a newline but QT doesn't like it, old code still + * here just in case.. + */ + if (line == 1) { + wb->enc_buffer_used = get_decoder_line_encoded (wb->enc_buffer, i, data); + line = 2; + } else { + if (line == 2) { + wb->enc_buffer_used += encode_line (wb->enc_buffer+wb->enc_buffer_used, + (unsigned char *) " "); } else { - wb->hb_buffer = buffer; + wb->enc_buffer_used += encode_line (wb->enc_buffer+wb->enc_buffer_used, + (unsigned char *) " "); } - wb->hb_last_buffer = buffer; - - //fwrite (wb->subline, 1, length, wb->fh); - XMLRPC_APPEND(wb->subline,length); - //fwrite (encoded_crlf, 1, encoded_crlf_length,wb->fh); - XMLRPC_APPEND(encoded_crlf,encoded_crlf_length); - wrote_something=1; - // fhb_log (wb->fh,encoded_crlf); + wb->enc_buffer_used += get_decoder_line_encoded (wb->enc_buffer+wb->enc_buffer_used, i, data); } } } + if (wb->enc_buffer_used) + { + hb_buffer_t *buffer = hb_buffer_init( wb->enc_buffer_used + 2 ); + buffer->start = ms_start; + buffer->stop = ms_end; + memcpy( buffer->data, wb->enc_buffer, wb->enc_buffer_used + 1 ); + if (wb->hb_last_buffer) { + wb->hb_last_buffer->next = buffer; + } else { + wb->hb_buffer = buffer; + } + wb->hb_last_buffer = buffer; + + wrote_something=1; + } if (debug_608) { hb_log ("- - - - - - - - - - - -\r\n"); @@ -1678,9 +1686,9 @@ int write_cc_buffer_as_sami (struct eia608_screen *data, struct s_write *wb) { hb_log ("\r%s\n", str); } - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); - fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str); + fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); for (i=0;i<15;i++) { if (data->row_used[i]) @@ -1708,17 +1716,17 @@ int write_cc_buffer_as_sami (struct eia608_screen *data, struct s_write *wb) { hb_log ("\r%s\n", str); } - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); - fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str); + fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); sprintf ((char *) str,"<SYNC start=\"%llu\"><P class=\"UNKNOWNCC\"> </P></SYNC>\r\n\r\n",endms); if (debug_608 && encoding!=ENC_UNICODE) { hb_log ("\r%s\n", str); } - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str); - fwrite (enc_buffer,enc_buffer_used,1,wb->fh); - XMLRPC_APPEND(enc_buffer,enc_buffer_used); + wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str); + fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh); + XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used); return wrote_something; } diff --git a/libhb/deccc608sub.h b/libhb/deccc608sub.h index 3e0288370..1b7b9405a 100644 --- a/libhb/deccc608sub.h +++ b/libhb/deccc608sub.h @@ -93,6 +93,9 @@ struct s_write { hb_buffer_t *hb_buffer; hb_buffer_t *hb_last_buffer; uint64_t last_pts; + unsigned char *enc_buffer; // Generic general purpose buffer + unsigned enc_buffer_used; + unsigned enc_buffer_capacity; }; enum command_code diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c index 2d5c7c494..6340ca61b 100644 --- a/libhb/decmpeg2.c +++ b/libhb/decmpeg2.c @@ -458,7 +458,18 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, subtitle->track = 0; subtitle->id = 0x0; snprintf( subtitle->lang, sizeof( subtitle->lang ), "Closed Captions"); - snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "und"); + /* + * The language of the subtitles will be the same as the first audio + * track, i.e. the same as the video. + */ + hb_audio_t *audio = hb_list_item( m->title->list_audio, 0 ); + if( audio ) + { + snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), + audio->config.lang.iso639_2); + } else { + snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "und"); + } subtitle->format = TEXTSUB; subtitle->source = CC608SUB; subtitle->dest = PASSTHRUSUB; diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index f49ba748f..0f06deb15 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -416,6 +416,8 @@ static int MP4Init( hb_mux_object_t * m ) mux_data->sub_format = subtitle->format; mux_data->track = MP4AddSubtitleTrack( m->file, 1 ); + MP4SetTrackLanguage(m->file, mux_data->track, subtitle->iso639_2); + /* Tune track chunk duration */ MP4TuneTrackDurationPerChunk( m, mux_data->track ); @@ -654,7 +656,8 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data, { hb_error("Failed to write to output file, disk full?"); *job->die = 1; - } + } + hb_log("Subtitle not due yet, adding delay of %lld", buf->start - m->sum_sub_duration); m->sum_sub_duration += buf->start - m->sum_sub_duration; } @@ -663,7 +666,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data, memcpy( buffer + 2, buf->data, buf->size ); buffer[0] = ( buf->size >> 8 ) & 0xff; buffer[1] = buf->size & 0xff; - + if( !MP4WriteSample( m->file, mux_data->track, buffer, @@ -676,13 +679,17 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data, *job->die = 1; } - m->sum_sub_duration += buf->stop - buf->start; - hb_log("MuxMP4:Sub:%lld:%lld: %s", buf->start, buf->stop, buf->data); + m->sum_sub_duration += (buf->stop - buf->start); + hb_log("MuxMP4:Sub:%lld:%lld:%lld: %s", buf->start, buf->stop, + (buf->stop - buf->start), buf->data); hb_log("MuxMP4:Total time elapsed:%lld", m->sum_sub_duration); } } else { + /* + * Audio + */ if( !MP4WriteSample( m->file, mux_data->track, buf->data, |