summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-04-03 23:17:56 +0200
committerCarl Hetherington <cth@carlh.net>2021-04-03 23:17:56 +0200
commita7a8cd74f2f32de8b708c78cc8bc9c0cf17d60f5 (patch)
treecb582fa9ed35e1c7383675761b5955922aef3617 /src
parent996d8defbb783e5c82ef31a71fb6a06a6a5ab873 (diff)
Show an explanatory message if the player is not performing very well (#1932).
Diffstat (limited to 'src')
-rw-r--r--src/lib/config.h4
-rw-r--r--src/wx/film_viewer.cc33
-rw-r--r--src/wx/film_viewer.h1
-rw-r--r--src/wx/nag_dialog.cc2
-rw-r--r--src/wx/video_view.cc30
-rw-r--r--src/wx/video_view.h13
6 files changed, 71 insertions, 12 deletions
diff --git a/src/lib/config.h b/src/lib/config.h
index 3371e48bf..0a48a00e1 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -392,6 +392,9 @@ public:
return _jump_to_selected;
}
+ /* This could be an enum class but we use the enum a lot to index _nagged
+ * so it means a lot of casts.
+ */
enum Nag {
NAG_DKDM_CONFIG,
NAG_ENCRYPTED_METADATA,
@@ -400,6 +403,7 @@ public:
NAG_IMPORT_DECRYPTION_CHAIN,
NAG_DELETE_DKDM,
NAG_32_ON_64,
+ NAG_TOO_MANY_DROPPED_FRAMES,
NAG_COUNT
};
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index b9e9bd533..14737d009 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -18,17 +18,20 @@
*/
+
/** @file src/film_viewer.cc
* @brief A wx widget to view a preview of a Film.
*/
-#include "film_viewer.h"
-#include "playhead_to_timecode_dialog.h"
-#include "playhead_to_frame_dialog.h"
-#include "wx_util.h"
+
#include "closed_captions_dialog.h"
+#include "film_viewer.h"
#include "gl_video_view.h"
+#include "nag_dialog.h"
+#include "playhead_to_frame_dialog.h"
+#include "playhead_to_timecode_dialog.h"
#include "simple_video_view.h"
+#include "wx_util.h"
#include "lib/film.h"
#include "lib/ratio.h"
#include "lib/util.h"
@@ -106,6 +109,7 @@ FilmViewer::FilmViewer (wxWindow* p)
}
_video_view->Sized.connect (boost::bind(&FilmViewer::video_view_sized, this));
+ _video_view->TooManyDropped.connect (boost::bind(&FilmViewer::too_many_frames_dropped, this));
set_film (shared_ptr<Film> ());
@@ -730,3 +734,22 @@ FilmViewer::image_changed (shared_ptr<PlayerVideo> pv)
emit (boost::bind(boost::ref(ImageChanged), pv));
}
+
+void
+FilmViewer::too_many_frames_dropped ()
+{
+ if (!Config::instance()->nagged(Config::NAG_TOO_MANY_DROPPED_FRAMES)) {
+ stop ();
+ }
+
+ bool shown = NagDialog::maybe_nag (
+ panel(),
+ Config::NAG_TOO_MANY_DROPPED_FRAMES,
+ _("The player is dropping a lot of frames, so playback may not be accurate.\n\n"
+ "<b>This does not necessarily mean that the DCP you are playing is defective!</b>\n\n"
+ "You may be able to improve player performance by:\n"
+ "• choosing 'decode at half resolution' or 'decode at quarter resolution' from the View menu\n"
+ "• using a more powerful computer.\n"
+ )
+ );
+}
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index 8024bb1bf..52b97f0f6 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -161,6 +161,7 @@ private:
void config_changed (Config::Property);
void film_length_change ();
void ui_finished ();
+ void too_many_frames_dropped ();
dcpomatic::DCPTime uncorrected_time () const;
Frame average_latency () const;
diff --git a/src/wx/nag_dialog.cc b/src/wx/nag_dialog.cc
index 466b80b6b..85f2d0110 100644
--- a/src/wx/nag_dialog.cc
+++ b/src/wx/nag_dialog.cc
@@ -70,7 +70,7 @@ NagDialog::maybe_nag (wxWindow* parent, Config::Nag nag, wxString message, bool
return false;
}
- NagDialog* d = new NagDialog (parent, nag, message, can_cancel);
+ auto d = new NagDialog (parent, nag, message, can_cancel);
int const r = d->ShowModal();
d->Destroy ();
diff --git a/src/wx/video_view.cc b/src/wx/video_view.cc
index 5f44c37d6..387d4052f 100644
--- a/src/wx/video_view.cc
+++ b/src/wx/video_view.cc
@@ -25,12 +25,18 @@
#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")
@@ -124,6 +130,7 @@ VideoView::start ()
boost::mutex::scoped_lock lm (_mutex);
_dropped = 0;
_errored = 0;
+ gettimeofday(&_dropped_check_period_start, nullptr);
}
@@ -143,3 +150,26 @@ 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)));
+ }
+}
diff --git a/src/wx/video_view.h b/src/wx/video_view.h
index d3a15d38c..d7d60c21d 100644
--- a/src/wx/video_view.h
+++ b/src/wx/video_view.h
@@ -24,9 +24,10 @@
#include "lib/dcpomatic_time.h"
+#include "lib/exception_store.h"
+#include "lib/signaller.h"
#include "lib/timer.h"
#include "lib/types.h"
-#include "lib/exception_store.h"
#include <boost/signals2.hpp>
#include <boost/thread.hpp>
@@ -38,7 +39,7 @@ class Player;
class PlayerVideo;
-class VideoView : public ExceptionStore
+class VideoView : public ExceptionStore, public Signaller
{
public:
VideoView (FilmViewer* viewer);
@@ -70,6 +71,8 @@ public:
/** Emitted from the GUI thread when our display changes in size */
boost::signals2::signal<void()> Sized;
+ /** Emitted from the GUI thread when a lot of frames are being dropped */
+ boost::signals2::signal<void()> TooManyDropped;
/* Accessors for FilmViewer */
@@ -143,10 +146,7 @@ protected:
return _player_video;
}
- void add_dropped () {
- boost::mutex::scoped_lock lm (_mutex);
- ++_dropped;
- }
+ void add_dropped ();
void add_get () {
boost::mutex::scoped_lock lm (_mutex);
@@ -169,6 +169,7 @@ private:
bool _three_d = false;
int _dropped = 0;
+ struct timeval _dropped_check_period_start;
int _errored = 0;
int _gets = 0;
};