Remove in-place translations support.
[dcpomatic.git] / src / lib / shuffler.cc
index 0ec4daf5ad654bab9a1c8ef17f17eddfca96bb49..5a4faf4d15fa4c0f74617bd2bd03ecd57f1ba114 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 #include "shuffler.h"
 #include "content_video.h"
 #include "dcpomatic_assert.h"
-#include <boost/foreach.hpp>
+#include "dcpomatic_log.h"
+#include <string>
 #include <iostream>
 
+
 using std::make_pair;
-using boost::weak_ptr;
-using boost::shared_ptr;
+using std::shared_ptr;
+using std::string;
+using std::weak_ptr;
 using boost::optional;
 
+
+int const Shuffler::_max_size = 64;
+
+
 struct Comparator
 {
        bool operator()(Shuffler::Store const & a, Shuffler::Store const & b) {
@@ -39,19 +47,24 @@ struct Comparator
        }
 };
 
+
 void
 Shuffler::video (weak_ptr<Piece> weak_piece, ContentVideo video)
 {
-       /* Something has gong wrong if our store gets too big */
-       DCPOMATIC_ASSERT (_store.size() != 8);
-       /* We should only ever see 3D_LEFT / 3D_RIGHT */
-       DCPOMATIC_ASSERT (video.eyes == EYES_LEFT || video.eyes == EYES_RIGHT);
+       LOG_DEBUG_THREE_D ("Shuffler::video frame=%1 eyes=%2 part=%3", video.frame, static_cast<int>(video.eyes), static_cast<int>(video.part));
+
+       if (video.eyes != Eyes::LEFT && video.eyes != Eyes::RIGHT) {
+               /* Pass through anything that we don't care about */
+               Video (weak_piece, video);
+               return;
+       }
 
-       shared_ptr<Piece> piece = weak_piece.lock ();
+       auto piece = weak_piece.lock ();
        DCPOMATIC_ASSERT (piece);
 
-       if (!_last) {
-               /* We haven't seen anything since the last clear() so assume everything is OK */
+       if (!_last && video.eyes == Eyes::LEFT) {
+               LOG_DEBUG_THREE_D_NC ("Shuffler first after clear");
+               /* We haven't seen anything since the last clear() and we have some eyes-left so assume everything is OK */
                Video (weak_piece, video);
                _last = video;
                return;
@@ -60,32 +73,55 @@ Shuffler::video (weak_ptr<Piece> weak_piece, ContentVideo video)
        _store.push_back (make_pair (weak_piece, video));
        _store.sort (Comparator());
 
-       while (
-               !_store.empty() &&
-               (
-                       (_store.front().second.frame == _last->frame && _store.front().second.eyes == EYES_RIGHT && _last->eyes == EYES_LEFT) ||
-                       (_store.front().second.frame == (_last->frame + 1) && _store.front().second.eyes == EYES_LEFT && _last->eyes == EYES_RIGHT) ||
-                       _store.size() > 8
-                       )
-               ) {
+       while (true) {
 
+               bool const store_front_in_sequence =
+                       !_store.empty() &&
+                       _last &&
+                       (
+                               (_store.front().second.frame == _last->frame       && _store.front().second.eyes == Eyes::RIGHT && _last->eyes == Eyes::LEFT) ||
+                               (_store.front().second.frame >= (_last->frame + 1) && _store.front().second.eyes == Eyes::LEFT  && _last->eyes == Eyes::RIGHT)
+                               );
+
+               if (!store_front_in_sequence) {
+                       string const store = _store.empty() ? "store empty" : String::compose("store front frame=%1 eyes=%2", _store.front().second.frame, static_cast<int>(_store.front().second.eyes));
+                       string const last = _last ? String::compose("last frame=%1 eyes=%2", _last->frame, static_cast<int>(_last->eyes)) : "no last";
+                       LOG_DEBUG_THREE_D("Shuffler not in sequence: %1 %2", store, last);
+               }
+
+               if (!store_front_in_sequence && _store.size() <= _max_size) {
+                       /* store_front_in_sequence means everything is ok; otherwise if the store is getting too big just
+                          start emitting things as best we can.  This can easily happen if, for example, there is only content
+                          for one eye in some part of the timeline.
+                       */
+                       break;
+               }
+
+               if (_store.size() > _max_size) {
+                       LOG_WARNING ("Shuffler is full after receiving frame %1; 3D sync may be incorrect.", video.frame);
+               }
+
+               LOG_DEBUG_THREE_D("Shuffler emits frame=%1 eyes=%2 store=%3", _store.front().second.frame, static_cast<int>(_store.front().second.eyes), _store.size());
                Video (_store.front().first, _store.front().second);
                _last = _store.front().second;
                _store.pop_front ();
        }
 }
 
+
 void
 Shuffler::clear ()
 {
+       LOG_DEBUG_THREE_D_NC ("Shuffler::clear");
        _store.clear ();
        _last = optional<ContentVideo>();
 }
 
+
 void
 Shuffler::flush ()
 {
-       BOOST_FOREACH (Store i, _store) {
+       for (auto i: _store) {
                Video (i.first, i.second);
        }
 }