diff options
-rw-r--r-- | libhb/common.h | 12 | ||||
-rw-r--r-- | libhb/dvd.c | 4 | ||||
-rw-r--r-- | libhb/hb.c | 18 | ||||
-rw-r--r-- | libhb/reader.c | 39 | ||||
-rw-r--r-- | libhb/scan.c | 3 | ||||
-rw-r--r-- | libhb/sync.c | 228 | ||||
-rw-r--r-- | libhb/work.c | 4 | ||||
-rw-r--r-- | macosx/Controller.mm | 59 | ||||
-rw-r--r-- | test/test.c | 10 |
9 files changed, 220 insertions, 157 deletions
diff --git a/libhb/common.h b/libhb/common.h index 60ba93ef6..f19511027 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -213,11 +213,9 @@ struct hb_job_s /* List of audio settings. */ hb_list_t * list_audio; - /* Subtitle settings: - subtitle: index in hb_title_t's subtitles list, starting - from 0. -1 means no subtitle */ - int subtitle; - int subtitleSmartAdjust; + /* Subtitles + */ + hb_list_t * list_subtitle; /* Muxer settings mux: output file format @@ -442,7 +440,11 @@ struct hb_chapter_s struct hb_subtitle_s { + int track; int id; + enum subtype { PICTURESUB, TEXTSUB } format; + enum subsource { VOBSUB, SRTSUB, CCSUB } source; + enum subdest { RENDERSUB, PASSTHRUSUB } dest; char lang[1024]; char iso639_2[4]; uint8_t type; /* Closed Caption, Childrens, Directors etc */ diff --git a/libhb/dvd.c b/libhb/dvd.c index cf6eefe49..58ce9adde 100644 --- a/libhb/dvd.c +++ b/libhb/dvd.c @@ -463,11 +463,15 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t ) lang = lang_for_code( vts->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/hb.c b/libhb/hb.c index ff8524956..943e2389f 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -1125,17 +1125,22 @@ void hb_add( hb_handle_t * h, hb_job_t * job ) } } else { /* - * Manually selected subtitle, in which case only + * Manually selected subtitles, in which case only * bother adding them for pass 0 or pass 2 of a two * pass. */ if( job->pass != 1 ) { - if( ( subtitle = hb_list_item( title->list_subtitle, job->subtitle ) ) ) - { - subtitle_copy = malloc( sizeof( hb_subtitle_t ) ); - memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) ); - hb_list_add( title_copy->list_subtitle, subtitle_copy ); + /* + * Copy all of them from the input job, to the title_copy/job_copy. + */ + for( i = 0; i < hb_list_count(job->list_subtitle); i++ ) { + if( ( subtitle = hb_list_item( job->list_subtitle, i ) ) ) + { + subtitle_copy = malloc( sizeof( hb_subtitle_t ) ); + memcpy( subtitle_copy, subtitle, sizeof( hb_subtitle_t ) ); + hb_list_add( title_copy->list_subtitle, subtitle_copy ); + } } } } @@ -1148,6 +1153,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job ) title_copy->job = job_copy; job_copy->title = title_copy; job_copy->list_audio = title_copy->list_audio; + job_copy->list_subtitle = title_copy->list_subtitle; // sharing list between title and job job_copy->file = strdup( job->file ); job_copy->h = h; job_copy->pause = h->pause_lock; diff --git a/libhb/reader.c b/libhb/reader.c index 0acbe0921..e0345378f 100644 --- a/libhb/reader.c +++ b/libhb/reader.c @@ -516,37 +516,24 @@ static hb_fifo_t ** GetFifoForId( hb_job_t * job, int id ) } } - if( job->indepth_scan ) { - /* - * Count the occurances of the subtitles, don't actually - * return any to encode unless we are looking fro forced - * subtitles in which case we need to look in the sub picture - * to see if it has the forced flag enabled. - */ - for (i=0; i < hb_list_count(title->list_subtitle); i++) { - subtitle = hb_list_item( title->list_subtitle, i); - if (id == subtitle->id) { + for( i=0; i < hb_list_count( title->list_subtitle ); i++ ) { + subtitle = hb_list_item( title->list_subtitle, i ); + if (id == subtitle->id) { + subtitle->hits++; + if( !job->indepth_scan || job->subtitle_force ) + { /* - * A hit, count it. + * Pass the subtitles to be processed if we are not scanning, or if + * we are scanning and looking for forced subs, then pass them up + * to decode whether the sub is a forced one. */ - subtitle->hits++; - if( job->subtitle_force ) - { - - fifos[0] = subtitle->fifo_in; - return fifos; - } - break; + fifos[0] = subtitle->fifo_in; + return fifos; } - } - } else { - if( ( subtitle = hb_list_item( title->list_subtitle, 0 ) ) && - id == subtitle->id ) - { - fifos[0] = subtitle->fifo_in; - return fifos; + break; } } + if( !job->indepth_scan ) { n = 0; diff --git a/libhb/scan.c b/libhb/scan.c index a549285b5..420904b61 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -224,8 +224,7 @@ static void ScanFunc( void * _data ) job->vrate_base = title->rate_base; job->list_audio = hb_list_init(); - - job->subtitle = -1; + job->list_subtitle = hb_list_init(); job->mux = HB_MUX_MP4; } diff --git a/libhb/sync.c b/libhb/sync.c index a1a7f1ad9..798c01b26 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -44,7 +44,6 @@ struct hb_work_private_s // an eof buf. syncWork returns done when all // bits are clear. /* Video */ - hb_subtitle_t * subtitle; int64_t pts_offset; int64_t next_start; /* start time of next output frame */ int64_t next_pts; /* start time of next input frame */ @@ -125,16 +124,13 @@ int syncInit( hb_work_object_t * w, hb_job_t * job ) /* Initialize libsamplerate for every audio track we have */ if ( ! job->indepth_scan ) { - for( i = 0; i < hb_list_count( title->list_audio ); i++ ) + for( i = 0; i < hb_list_count( title->list_audio ) && i < 8; i++ ) { pv->busy |= ( 1 << (i + 1) ); InitAudio( w, i ); } } - /* Get subtitle info, if any */ - pv->subtitle = hb_list_item( title->list_subtitle, 0 ); - return 0; } @@ -284,6 +280,8 @@ static void SyncVideo( hb_work_object_t * w ) hb_work_private_t * pv = w->private_data; hb_buffer_t * cur, * next, * sub = NULL; hb_job_t * job = pv->job; + hb_subtitle_t *subtitle; + int i; if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) ) { @@ -385,138 +383,160 @@ static void SyncVideo( hb_work_object_t * w ) */ pv->video_sequence = cur->sequence; - /* Look for a subtitle for this frame */ - if( pv->subtitle ) + /* + * Look for a subtitle for this frame. + * + * If found then it will be tagged onto a video buffer of the correct time and + * sent in to the render pipeline. This only needs to be done for VOBSUBs which + * get rendered, other types of subtitles can just sit in their raw_queue until + * delt with at muxing. + */ + for( i = 0; i < hb_list_count( job->list_subtitle ); i++) { - hb_buffer_t * sub2; - while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) ) + subtitle = hb_list_item( job->list_subtitle, i ); + if( subtitle->dest == RENDERSUB ) { - /* If two subtitles overlap, make the first one stop - when the second one starts */ - sub2 = hb_fifo_see2( pv->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); - - if( sub->sequence > cur->sequence ) + hb_buffer_t * sub2; + while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) ) { + /* If two subtitles overlap, make the first one stop + 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); + + if( sub->sequence > cur->sequence ) + { + /* + * The video is behind where we are, so wait until + * it catches up to the same reader point on the + * DVD. Then our PTS should be in the same region + * as the video. + */ + sub = NULL; + break; + } + + if( sub->stop > cur->start ) { + /* + * The stop time is in the future, so fall through + * and we'll deal with it in the next block of + * code. + */ + break; + } + /* - * The video is behind where we are, so wait until - * it catches up to the same reader point on the - * DVD. Then our PTS should be in the same region - * as the video. - */ - sub = NULL; - break; - } - - if( sub->stop > cur->start ) { - /* - * The stop time is in the future, so fall through - * and we'll deal with it in the next block of - * code. + * The subtitle is older than this picture, trash it */ - break; + sub = hb_fifo_get( subtitle->fifo_raw ); + hb_buffer_close( &sub ); } - + /* - * The subtitle is older than this picture, trash it + * There is a valid subtitle, is it time to display it? */ - sub = hb_fifo_get( pv->subtitle->fifo_raw ); - hb_buffer_close( &sub ); - } - - /* - * There is a valid subtitle, is it time to display it? - */ - if( sub ) - { - if( sub->stop > sub->start) + if( sub ) { - /* - * Normal subtitle which ends after it starts, check to - * see that the current video is between the start and end. - */ - 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. + * We should be playing this, so leave the + * subtitle in place. * - * This is in response to Indochine which only - * displays subs for 1 second - too fast to read. + * fall through to display */ - sub->stop = sub->start + ( 3 * 90000 ); - - sub2 = hb_fifo_see2( pv->subtitle->fifo_raw ); - - if( sub2 && sub->stop > sub2->start ) + if( ( sub->stop - sub->start ) < ( 3 * 90000 ) ) { - sub->stop = sub2->start; + /* + * 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 ); + + 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 - */ - sub = NULL; - } - } - else - { - /* - * The end of the subtitle is less than the start, this is a - * sign of a PTS discontinuity. - */ - if( sub->start > cur->start ) - { - /* - * we haven't reached the start time yet, or - * we have jumped backwards after having - * already started this subtitle. + * The end of the subtitle is less than the start, this is a + * sign of a PTS discontinuity. */ - if( cur->start < sub->stop ) + if( sub->start > cur->start ) { /* - * We have jumped backwards and so should - * continue displaying this subtitle. - * - * fall through to display. + * we haven't reached the start time yet, or + * we have jumped backwards after having + * already started this subtitle. */ - } - else - { + 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 { /* - * Defer until the play point is within the subtitle + * Play this subtitle as the start is greater than our + * video point. + * + * fall through to display/ */ - sub = NULL; } - } else { - /* - * Play this subtitle as the start is greater than our - * video point. - * - * fall through to display/ - */ } } } - } + if( sub ) + { + /* + * Don't overwrite the current sub, we'll check the + * other subtitle streams on the next video buffer. + * + * It doesn't make much sense having multiple rendered + * subtitle tracks anyway. + */ + break; + } + } // end subtitles /* * Adjust the pts of the current frame so that it's contiguous diff --git a/libhb/work.c b/libhb/work.c index 8e0734ceb..8c6db7d54 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -278,7 +278,7 @@ void hb_display_job_info( hb_job_t * job ) if( subtitle ) { - hb_log( " * subtitle track %i, %s (id %x)", job->subtitle+1, subtitle->lang, subtitle->id); + hb_log( " * subtitle track %i, %s (id %x)", subtitle->track, subtitle->lang, subtitle->id); } } @@ -503,7 +503,7 @@ static void do_job( hb_job_t * job, int cpu_count ) } } - if (!job->indepth_scan || job->subtitle_force) { + if( !job->indepth_scan || job->subtitle_force ) { /* * Don't add threads for subtitles when we are scanning, unless * looking for forced subtitles. diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 025304035..1872e5fff 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -2617,9 +2617,9 @@ fWorkingCount = 0; job->subtitle_force = 0; /* - * subtitle of -1 is a scan + * If scanning we need to do some extra setup of the job. */ - if( job->subtitle == -1 ) + if( job->indepth_scan == 1 ) { char *x264opts_tmp; @@ -2629,7 +2629,6 @@ fWorkingCount = 0; */ job->pass = -1; x264opts_tmp = job->x264opts; - job->subtitle = -1; job->x264opts = NULL; @@ -2647,12 +2646,6 @@ fWorkingCount = 0; else job->select_subtitle = NULL; - /* No subtitle were selected, so reset the subtitle to -1 (which before - * this point meant we were scanning - */ - if( job->subtitle == -2 ) - job->subtitle = -1; - if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 ) { hb_subtitle_t **subtitle_tmp = job->select_subtitle; @@ -2786,7 +2779,28 @@ fWorkingCount = 0; } /* Subtitle settings */ - job->subtitle = [fSubPopUp indexOfSelectedItem] - 2; + switch( [fSubPopUp indexOfSelectedItem] - 2 ) + { + case -2: + /* + * No subtitles selected + */ + break; + case -1: + /* + * Subtitle scan selected + */ + job->indepth_scan = 1; + break; + default: + /* + * Subtitle selected, add it into the job from the title. + */ + job->indepth_scan = 0; + hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, [fSubPopUp indexOfSelectedItem] - 2 ); + hb_list_add( job->list_subtitle, subtitle ); + break; + } /* Audio tracks and mixdowns */ /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/ @@ -3184,8 +3198,31 @@ fWorkingCount = 0; job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue]; /* Subtitle settings */ - job->subtitle = [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2; + switch( [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 ) + { + case -2: + /* + * No subtitles selected + */ + break; + case -1: + /* + * Subtitle scan selected + */ + job->indepth_scan = 1; + break; + default: + /* + * Subtitle selected, add it into the job from the title. + */ + job->indepth_scan = 0; + hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, + [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 ); + hb_list_add( job->list_subtitle, subtitle ); + break; + } + /* Audio tracks and mixdowns */ /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/ int audiotrack_count = hb_list_count(job->list_audio); diff --git a/test/test.c b/test/test.c index 2ab159488..411c20c61 100644 --- a/test/test.c +++ b/test/test.c @@ -1640,7 +1640,15 @@ static int HandleEvents( hb_handle_t * h ) if( sub ) { - job->subtitle = sub - 1; + hb_subtitle_t *subtitle; + /* + * Find the subtitle with the same track as "sub" and + * add that to the job subtitle list + */ + subtitle = hb_list_item( title->list_subtitle, sub ); + if( subtitle ) { + hb_list_add( job->list_subtitle, subtitle ); + } } if( native_language ) |