Add option to open a DCP in the player (#1312).
authorCarl Hetherington <cth@carlh.net>
Sat, 9 Jun 2018 22:43:58 +0000 (23:43 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 9 Jun 2018 22:43:58 +0000 (23:43 +0100)
ChangeLog
src/lib/cross.cc
src/lib/cross.h
src/lib/types.h
src/tools/dcpomatic.cc
src/tools/dcpomatic_player.cc

index 842ac5a2afe68af1041cbff0652113868f725fd8..85b0f21a9b803334a69a7e452abd6f97f42c1348 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,8 @@
-2018-06-08  Carl Hetherington  <cth@carlh.net>
+2018-06-09  Carl Hetherington  <cth@carlh.net>
+
+       * Add option to open a DCP in the player (#1312).
+
+a2018-06-08  Carl Hetherington  <cth@carlh.net>
 
        * Add support for rotation and flipping of video sources,
        and auto-detect when this is necessary (#966).
index 4991d9ae38e3fef519e4ec297c8a021c903e0eb2..75205dc1aa11709d84b651421f452005e0399b6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -414,6 +414,12 @@ start_batch_converter (boost::filesystem::path dcpomatic)
        start_tool (dcpomatic, "dcpomatic2_batch", "DCP-o-matic\\ 2\\ Batch\\ Converter.app");
 }
 
+void
+start_player (boost::filesystem::path dcpomatic)
+{
+       start_tool (dcpomatic, "dcpomatic2_player", "DCP-o-matic\\ 2\\ Player.app");
+}
+
 uint64_t
 thread_id ()
 {
index 8c1df998b56dec3ccdfd8758fa0262a4a76f1fa4..f1af03346d5253ace206a45dc17b5a957e101901 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -52,6 +52,7 @@ extern boost::filesystem::path shared_path ();
 extern FILE * fopen_boost (boost::filesystem::path, std::string);
 extern int dcpomatic_fseek (FILE *, int64_t, int);
 extern void start_batch_converter (boost::filesystem::path dcpomatic);
+extern void start_player (boost::filesystem::path dcpomatic);
 extern uint64_t thread_id ();
 extern int avio_open_boost (AVIOContext** s, boost::filesystem::path file, int flags);
 
index ed3746f45ae5c99e76cbaea0461130273cccec0f..dfce6aec54be448c4c3e87658576783ca5ebba77 100644 (file)
@@ -80,6 +80,8 @@ namespace xmlpp {
 #define BATCH_SERVER_PRESENCE_PORT (Config::instance()->server_port_base()+3)
 /** Port on which batch converter listens for job requests */
 #define BATCH_JOB_PORT (Config::instance()->server_port_base()+4)
+/** Port on which player listens for play requests */
+#define PLAYER_PLAY_PORT (Config::instance()->server_port_base()+5)
 
 typedef std::vector<boost::shared_ptr<Content> > ContentList;
 typedef std::vector<boost::shared_ptr<FFmpegContent> > FFmpegContentList;
index f349a7cf3be7152c3877318f3a5b13ecee7ac34a..64c11281c276529063c5f70dd293ce3a5ddf0853 100644 (file)
@@ -211,6 +211,7 @@ enum {
        ID_jobs_export,
        ID_jobs_send_dcp_to_tms,
        ID_jobs_show_dcp,
+       ID_jobs_open_dcp_in_player,
        ID_tools_video_waveform,
        ID_tools_hints,
        ID_tools_encoding_servers,
@@ -295,6 +296,7 @@ public:
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_export, this),             ID_jobs_export);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_send_dcp_to_tms, this),    ID_jobs_send_dcp_to_tms);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_show_dcp, this),           ID_jobs_show_dcp);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_open_dcp_in_player, this), ID_jobs_open_dcp_in_player);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_video_waveform, this),    ID_tools_video_waveform);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_hints, this),             ID_tools_hints);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_encoding_servers, this),  ID_tools_encoding_servers);
@@ -739,6 +741,17 @@ private:
                }
        }
 
+       void jobs_open_dcp_in_player ()
+       {
+               if (!_film) {
+                       return;
+               }
+
+               if (send_to_other_tool (PLAYER_PLAY_PORT, bind (&start_player, _1), _film->dir(_film->dcp_name(false)).string())) {
+                       error_dialog (this, _("Could not find player."));
+               }
+       }
+
        void jobs_make_self_dkdm ()
        {
                if (!_film) {
@@ -1120,6 +1133,7 @@ private:
                jobs_menu->AppendSeparator ();
                add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
                add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+               add_item (jobs_menu, _("Open DCP in &player"), ID_jobs_open_dcp_in_player, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
 
                wxMenu* tools = new wxMenu;
                add_item (tools, _("Video waveform..."), ID_tools_video_waveform, NEEDS_FILM);
index 5c8c7d1d5f3177a1721a317a7dfec88628e75509..839886c8716fd8f2848aaff4274d221ff6802344 100644 (file)
@@ -32,6 +32,8 @@
 #include "lib/verify_dcp_job.h"
 #include "lib/dcp_examiner.h"
 #include "lib/examine_content_job.h"
+#include "lib/server.h"
+#include "lib/dcpomatic_socket.h"
 #include "wx/wx_signal_manager.h"
 #include "wx/wx_util.h"
 #include "wx/about_dialog.h"
@@ -65,8 +67,10 @@ using std::list;
 using std::exception;
 using std::vector;
 using boost::shared_ptr;
+using boost::scoped_array;
 using boost::optional;
 using boost::dynamic_pointer_cast;
+using boost::thread;
 
 enum {
        ID_file_open = 1,
@@ -647,6 +651,32 @@ static const wxCmdLineEntryDesc command_line_description[] = {
        { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 }
 };
 
+class PlayServer : public Server
+{
+public:
+       explicit PlayServer (DOMFrame* frame)
+               : Server (PLAYER_PLAY_PORT)
+               , _frame (frame)
+       {}
+
+       void handle (shared_ptr<Socket> socket)
+       {
+               try {
+                       int const length = socket->read_uint32 ();
+                       scoped_array<char> buffer (new char[length]);
+                       socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
+                       string s (buffer.get());
+                       signal_manager->when_idle (bind (&DOMFrame::load_dcp, _frame, s));
+                       socket->write (reinterpret_cast<uint8_t const *> ("OK"), 3);
+               } catch (...) {
+
+               }
+       }
+
+private:
+       DOMFrame* _frame;
+};
+
 /** @class App
  *  @brief The magic App class for wxWidgets.
  */
@@ -716,6 +746,9 @@ private:
 
                signal_manager = new wxSignalManager (this);
 
+               PlayServer* server = new PlayServer (_frame);
+               new thread (boost::bind (&PlayServer::run, server));
+
                if (!_dcp_to_load.empty() && boost::filesystem::is_directory (_dcp_to_load)) {
                        try {
                                _frame->load_dcp (_dcp_to_load);