+ subtitle = hb_list_item( job->list_subtitle, i );
+
+ /*
+ * Rewrite timestamps on subtitles that need it (on raw queue).
+ */
+ if( subtitle->source == CC608SUB ||
+ subtitle->source == CC708SUB ||
+ subtitle->source == SRTSUB )
+ {
+ /*
+ * Rewrite timestamps on subtitles that came from Closed Captions
+ * since they are using the MPEG2 timestamps.
+ */
+ while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
+ {
+ /*
+ * Rewrite the timestamps as and when the video
+ * (cur->start) reaches the same timestamp as a
+ * closed caption (sub->start).
+ *
+ * What about discontinuity boundaries - not delt
+ * with here - Van?
+ *
+ * Bypass the sync fifo altogether.
+ */
+ if( sub->size <= 0 )
+ {
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ hb_fifo_push( subtitle->fifo_out, sub );
+ sub = NULL;
+ break;
+ } else {
+ /*
+ * Sync the subtitles to the incoming video, and use
+ * the matching converted video timestamp.
+ *
+ * Note that it doesn't appear that we need to convert
+ * timestamps, I guess that they were already correct,
+ * so just push them through for rendering.
+ *
+ */
+ if( sub->start < cur->start )
+ {
+ uint64_t duration;
+ duration = sub->stop - sub->start;
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ hb_fifo_push( subtitle->fifo_out, sub );
+ } else {
+ sub = NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ if( subtitle->source == VOBSUB )
+ {
+ hb_buffer_t * sub2;
+ while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
+ {
+ if( sub->size == 0 )
+ {
+ /*
+ * EOF, pass it through immediately.
+ */
+ break;
+ }
+
+ /* 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.
+ */
+
+ /*
+ * There is a valid subtitle, is it time to display it?
+ */
+ 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.
+ */
+ if( cur->start > sub->start &&
+ cur->start < sub->stop )
+ {
+ /*
+ * We should be playing this, so leave the
+ * subtitle in place.
+ *
+ * fall through to display
+ */
+ if( ( sub->stop - sub->start ) < ( 2 * 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 + ( 2 * 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
+ {
+ /*
+ * 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.
+ */
+ 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 subtitle is older than this picture, trash it
+ */
+ 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->config.dest == RENDERSUB )
+ {
+ if ( cur->sub == NULL )
+ {
+ /*
+ * Tack onto the video buffer for rendering
+ */
+ 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 {
+ /*
+ * 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->config.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 );
+ }
+ }
+ }
+ }
+ } // end subtitles
+
+ /*
+ * Adjust the pts of the current frame so that it's contiguous
+ * with the previous frame. The start time of the current frame
+ * has to be the end time of the previous frame and the stop
+ * time has to be the start of the next frame. We don't
+ * make any adjustments to the source timestamps other than removing
+ * the clock offsets (which also removes pts discontinuities).
+ * This means we automatically encode at the source's frame rate.
+ * MP2 uses an implicit duration (frames end when the next frame
+ * starts) but more advanced containers like MP4 use an explicit
+ * duration. Since we're looking ahead one frame we set the
+ * explicit stop time from the start time of the next frame.
+ */
+ 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 - pts_skip - buf_tmp->start;
+ pts_skip = 0;
+ if ( duration <= 0 )