Fix ignore_video checker for separate-3D content (#2246).
[dcpomatic.git] / src / lib / player.cc
index 619a3583cbb770e6c5d6f3f2329e4aa0d6e4f43d..f3d78ab323803b396186ba928b5688c129b469a3 100644 (file)
@@ -166,8 +166,19 @@ Player::setup_pieces_unlocked ()
        auto old_pieces = _pieces;
        _pieces.clear ();
 
-       _shuffler.reset (new Shuffler());
-       _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
+       auto playlist_content = playlist()->content();
+       bool const have_threed = std::any_of(
+               playlist_content.begin(),
+               playlist_content.end(),
+               [](shared_ptr<const Content> c) {
+                       return c->video && (c->video->frame_type() == VideoFrameType::THREE_D_LEFT || c->video->frame_type() == VideoFrameType::THREE_D_RIGHT);
+               });
+
+
+       if (have_threed) {
+               _shuffler.reset(new Shuffler());
+               _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
+       }
 
        for (auto i: playlist()->content()) {
 
@@ -219,7 +230,7 @@ Player::setup_pieces_unlocked ()
                _pieces.push_back (piece);
 
                if (decoder->video) {
-                       if (i->video->frame_type() == VideoFrameType::THREE_D_LEFT || i->video->frame_type() == VideoFrameType::THREE_D_RIGHT) {
+                       if (have_threed) {
                                /* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */
                                decoder->video->Data.connect (bind(&Shuffler::video, _shuffler.get(), weak_ptr<Piece>(piece), _1));
                        } else {
@@ -261,17 +272,17 @@ Player::setup_pieces_unlocked ()
                }
        }
 
+       auto ignore_overlap = [](shared_ptr<VideoContent> v) {
+               return v && v->use() && v->frame_type() != VideoFrameType::THREE_D_LEFT && v->frame_type() != VideoFrameType::THREE_D_RIGHT;
+       };
+
        for (auto i = _pieces.begin(); i != _pieces.end(); ++i) {
-               if (auto video = (*i)->content->video) {
-                       if (video->use() && video->frame_type() != VideoFrameType::THREE_D_LEFT && video->frame_type() != VideoFrameType::THREE_D_RIGHT) {
-                               /* Look for content later in the content list with in-use video that overlaps this */
-                               auto period = DCPTimePeriod((*i)->content->position(), (*i)->content->end(_film));
-                               auto j = i;
-                               ++j;
-                               for (; j != _pieces.end(); ++j) {
-                                       if ((*j)->content->video && (*j)->content->video->use()) {
-                                               (*i)->ignore_video = DCPTimePeriod((*j)->content->position(), (*j)->content->end(_film)).overlap(period);
-                                       }
+               if (ignore_overlap((*i)->content->video)) {
+                       /* Look for content later in the content list with in-use video that overlaps this */
+                       auto const period = DCPTimePeriod((*i)->content->position(), (*i)->content->end(_film));
+                       for (auto j = std::next(i); j != _pieces.end(); ++j) {
+                               if ((*j)->content->video && ignore_overlap((*j)->content->video)) {
+                                       (*i)->ignore_video = DCPTimePeriod((*j)->content->position(), (*j)->content->end(_film)).overlap(period);
                                }
                        }
                }
@@ -810,7 +821,9 @@ Player::pass ()
        }
 
        if (done) {
-               _shuffler->flush ();
+               if (_shuffler) {
+                       _shuffler->flush ();
+               }
                for (auto const& i: _delay) {
                        do_emit_video(i.first, i.second);
                }
@@ -1432,6 +1445,22 @@ Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t)
 }
 
 
+optional<ContentTime>
+Player::dcp_to_content_time (shared_ptr<const Content> content, DCPTime t)
+{
+       boost::mutex::scoped_lock lm (_mutex);
+
+       for (auto i: _pieces) {
+               if (i->content == content) {
+                       return dcp_to_content_time (i, t);
+               }
+       }
+
+       /* We couldn't find this content; perhaps things are being changed over */
+       return {};
+}
+
+
 shared_ptr<const Playlist>
 Player::playlist () const
 {