diff options
author | eddyg <[email protected]> | 2009-05-04 01:39:48 +0000 |
---|---|---|
committer | eddyg <[email protected]> | 2009-05-04 01:39:48 +0000 |
commit | 6be1d2f6861284fede24d8ca1021905846008a5a (patch) | |
tree | 9ba0b04aaeeddbe1e3c854a5986406d5bf6d107e /libhb/sync.c | |
parent | 1349c26c5417fd23676a4cb5cf572fbfe75e3b62 (diff) |
Stage 1 Soft Subtitle Support - Allow multiple subtitle tracks to be selected, and mark them for Render or Pass Through. No functional difference from the UIs, however in theory they could render multiple tracks - would be a dogs breakfast on screen though, and is untested. Have tested all normal operations from the UIs, including scanning.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2373 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/sync.c')
-rw-r--r-- | libhb/sync.c | 228 |
1 files changed, 124 insertions, 104 deletions
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 |