]> granicus.if.org Git - handbrake/commitdiff
reader: fix subtitle start time not advancing
authorjstebbins <jstebbins.hb@gmail.com>
Tue, 7 Apr 2015 23:33:24 +0000 (23:33 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Tue, 7 Apr 2015 23:33:24 +0000 (23:33 +0000)
We must set a start time for subtitles or the vobsub decoder (and probably
other subtitle decoders) will assign duplicate timestamps. So when a
discontinuity occurs, make the closest guess that we can.

git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.10.x@7073 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/reader.c

index 0d29ed8389ea2707050cd7780bc8a9aac8652a45..8a9b167e0c71712ee7fa4d210588e99b2ca6dcce 100644 (file)
@@ -45,6 +45,7 @@ struct hb_work_private_s
 
     stream_timing_t *stream_timing;
     int64_t        scr_offset;
+    int            sub_scr_set;
     hb_psdemux_t   demux;
     int            scr_changes;
     uint32_t       sequence;
@@ -226,6 +227,21 @@ static int is_audio( hb_work_private_t *r, int id )
     return 0;
 }
 
+static int is_subtitle( hb_work_private_t *r, int id )
+{
+    int i;
+    hb_subtitle_t *sub;
+
+    for( i = 0; ( sub = hb_list_item( r->title->list_subtitle, i ) ); ++i )
+    {
+        if ( sub->id == id )
+        {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 // The MPEG STD (Standard Target Decoder) essentially requires that we keep
 // per-stream timing so that when there's a timing discontinuity we can
 // seemlessly join packets on either side of the discontinuity. This join
@@ -601,6 +617,7 @@ void ReadLoop( void * _w )
                              ( st == r->stream_timing && !r->saw_audio ) )
                         {
                             new_scr_offset( r, buf );
+                            r->sub_scr_set = 0;
                         }
                         else
                         {
@@ -609,8 +626,26 @@ void ReadLoop( void * _w )
                             // frame but video & subtitles don't. Clear
                             // the timestamps so the decoder will generate
                             // them from the frame durations.
-                            buf->s.start = AV_NOPTS_VALUE;
-                            buf->s.renderOffset = AV_NOPTS_VALUE;
+                            if (is_subtitle(r, buf->s.id) &&
+                                buf->s.start != AV_NOPTS_VALUE)
+                            {
+                                if (!r->sub_scr_set)
+                                {
+                                    // We can't generate timestamps in the
+                                    // subtitle decoder as we can for
+                                    // audio & video.  So we need to make
+                                    // the closest guess that we can
+                                    // for the subtitles start time here.
+                                    int64_t last = r->stream_timing[0].last;
+                                    r->scr_offset = buf->s.start - last;
+                                    r->sub_scr_set = 1;
+                                }
+                            }
+                            else
+                            {
+                                buf->s.start = AV_NOPTS_VALUE;
+                                buf->s.renderOffset = AV_NOPTS_VALUE;
+                            }
                         }
                     }
                 }