#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"
#include "lib/ffmpeg_content.h"
#include "lib/dcpomatic_log.h"
#include "lib/file_log.h"
+#include <dcp/cpl.h>
#include <dcp/dcp.h>
#include <dcp/raw_convert.h>
#include <dcp/exceptions.h>
_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__
_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());
_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);
}
_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 {