Avoid random black gaps between bits of content A and B when
[dcpomatic.git] / src / lib / player.cc
index 6f0cfd1af7e9490f216b2d243742b86d081badb5..bdfa51528deb305c4b72e09b457490012e7f50bb 100644 (file)
@@ -48,6 +48,7 @@
 #include "image_decoder.h"
 #include "compose.hpp"
 #include "shuffler.h"
+#include "timer.h"
 #include <dcp/reel.h>
 #include <dcp/reel_sound_asset.h>
 #include <dcp/reel_subtitle_asset.h>
@@ -137,6 +138,7 @@ have_audio (shared_ptr<Piece> piece)
 void
 Player::setup_pieces_unlocked ()
 {
+       list<shared_ptr<Piece> > old_pieces = _pieces;
        _pieces.clear ();
 
        delete _shuffler;
@@ -154,7 +156,15 @@ Player::setup_pieces_unlocked ()
                        continue;
                }
 
-               shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast);
+               shared_ptr<Decoder> old_decoder;
+               BOOST_FOREACH (shared_ptr<Piece> j, old_pieces) {
+                       if (j->content == i) {
+                               old_decoder = j->decoder;
+                               break;
+                       }
+               }
+
+               shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast, old_decoder);
                FrameRateChange frc (_film, i);
 
                if (!decoder) {
@@ -1044,8 +1054,12 @@ Player::seek (DCPTime time, bool accurate)
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                if (time < i->content->position()) {
-                       /* Before; seek to the start of the content */
-                       i->decoder->seek (dcp_to_content_time (i, i->content->position()), accurate);
+                       /* Before; seek to the start of the content.  Even if this request is for an inaccurate seek
+                          we must seek this (following) content accurately, otherwise when we come to the end of the current
+                          content we may not start right at the beginning of the next, causing a gap (if the next content has
+                          been trimmed to a point between keyframes, or something).
+                       */
+                       i->decoder->seek (dcp_to_content_time (i, i->content->position()), true);
                        i->done = false;
                } else if (i->content->position() <= time && time < i->content->end(_film)) {
                        /* During; seek to position */