Use an enum instead of a bool to specify blocking/non-blocking.
[dcpomatic.git] / src / wx / video_view.cc
index 5f44c37d61779db3cced384221af5fdba9289506..1c645f11f688bd6adab4924c07ad9b0fcd25811c 100644 (file)
 #include "lib/butler.h"
 #include "lib/dcpomatic_log.h"
 #include <boost/optional.hpp>
+#include <sys/time.h>
+
 
-using std::pair;
 using std::shared_ptr;
 using boost::optional;
 
 
+static constexpr int TOO_MANY_DROPPED_FRAMES = 20;
+static constexpr int TOO_MANY_DROPPED_PERIOD = 5.0;
+
+
 VideoView::VideoView (FilmViewer* viewer)
        : _viewer (viewer)
        , _state_timer ("viewer")
@@ -70,12 +75,12 @@ VideoView::get_next_frame (bool non_blocking)
 
        do {
                Butler::Error e;
-               auto pv = butler->get_video (!non_blocking, &e);
-               if (e.code == Butler::Error::DIED) {
+               auto pv = butler->get_video (non_blocking ? Butler::Behaviour::NON_BLOCKING : Butler::Behaviour::BLOCKING, &e);
+               if (e.code == Butler::Error::Code::DIED) {
                        LOG_ERROR ("Butler died with %1", e.summary());
                }
                if (!pv.first) {
-                       return e.code == Butler::Error::AGAIN ? AGAIN : FAIL;
+                       return e.code == Butler::Error::Code::AGAIN ? AGAIN : FAIL;
                }
                _player_video = pv;
        } while (
@@ -124,6 +129,7 @@ VideoView::start ()
        boost::mutex::scoped_lock lm (_mutex);
        _dropped = 0;
        _errored = 0;
+       gettimeofday(&_dropped_check_period_start, nullptr);
 }
 
 
@@ -143,3 +149,40 @@ VideoView::reset_metadata (shared_ptr<const Film> film, dcp::Size player_video_c
        return true;
 }
 
+
+void
+VideoView::add_dropped ()
+{
+       bool too_many = false;
+
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               ++_dropped;
+               if (_dropped > TOO_MANY_DROPPED_FRAMES) {
+                       struct timeval now;
+                       gettimeofday (&now, nullptr);
+                       double const elapsed = seconds(now) - seconds(_dropped_check_period_start);
+                       too_many = elapsed < TOO_MANY_DROPPED_PERIOD;
+                       _dropped = 0;
+                       _dropped_check_period_start = now;
+               }
+       }
+
+       if (too_many) {
+               emit (boost::bind(boost::ref(TooManyDropped)));
+       }
+}
+
+
+wxColour
+VideoView::pad_colour () const
+{
+       if (_viewer->pad_black()) {
+               return wxColour(0, 0, 0);
+       } else if (gui_is_dark()) {
+               return wxColour(50, 50, 50);
+       } else {
+               return wxColour(240, 240, 240);
+       }
+}
+