summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2010-11-22 21:52:05 +0000
committerjstebbins <[email protected]>2010-11-22 21:52:05 +0000
commitbdb3c747159ff77aa36feaeb9365c58c23d512b6 (patch)
treebc77628a40f6ea9c55b59e2939e875cb346a9bab
parentffa6c17f19cf2e88d1de9858c10cf9925272001b (diff)
fix sync of ssa subtitles when using point-to-point encoding
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3685 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/decssasub.c28
-rw-r--r--libhb/reader.c37
-rw-r--r--libhb/sync.c12
3 files changed, 44 insertions, 33 deletions
diff --git a/libhb/decssasub.c b/libhb/decssasub.c
index c02de3e85..8d0a9995d 100644
--- a/libhb/decssasub.c
+++ b/libhb/decssasub.c
@@ -170,6 +170,34 @@ static hb_buffer_t *ssa_decode_packet( hb_work_object_t * w, hb_buffer_t *in )
*nextPtr = out;
nextPtr = &out->next;
}
+
+ // For point-to-point encoding, when the start time of the stream
+ // may be offset, the timestamps of the subtitles must be offset as well.
+ //
+ // HACK: Here we are making the assumption that, under normal circumstances,
+ // the output display time of the first output packet is equal to the
+ // display time of the input packet.
+ //
+ // During point-to-point encoding, the display time of the input
+ // packet will be offset to compensate.
+ //
+ // Therefore we offset all of the output packets by a slip amount
+ // such that first output packet's display time aligns with the
+ // input packet's display time. This should give the correct time
+ // when point-to-point encoding is in effect.
+ if (out_list && out_list->start > in->start)
+ {
+ int64_t slip = out_list->start - in->start;
+ hb_buffer_t *out;
+
+ out = out_list;
+ while (out)
+ {
+ out->start -= slip;
+ out->stop -= slip;
+ out = out->next;
+ }
+ }
return out_list;
}
diff --git a/libhb/reader.c b/libhb/reader.c
index f6c334172..783535492 100644
--- a/libhb/reader.c
+++ b/libhb/reader.c
@@ -260,6 +260,8 @@ static void ReaderFunc( void * _r )
else if ( r->job->pts_to_start )
{
hb_bd_seek_pts( r->bd, r->job->pts_to_start );
+ r->job->pts_to_start = 0;
+ r->start_found = 1;
}
else
{
@@ -410,10 +412,14 @@ static void ReaderFunc( void * _r )
// to skip from this seek point to the timestamp we
// want to start at.
if ( ps->start > 0 && ps->start < r->job->pts_to_start )
+ {
r->job->pts_to_start -= ps->start;
+ }
else if ( ps->start >= r->job->pts_to_start )
+ {
r->job->pts_to_start = 0;
- r->start_found = 1;
+ r->start_found = 1;
+ }
}
}
@@ -495,18 +501,8 @@ static void ReaderFunc( void * _r )
// frame but video & subtitles don't. Clear
// the timestamps so the decoder will generate
// them from the frame durations.
- if ( st != r->stream_timing )
- {
- // not a video stream so it's probably
- // subtitles - the best we can do is to
- // line it up with the last video packet.
- buf->start = r->stream_timing->last;
- }
- else
- {
- buf->start = -1;
- buf->renderOffset = -1;
- }
+ buf->start = -1;
+ buf->renderOffset = -1;
}
}
}
@@ -517,23 +513,10 @@ static void ReaderFunc( void * _r )
UpdateState( r, start );
if ( !r->start_found &&
- r->job->pts_to_start &&
- buf->renderOffset != -1 &&
start >= r->job->pts_to_start )
{
// pts_to_start point found
- // force a new scr offset computation
- stream_timing_t *st = find_st( r, buf );
- if ( st &&
- (st->is_audio ||
- ( st == r->stream_timing && !r->saw_audio ) ) )
- {
- // Re-zero our timestamps
- st->last = -st->average;
- new_scr_offset( r, buf );
- r->start_found = 1;
- r->job->pts_to_start = 0;
- }
+ r->start_found = 1;
}
// This log is handy when you need to debug timing problems
//hb_log("id %x scr_offset %ld start %ld --> %ld",
diff --git a/libhb/sync.c b/libhb/sync.c
index cfc0c2a20..b44765e08 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -317,7 +317,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_DONE;
}
if ( pv->common->count_frames < job->frame_to_start ||
- next_start < job->pts_to_start )
+ next->start < job->pts_to_start )
{
// Flush any subtitles that have pts prior to the
// current frame
@@ -334,7 +334,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
}
hb_lock( pv->common->mutex );
// Tell the audio threads what must be dropped
- pv->common->audio_pts_thresh = next_start;
+ pv->common->audio_pts_thresh = next_start + pv->common->video_pts_slip;
hb_cond_broadcast( pv->common->next_frame );
hb_unlock( pv->common->mutex );
@@ -345,8 +345,8 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
}
hb_lock( pv->common->mutex );
pv->common->audio_pts_thresh = 0;
- pv->common->audio_pts_slip = next_start;
- pv->common->video_pts_slip = next_start;
+ pv->common->audio_pts_slip += next_start;
+ pv->common->video_pts_slip += next_start;
next_start = 0;
pv->common->start_found = 1;
pv->common->count_frames = 0;
@@ -989,14 +989,14 @@ static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
// after hb_sync_init is called.
pv->common->audio_pts_thresh = job->pts_to_start;
}
- if ( start < pv->common->audio_pts_thresh )
+ if ( buf->start < pv->common->audio_pts_thresh )
{
hb_buffer_close( &buf );
hb_unlock( pv->common->mutex );
return HB_WORK_OK;
}
while ( !pv->common->start_found &&
- start >= pv->common->audio_pts_thresh )
+ buf->start >= pv->common->audio_pts_thresh )
{
hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 );
}