Primitive subtitle export feature.
[dcpomatic.git] / src / lib / player.cc
index 6f0cfd1af7e9490f216b2d243742b86d081badb5..23fe65cf4c8fcfd9448975d1b050edc7f787c8cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -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>
@@ -92,6 +93,7 @@ Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist
        , _ignore_text (false)
        , _always_burn_open_subtitles (false)
        , _fast (false)
+       , _tolerant (film->tolerant())
        , _play_referenced (false)
        , _audio_merger (_film->audio_frame_rate())
        , _shuffler (0)
@@ -137,6 +139,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 +157,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, _tolerant, old_decoder);
                FrameRateChange frc (_film, i);
 
                if (!decoder) {
@@ -493,7 +504,7 @@ Player::get_reel_assets ()
 
                scoped_ptr<DCPDecoder> decoder;
                try {
-                       decoder.reset (new DCPDecoder (_film, j, false));
+                       decoder.reset (new DCPDecoder (_film, j, false, false, shared_ptr<DCPDecoder>()));
                } catch (...) {
                        return a;
                }
@@ -1044,8 +1055,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 */