OSDN Git Service

fix sync of ssa subtitles when using point-to-point encoding
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Mon, 22 Nov 2010 21:52:05 +0000 (21:52 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Mon, 22 Nov 2010 21:52:05 +0000 (21:52 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@3685 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/decssasub.c
libhb/reader.c
libhb/sync.c

index c02de3e..8d0a999 100644 (file)
@@ -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;
 }
index f6c3341..7835354 100644 (file)
@@ -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", 
index cfc0c2a..b44765e 100644 (file)
@@ -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 );
         }