More player debugging for butler video-full states.
[dcpomatic.git] / src / lib / shuffler.cc
index 84bf98ed254cbb43b4078cafa66e988a3e7a5f00..a46b26da0f85ee652fdd83f6e18fa1f1f7382e10 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -21,6 +21,7 @@
 #include "shuffler.h"
 #include "content_video.h"
 #include "dcpomatic_assert.h"
+#include "dcpomatic_log.h"
 #include <boost/foreach.hpp>
 #include <iostream>
 
@@ -29,6 +30,8 @@ using boost::weak_ptr;
 using boost::shared_ptr;
 using boost::optional;
 
+int const Shuffler::_max_size = 64;
+
 struct Comparator
 {
        bool operator()(Shuffler::Store const & a, Shuffler::Store const & b) {
@@ -42,16 +45,17 @@ 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);
+       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 ();
        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) {
+               /* 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,14 +64,27 @@ 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 && _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);
+               }
 
                Video (_store.front().first, _store.front().second);
                _last = _store.front().second;
@@ -78,6 +95,7 @@ Shuffler::video (weak_ptr<Piece> weak_piece, ContentVideo video)
 void
 Shuffler::clear ()
 {
+       _store.clear ();
        _last = optional<ContentVideo>();
 }