]> granicus.if.org Git - handbrake/commitdiff
sync: don't delay subtitles when duration is known
authorJohn Stebbins <jstebbins.hb@gmail.com>
Thu, 15 Dec 2016 23:09:45 +0000 (15:09 -0800)
committerJohn Stebbins <jstebbins.hb@gmail.com>
Thu, 15 Dec 2016 23:18:55 +0000 (15:18 -0800)
Delayed subtitles were causing incorrect muxing in mkv.  The mkv muxer
writes chunks where all samples should be relative to a chunk's base
timestamp.  When the subtitle is delayed long enough for a new chunk to
start before it gets muxed, the calculated offset to the chunk's base
time is negative (which is illegal).

Note that this is still a possibility with subtitles that must be
delayed (e.g. CC and VOBSUB) because the duration is not known until
the next subtitle's start time is known. The only fix for this would be
to add a special subtitle parsing pass that caches subtitle timestamps
before the main encoding pass is performed.

libhb/sync.c

index 4d2e88a826fd0ce228e1c4d6094c08c0a0cb44e1..154346f48a770f0e4bc65c49b7456a7ce02d4c7f 100644 (file)
@@ -2587,18 +2587,22 @@ static hb_buffer_t * mergeSubtitles(sync_stream_t * stream)
 
     if (!sanitizer->merge)
     {
-        int limit = sanitizer->link ? 1 : 0;
-
         // Handle all but the last buffer
         // The last buffer may not have been "linked" yet
-        while (hb_buffer_list_count(&sanitizer->list_current) > limit)
+        while (hb_buffer_list_count(&sanitizer->list_current) > 0)
         {
-            buf = hb_buffer_list_rem_head(&sanitizer->list_current);
-            if (!(buf->s.flags & HB_BUF_FLAG_EOF))
+            buf = hb_buffer_list_head(&sanitizer->list_current);
+            if (!(buf->s.flags & HB_BUF_FLAG_EOF) &&
+                buf->s.stop != AV_NOPTS_VALUE)
             {
+                buf = hb_buffer_list_rem_head(&sanitizer->list_current);
                 buf = setSubDuration(stream, buf);
                 hb_buffer_list_append(&list, buf);
             }
+            else
+            {
+                break;
+            }
         }
         return hb_buffer_list_clear(&list);
     }