From 0ac869507784e807357b06b61fbb4b69f4191278 Mon Sep 17 00:00:00 2001 From: jstebbins <jstebbins.hb@gmail.com> Date: Tue, 19 May 2009 22:27:11 +0000 Subject: mkv soft subtitle support - new libmkv 0.6.4 with subtitle track support - muxmkv supports vobsub and closed caption subtitles - added subtitle format, source, and dest initialization to dvdnav - moved subtitle_force flag into hb_subtitle_t struct as it needs to be settable per subtitle - gtk ui added subtitle tab which allows selection of multiple subtitles - reorgainize subtitle sync code to prevent dropping of subtitles when multiple subtitles are enabled git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2428 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/common.h | 5 +- libhb/decvobsub.c | 102 ++++++++++++---------- libhb/dvdnav.c | 4 + libhb/encvobsub.c | 18 +++- libhb/fifo.c | 1 + libhb/muxmkv.c | 87 ++++++++++++++----- libhb/reader.c | 2 +- libhb/sync.c | 246 +++++++++++++++++++++++++++--------------------------- libhb/work.c | 8 +- 9 files changed, 279 insertions(+), 194 deletions(-) (limited to 'libhb') diff --git a/libhb/common.h b/libhb/common.h index 516318907..224b40c78 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -238,7 +238,6 @@ struct hb_job_s int indepth_scan; hb_subtitle_t ** select_subtitle; - int subtitle_force; char * native_language; int angle; // dvd angle to encode @@ -445,6 +444,7 @@ struct hb_subtitle_s enum subtype { PICTURESUB, TEXTSUB } format; enum subsource { VOBSUB, SRTSUB, CC608SUB, CC708SUB } source; enum subdest { RENDERSUB, PASSTHRUSUB } dest; + int force; char lang[1024]; char iso639_2[4]; uint8_t type; /* Closed Caption, Childrens, Directors etc */ @@ -639,6 +639,9 @@ struct hb_work_object_s /* Pointer hb_audio_t so we have access to the info in the audio worker threads. */ hb_audio_t * audio; + /* Pointer hb_subtitle_t so we have access to the info in the subtitle worker threads. */ + hb_subtitle_t * subtitle; + hb_work_private_t * private_data; hb_thread_t * thread; diff --git a/libhb/decvobsub.c b/libhb/decvobsub.c index fd1f89179..e5633d54d 100644 --- a/libhb/decvobsub.c +++ b/libhb/decvobsub.c @@ -8,27 +8,27 @@ struct hb_work_private_s { - hb_job_t * job; - - uint8_t buf[0xFFFF]; - int size_sub; - int size_got; - int size_rle; - int64_t pts; - int64_t pts_start; - int64_t pts_stop; - int pts_forced; - int x; - int y; - int width; - int height; - int stream_id; - - int offsets[2]; - uint8_t lum[4]; - uint8_t chromaU[4]; - uint8_t chromaV[4]; - uint8_t alpha[4]; + hb_job_t * job; + + hb_buffer_t * buf; + int size_sub; + int size_got; + int size_rle; + int64_t pts; + int64_t pts_start; + int64_t pts_stop; + int pts_forced; + int x; + int y; + int width; + int height; + int stream_id; + + int offsets[2]; + uint8_t lum[4]; + uint8_t chromaU[4]; + uint8_t chromaV[4]; + uint8_t alpha[4]; }; static hb_buffer_t * Decode( hb_work_object_t * ); @@ -76,7 +76,10 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, pv->size_sub = size_sub; pv->size_rle = size_rle; - memcpy( pv->buf, in->data, in->size ); + pv->buf = hb_buffer_init( 0xFFFF ); + memcpy( pv->buf->data, in->data, in->size ); + pv->buf->id = in->id; + pv->buf->sequence = in->sequence; pv->size_got = in->size; pv->pts = in->start; } @@ -86,7 +89,9 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, /* We are waiting for the end of the current subtitle */ if( in->size <= pv->size_sub - pv->size_got ) { - memcpy( pv->buf + pv->size_got, in->data, in->size ); + memcpy( pv->buf->data + pv->size_got, in->data, in->size ); + pv->buf->id = in->id; + pv->buf->sequence = in->sequence; pv->size_got += in->size; if( in->start >= 0 ) { @@ -99,11 +104,14 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, if( pv->size_sub && pv->size_sub == pv->size_got ) { + pv->buf->size = pv->size_sub; + /* We got a complete subtitle, decode it */ *buf_out = Decode( w ); if( buf_out && *buf_out ) { + (*buf_out)->id = in->id; (*buf_out)->sequence = in->sequence; } @@ -145,6 +153,7 @@ static void ParseControls( hb_work_object_t * w ) hb_job_t * job = pv->job; hb_title_t * title = job->title; hb_subtitle_t * subtitle; + uint8_t * buf = pv->buf->data; int i, n; int command; @@ -161,12 +170,12 @@ static void ParseControls( hb_work_object_t * w ) for( i = pv->size_rle; ; ) { - date = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2; - next = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2; + date = ( buf[i] << 8 ) | buf[i+1]; i += 2; + next = ( buf[i] << 8 ) | buf[i+1]; i += 2; for( ;; ) { - command = pv->buf[i++]; + command = buf[i++]; /* * There are eight commands available for @@ -224,10 +233,10 @@ static void ParseControls( hb_work_object_t * w ) int colors[4]; int j; - colors[0] = (pv->buf[i+0]>>4)&0x0f; - colors[1] = (pv->buf[i+0])&0x0f; - colors[2] = (pv->buf[i+1]>>4)&0x0f; - colors[3] = (pv->buf[i+1])&0x0f; + colors[0] = (buf[i+0]>>4)&0x0f; + colors[1] = (buf[i+0])&0x0f; + colors[2] = (buf[i+1]>>4)&0x0f; + colors[3] = (buf[i+1])&0x0f; for( j = 0; j < 4; j++ ) { @@ -267,10 +276,10 @@ static void ParseControls( hb_work_object_t * w ) */ uint8_t alpha[4]; - alpha[3] = (pv->buf[i+0]>>4)&0x0f; - alpha[2] = (pv->buf[i+0])&0x0f; - alpha[1] = (pv->buf[i+1]>>4)&0x0f; - alpha[0] = (pv->buf[i+1])&0x0f; + alpha[3] = (buf[i+0]>>4)&0x0f; + alpha[2] = (buf[i+0])&0x0f; + alpha[1] = (buf[i+1]>>4)&0x0f; + alpha[0] = (buf[i+1])&0x0f; int lastAlpha = pv->alpha[3] + pv->alpha[2] + pv->alpha[1] + pv->alpha[0]; @@ -296,17 +305,17 @@ static void ParseControls( hb_work_object_t * w ) } case 0x05: // 0x05 - SET_DAREA - defines the display area { - pv->x = (pv->buf[i+0]<<4) | ((pv->buf[i+1]>>4)&0x0f); - pv->width = (((pv->buf[i+1]&0x0f)<<8)| pv->buf[i+2]) - pv->x + 1; - pv->y = (pv->buf[i+3]<<4)| ((pv->buf[i+4]>>4)&0x0f); - pv->height = (((pv->buf[i+4]&0x0f)<<8)| pv->buf[i+5]) - pv->y + 1; + pv->x = (buf[i+0]<<4) | ((buf[i+1]>>4)&0x0f); + pv->width = (((buf[i+1]&0x0f)<<8)| buf[i+2]) - pv->x + 1; + pv->y = (buf[i+3]<<4)| ((buf[i+4]>>4)&0x0f); + pv->height = (((buf[i+4]&0x0f)<<8)| buf[i+5]) - pv->y + 1; i += 6; break; } case 0x06: // 0x06 - SET_DSPXA - defines the pixel data addresses { - pv->offsets[0] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2; - pv->offsets[1] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2; + pv->offsets[0] = ( buf[i] << 8 ) | buf[i+1]; i += 2; + pv->offsets[1] = ( buf[i] << 8 ) | buf[i+1]; i += 2; break; } } @@ -475,7 +484,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) /* Get infos about the subtitle */ ParseControls( w ); - if( job->indepth_scan || ( job->subtitle_force && pv->pts_forced == 0 ) ) + if( job->indepth_scan || ( w->subtitle->force && pv->pts_forced == 0 ) ) { /* * Don't encode subtitles when doing a scan. @@ -486,11 +495,18 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) return NULL; } + if (w->subtitle->dest == PASSTHRUSUB) + { + pv->buf->start = pv->pts_start; + pv->buf->stop = pv->pts_stop; + return pv->buf; + } + /* Do the actual decoding now */ buf_raw = malloc( ( pv->width * pv->height ) * 4 ); #define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \ -( pv->buf[((*offset)>>1)] & 0xF ) : ( pv->buf[((*offset)>>1)] >> 4 ) ) ); \ +( pv->buf->data[((*offset)>>1)] & 0xF ) : ( pv->buf->data[((*offset)>>1)] >> 4 ) ) ); \ (*offset)++ offsets[0] = pv->offsets[0] * 2; @@ -547,6 +563,8 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) } } + hb_buffer_close( &pv->buf ); + /* Crop subtitle (remove transparent borders) */ buf = CropSubtitle( w, buf_raw ); diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c index 5fde4cba7..515de1ee0 100644 --- a/libhb/dvdnav.c +++ b/libhb/dvdnav.c @@ -619,11 +619,15 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t ) lang = lang_for_code( ifo->vtsi_mat->vts_subp_attr[i].lang_code ); subtitle = calloc( sizeof( hb_subtitle_t ), 1 ); + subtitle->track = i+1; subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd; snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name); snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "%s", lang->iso639_2); + subtitle->format = PICTURESUB; + subtitle->source = VOBSUB; + subtitle->dest = RENDERSUB; // By default render (burn-in) the VOBSUB. subtitle->type = lang_extension; diff --git a/libhb/encvobsub.c b/libhb/encvobsub.c index ee49d7ad6..20a9879d6 100644 --- a/libhb/encvobsub.c +++ b/libhb/encvobsub.c @@ -26,9 +26,15 @@ int encsubInit( hb_work_object_t * w, hb_job_t * job ) int encsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, hb_buffer_t ** buf_out ) { - hb_work_private_t * pv = w->private_data; hb_buffer_t * in = *buf_in; + if (w->subtitle->source != VOBSUB) + { + // Invalid source, send EOF, this shouldn't ever happen + hb_log("encvobsub: invalid subtitle source"); + hb_buffer_close( buf_in ); + *buf_out = hb_buffer_init(0); + } if ( in->size <= 0 ) { /* EOF on input stream - send it downstream & say that we're done */ @@ -38,10 +44,14 @@ int encsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, } /* - * Don't do anything at present, just pass the buffer on. + * Not much to do, just pass the buffer on. + * Some day, we may re-encode bd subtitles here ;) */ - *buf_out = in; - *buf_in = NULL; + if (buf_out) + { + *buf_out = in; + *buf_in = NULL; + } return HB_WORK_OK; } diff --git a/libhb/fifo.c b/libhb/fifo.c index c756f5673..7337874bf 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -191,6 +191,7 @@ void hb_buffer_close( hb_buffer_t ** _b ) if( buffer_pool && b->data && !hb_fifo_is_full( buffer_pool ) ) { hb_fifo_push_head( buffer_pool, b ); + *_b = NULL; return; } /* either the pool is full or this size doesn't use a pool - free the buf */ diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c index c3d627979..04f9ae595 100644 --- a/libhb/muxmkv.c +++ b/libhb/muxmkv.c @@ -34,6 +34,27 @@ struct hb_mux_data_s int sub_format; }; +static int yuv2rgb(int yuv) +{ + double y, Cr, Cb; + int r, g, b; + + y = (yuv >> 16) & 0xff; + Cr = (yuv >> 8) & 0xff; + Cb = (yuv) & 0xff; + + r = 1.164 * (y - 16) + 2.018 * (Cb - 128); + g = 1.164 * (y - 16) - 0.813 * (Cr - 128) - 0.391 * (Cb - 128); + b = 1.164 * (y - 16) + 1.596 * (Cr - 128); + r = (r < 0) ? 0 : r; + g = (g < 0) ? 0 : g; + b = (b < 0) ? 0 : b; + r = (r > 255) ? 255 : r; + g = (g > 255) ? 255 : g; + b = (b > 255) ? 255 : b; + return (r << 16) | (g << 8) | b; +} + /********************************************************************** * MKVInit ********************************************************************** @@ -48,7 +69,7 @@ static int MKVInit( hb_mux_object_t * m ) uint8_t *avcC = NULL; uint8_t default_track_flag = 1; - int avcC_len, i; + int avcC_len, i, j; ogg_packet *ogg_headers[3]; mk_TrackConfig *track; @@ -261,7 +282,7 @@ static int MKVInit( hb_mux_object_t * m ) for( i = 0; i < hb_list_count( title->list_subtitle ); i++ ) { hb_subtitle_t * subtitle; - uint32_t * palette; + uint32_t rgb[16]; char subidx[2048]; int len; @@ -270,28 +291,39 @@ static int MKVInit( hb_mux_object_t * m ) continue; memset(track, 0, sizeof(mk_TrackConfig)); + switch (subtitle->format) + { + case PICTURESUB: + track->codecID = MK_SUBTITLE_VOBSUB; + for (j = 0; j < 16; j++) + rgb[j] = yuv2rgb(title->palette[j]); + len = snprintf(subidx, 2048, subidx_fmt, + title->width, title->height, + 0, 0, "OFF", + rgb[0], rgb[1], rgb[2], rgb[3], + rgb[4], rgb[5], rgb[6], rgb[7], + rgb[8], rgb[9], rgb[10], rgb[11], + rgb[12], rgb[13], rgb[14], rgb[15]); + track->codecPrivate = subidx; + track->codecPrivateSize = len + 1; + break; + case TEXTSUB: + track->codecID = MK_SUBTITLE_UTF8; + break; + default: + continue; + } mux_data = calloc(1, sizeof( hb_mux_data_t ) ); subtitle->mux_data = mux_data; mux_data->subtitle = 1; mux_data->sub_format = subtitle->format; - palette = title->palette; - len = snprintf(subidx, 2048, subidx_fmt, title->width, title->height, - 0, 0, "OFF", - palette[0], palette[1], palette[2], palette[3], - palette[4], palette[5], palette[6], palette[7], - palette[8], palette[9], palette[10], palette[11], - palette[12], palette[13], palette[14], palette[15]); - track->codecPrivate = subidx; - track->codecPrivateSize = len + 1; - track->codecID = MK_SUBTITLE_VOBSUB; track->flagEnabled = 1; track->trackType = MK_TRACK_SUBTITLE; track->language = subtitle->iso639_2; mux_data->track = mk_createTrack(m->file, track); - } if( mk_writeHeader( m->file, "HandBrake " HB_PROJECT_VERSION) < 0 ) @@ -362,19 +394,33 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data, *job->die = 1; } mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes); - mk_setFrameFlags(m->file, mux_data->track, timecode, 1); + mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0); return 0; } } else if ( mux_data->subtitle ) { timecode = buf->start * TIMECODE_SCALE; + if( mk_startFrame(m->file, mux_data->track) < 0) + { + hb_error( "Failed to write frame to output file, Disk Full?" ); + *job->die = 1; + } if( mux_data->sub_format == TEXTSUB ) { - hb_log("MuxMKV: Text Sub:%lld: %s", buf->start, buf->data); - // TODO: add CC data to track - return 0; + uint64_t duration; + + duration = buf->stop * TIMECODE_SCALE - timecode; + mk_addFrameData(m->file, mux_data->track, buf->data, buf->size); + mk_setFrameFlags(m->file, mux_data->track, timecode, 1, duration); } + else + { + mk_addFrameData(m->file, mux_data->track, buf->data, buf->size); + mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0); + } + mk_flushFrame(m->file, mux_data->track); + return 0; } else { @@ -391,7 +437,7 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data, *job->die = 1; } mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes); - mk_setFrameFlags(m->file, mux_data->track, timecode, 1); + mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0); return 0; } } @@ -403,7 +449,10 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data, } mk_addFrameData(m->file, mux_data->track, buf->data, buf->size); mk_setFrameFlags(m->file, mux_data->track, timecode, - ((job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data) ? (buf->frametype == HB_FRAME_IDR) : ((buf->frametype & HB_FRAME_KEY) != 0)) ); + ((job->vcodec == HB_VCODEC_X264 && + mux_data == job->mux_data) ? + (buf->frametype == HB_FRAME_IDR) : + ((buf->frametype & HB_FRAME_KEY) != 0)), 0 ); return 0; } diff --git a/libhb/reader.c b/libhb/reader.c index dd478151b..c865ea85f 100644 --- a/libhb/reader.c +++ b/libhb/reader.c @@ -527,7 +527,7 @@ static hb_fifo_t ** GetFifoForId( hb_job_t * job, int id ) subtitle = hb_list_item( title->list_subtitle, i ); if (id == subtitle->id) { subtitle->hits++; - if( !job->indepth_scan || job->subtitle_force ) + if( !job->indepth_scan || subtitle->force ) { /* * Pass the subtitles to be processed if we are not scanning, or if diff --git a/libhb/sync.c b/libhb/sync.c index 1001ed50c..d76907987 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -485,7 +485,9 @@ static void SyncVideo( hb_work_object_t * w ) when the second one starts */ sub2 = hb_fifo_see2( subtitle->fifo_raw ); if( sub2 && sub->stop > sub2->start ) + { sub->stop = sub2->start; + } // hb_log("0x%x: video seq: %lld subtitle sequence: %lld", // sub, cur->sequence, sub->sequence); @@ -508,120 +510,160 @@ static void SyncVideo( hb_work_object_t * w ) * and we'll deal with it in the next block of * code. */ - break; - } - - /* - * The subtitle is older than this picture, trash it - */ - sub = hb_fifo_get( subtitle->fifo_raw ); - hb_buffer_close( &sub ); - } - - if( sub && sub->size == 0 ) - { - /* - * Continue immediately on subtitle EOF - */ - break; - } - /* - * There is a valid subtitle, is it time to display it? - */ - if( sub ) - { - if( sub->stop > sub->start) - { /* - * Normal subtitle which ends after it starts, check to - * see that the current video is between the start and end. + * There is a valid subtitle, is it time to display it? */ - if( cur->start > sub->start && - cur->start < sub->stop ) + if( sub->stop > sub->start) { /* - * We should be playing this, so leave the - * subtitle in place. - * - * fall through to display + * Normal subtitle which ends after it starts, + * check to see that the current video is between + * the start and end. */ - if( ( sub->stop - sub->start ) < ( 3 * 90000 ) ) + if( cur->start > sub->start && + cur->start < sub->stop ) { /* - * Subtitle is on for less than three seconds, extend - * the time that it is displayed to make it easier - * to read. Make it 3 seconds or until the next - * subtitle is displayed. - * - * This is in response to Indochine which only - * displays subs for 1 second - too fast to read. - */ - sub->stop = sub->start + ( 3 * 90000 ); + * We should be playing this, so leave the + * subtitle in place. + * + * fall through to display + */ + if( ( sub->stop - sub->start ) < ( 3 * 90000 ) ) + { + /* + * Subtitle is on for less than three + * seconds, extend the time that it is + * displayed to make it easier to read. + * Make it 3 seconds or until the next + * subtitle is displayed. + * + * This is in response to Indochine which + * only displays subs for 1 second - + * too fast to read. + */ + sub->stop = sub->start + ( 3 * 90000 ); - sub2 = hb_fifo_see2( subtitle->fifo_raw ); + sub2 = hb_fifo_see2( subtitle->fifo_raw ); - if( sub2 && sub->stop > sub2->start ) - { - sub->stop = sub2->start; + if( sub2 && sub->stop > sub2->start ) + { + sub->stop = sub2->start; + } } } + else + { + /* + * Defer until the play point is within + * the subtitle + */ + sub = NULL; + } } else { /* - * Defer until the play point is within the subtitle + * The end of the subtitle is less than the start, + * this is a sign of a PTS discontinuity. */ - sub = NULL; + if( sub->start > cur->start ) + { + /* + * we haven't reached the start time yet, or + * we have jumped backwards after having + * already started this subtitle. + */ + if( cur->start < sub->stop ) + { + /* + * We have jumped backwards and so should + * continue displaying this subtitle. + * + * fall through to display. + */ + } + else + { + /* + * Defer until the play point is + * within the subtitle + */ + sub = NULL; + } + } else { + /* + * Play this subtitle as the start is + * greater than our video point. + * + * fall through to display/ + */ + } } + break; } else { + /* - * The end of the subtitle is less than the start, this is a - * sign of a PTS discontinuity. + * The subtitle is older than this picture, trash it */ - if( sub->start > cur->start ) + sub = hb_fifo_get( subtitle->fifo_raw ); + hb_buffer_close( &sub ); + } + } + + /* If we have a subtitle for this picture, copy it */ + /* FIXME: we should avoid this memcpy */ + if( sub ) + { + if( sub->size > 0 ) + { + if( subtitle->dest == RENDERSUB ) { - /* - * we haven't reached the start time yet, or - * we have jumped backwards after having - * already started this subtitle. - */ - if( cur->start < sub->stop ) - { - /* - * We have jumped backwards and so should - * continue displaying this subtitle. - * - * fall through to display. - */ - } - else + if ( cur->sub == NULL ) { /* - * Defer until the play point is within the subtitle + * Tack onto the video buffer for rendering */ - sub = NULL; + cur->sub = hb_buffer_init( sub->size ); + cur->sub->x = sub->x; + cur->sub->y = sub->y; + cur->sub->width = sub->width; + cur->sub->height = sub->height; + memcpy( cur->sub->data, sub->data, sub->size ); } } else { /* - * Play this subtitle as the start is greater than our - * video point. - * - * fall through to display/ + * Pass-Through, pop it off of the raw queue, + * rewrite times and make it available to be + * reencoded. */ + uint64_t sub_duration; + sub = hb_fifo_get( subtitle->fifo_raw ); + sub_duration = sub->stop - sub->start; + sub->start = cur->start; + buf_tmp = hb_fifo_see( job->fifo_raw ); + int64_t duration = buf_tmp->start - cur->start; + sub->stop = sub->start + duration; + hb_fifo_push( subtitle->fifo_sync, sub ); + } + } else { + /* + * EOF - consume for rendered, else pass through + */ + if( subtitle->dest == RENDERSUB ) + { + sub = hb_fifo_get( subtitle->fifo_raw ); + hb_buffer_close( &sub ); + } else { + sub = hb_fifo_get( subtitle->fifo_raw ); + hb_fifo_push( subtitle->fifo_out, sub ); } } } } - if( sub ) - { - /* - * Got a sub to display... - */ - break; - } } // end subtitles /* @@ -639,6 +681,7 @@ static void SyncVideo( hb_work_object_t * w ) */ buf_tmp = cur; pv->cur = cur = hb_fifo_get( job->fifo_raw ); + cur->sub = NULL; pv->next_pts = cur->start; int64_t duration = cur->start - buf_tmp->start; if ( duration <= 0 ) @@ -659,51 +702,6 @@ static void SyncVideo( hb_work_object_t * w ) pv->chap_mark = 0; } - /* If we have a subtitle for this picture, copy it */ - /* FIXME: we should avoid this memcpy */ - if( sub && subtitle && - subtitle->format == PICTURESUB ) - { - if( sub->size > 0 ) - { - if( subtitle->dest == RENDERSUB ) - { - /* - * Tack onto the video buffer for rendering - */ - buf_tmp->sub = hb_buffer_init( sub->size ); - buf_tmp->sub->x = sub->x; - buf_tmp->sub->y = sub->y; - buf_tmp->sub->width = sub->width; - buf_tmp->sub->height = sub->height; - memcpy( buf_tmp->sub->data, sub->data, sub->size ); - } else { - /* - * Pass-Through, pop it off of the raw queue, rewrite times and - * make it available to be reencoded. - */ - uint64_t sub_duration; - sub = hb_fifo_get( subtitle->fifo_raw ); - sub_duration = sub->stop - sub->start; - sub->start = buf_tmp->start; - sub->stop = sub->start + duration; - hb_fifo_push( subtitle->fifo_sync, sub ); - } - } else { - /* - * EOF - consume for rendered, else pass through - */ - if( subtitle->dest == RENDERSUB ) - { - sub = hb_fifo_get( subtitle->fifo_raw ); - hb_buffer_close( &sub ); - } else { - sub = hb_fifo_get( subtitle->fifo_raw ); - hb_fifo_push( subtitle->fifo_out, sub ); - } - } - } - /* Push the frame to the renderer */ hb_fifo_push( job->fifo_sync, buf_tmp ); diff --git a/libhb/work.c b/libhb/work.c index 7b270ca70..59dea5dfe 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -501,16 +501,16 @@ static void do_job( hb_job_t * job, int cpu_count ) * * select_subtitle implies that we did a scan. */ - if( !job->indepth_scan && job->subtitle_force && + if( !job->indepth_scan && subtitle->force && job->select_subtitle ) { if( subtitle->forced_hits == 0 ) { - job->subtitle_force = 0; + subtitle->force = 0; } } - if( (!job->indepth_scan || job->subtitle_force) && + if( (!job->indepth_scan || subtitle->force) && subtitle->source == VOBSUB ) { /* * Don't add threads for subtitles when we are scanning, unless @@ -519,6 +519,7 @@ static void do_job( hb_job_t * job, int cpu_count ) w = hb_get_work( WORK_DECVOBSUB ); w->fifo_in = subtitle->fifo_in; w->fifo_out = subtitle->fifo_raw; + w->subtitle = subtitle; hb_list_add( job->list_work, w ); } @@ -541,6 +542,7 @@ static void do_job( hb_job_t * job, int cpu_count ) w = hb_get_work( WORK_ENCVOBSUB ); w->fifo_in = subtitle->fifo_sync; w->fifo_out = subtitle->fifo_out; + w->subtitle = subtitle; hb_list_add( job->list_work, w ); } } -- cgit v1.2.3