Updated de_DE translation from Uwe Dittes.
[dcpomatic.git] / src / tools / dcpomatic_player.cc
index 506ba052e8a113e9dfef7dfe51b4b8f2d9f1529f..7ffb107bfc6bd8fdafff3b839530cae40dd2cfee 100644 (file)
@@ -33,6 +33,7 @@
 #include "wx/system_information_dialog.h"
 #include "wx/player_stress_tester.h"
 #include "wx/verify_dcp_progress_dialog.h"
+#include "wx/nag_dialog.h"
 #include "lib/cross.h"
 #include "lib/config.h"
 #include "lib/util.h"
@@ -210,6 +211,7 @@ public:
                _viewer->PlaybackPermitted.connect (bind(&DOMFrame::playback_permitted, this));
                _viewer->Started.connect (bind(&DOMFrame::playback_started, this, _1));
                _viewer->Stopped.connect (bind(&DOMFrame::playback_stopped, this, _1));
+               _viewer->TooManyDropped.connect (bind(&DOMFrame::too_many_frames_dropped, this));
                _info = new PlayerInformation (_overall_panel, _viewer);
                setup_main_sizer (Config::instance()->player_mode());
 #ifdef __WXOSX__
@@ -259,6 +261,14 @@ public:
                _stress.LoadDCP.connect (boost::bind(&DOMFrame::load_dcp, this, _1));
        }
 
+       ~DOMFrame ()
+       {
+               /* It's important that this is stopped before our frame starts destroying its children,
+                * otherwise UI elements that it depends on will disappear from under it.
+                */
+               _viewer.reset ();
+       }
+
        void setup_main_sizer (Config::PlayerMode mode)
        {
                _main_sizer->Detach (_viewer->panel());
@@ -339,6 +349,25 @@ public:
                _controls->log (wxString::Format("playback-stopped %s", time.timecode(_film->video_frame_rate()).c_str()));
        }
 
+
+       void too_many_frames_dropped ()
+       {
+               if (!Config::instance()->nagged(Config::NAG_TOO_MANY_DROPPED_FRAMES)) {
+                       _viewer->stop ();
+               }
+
+               NagDialog::maybe_nag (
+                       this,
+                       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"
+                        )
+                       );
+       }
+
        void set_decode_reduction (optional<int> reduction)
        {
                _viewer->set_dcp_decode_reduction (reduction);
@@ -1142,8 +1171,15 @@ private:
                        }
                        _frame->Show ();
 
-                       PlayServer* server = new PlayServer (_frame);
-                       new thread (boost::bind (&PlayServer::run, server));
+                       try {
+                               auto server = new PlayServer (_frame);
+                               new thread (boost::bind (&PlayServer::run, server));
+                       } catch (std::exception& e) {
+                               /* This is not the end of the world; probably a failure to bind the server socket
+                                * because there's already another player running.
+                                */
+                               LOG_DEBUG_PLAYER ("Failed to start play server (%1)", e.what());
+                       }
 
                        if (!_dcp_to_load.empty() && boost::filesystem::is_directory (_dcp_to_load)) {
                                try {