Another patch from Aaron.
authorCarl Hetherington <cth@carlh.net>
Wed, 4 Oct 2023 17:11:45 +0000 (19:11 +0200)
committerCarl Hetherington <cth@carlh.net>
Mon, 16 Oct 2023 15:57:18 +0000 (17:57 +0200)
src/lib/grok/context.h
src/lib/grok/messenger.h
src/lib/j2k_encoder.cc

index 96477d597deac87c2961fa322ba233a0056c9d4c..e7b5dbcbc221b3367d365f92e29182e03de36c15 100644 (file)
@@ -20,6 +20,9 @@
 
 #pragma once
 
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
 #include "../config.h"
 #include "../dcp_video.h"
 #include "../film.h"
@@ -106,10 +109,11 @@ struct DcpomaticContext {
 class GrokContext
 {
 public:
-       explicit GrokContext(DcpomaticContext* dcpomatic_context)
-               : _dcpomatic_context(dcpomatic_context)
-               , messenger_(nullptr)
-               , launched_(false)
+       explicit GrokContext(DcpomaticContext* dcpomatic_context) :
+                                                               _dcpomatic_context(dcpomatic_context),
+                                                               messenger_(nullptr),
+                                                               launched_(false),
+                                                               launchFailed_(false)
        {
                if (Config::instance()->enable_gpu ())  {
                    boost::filesystem::path folder(_dcpomatic_context->_location);
@@ -170,29 +174,40 @@ public:
                        return false;
                if (launched_)
                        return true;
+               if (launchFailed_)
+                       return false;
                std::unique_lock<std::mutex> lk_global(launchMutex);
                if (!messenger_)
                        return false;
                if (launched_)
                        return true;
+               if (launchFailed_)
+                       return false;
                if (MessengerInit::firstLaunch(true)) {
+
+                   if (!fs::exists(_dcpomatic_context->_location) || !fs::is_directory(_dcpomatic_context->_location)) {
+                       getMessengerLogger()->error("Invalid directory %s", _dcpomatic_context->_location.c_str());
+                               return false;
+                   }
                        auto s = dcpv.get_size();
                        _dcpomatic_context->setDimensions(s.width, s.height);
                        auto config = Config::instance();
-                       messenger_->launchGrok(
-                               _dcpomatic_context->_location,
-                               _dcpomatic_context->width_,_dcpomatic_context->width_,
-                               _dcpomatic_context->height_,
-                               3, 12, device,
-                               _dcpomatic_context->film_->resolution() == Resolution::FOUR_K,
-                               _dcpomatic_context->film_->video_frame_rate(),
-                               _dcpomatic_context->film_->j2k_bandwidth(),
-                               config->gpu_license_server(),
-                               config->gpu_license_port(),
-                               config->gpu_license()
-                               );
+                       if (!messenger_->launchGrok(_dcpomatic_context->_location,
+                                       _dcpomatic_context->width_,_dcpomatic_context->width_,
+                                       _dcpomatic_context->height_,
+                                       3, 12, device,
+                                       _dcpomatic_context->film_->resolution() == Resolution::FOUR_K,
+                                       _dcpomatic_context->film_->video_frame_rate(),
+                                       _dcpomatic_context->film_->j2k_bandwidth(),
+                                       config->gpu_license_server(),
+                                       config->gpu_license_port(),
+                                       config->gpu_license())) {
+                               launchFailed_ = true;
+                               return false;
+                       }
                }
                launched_ =  messenger_->waitForClientInit();
+               launchFailed_ = launched_;
 
                return launched_;
        }
@@ -226,6 +241,7 @@ private:
        DcpomaticContext* _dcpomatic_context;
        ScheduledMessenger<FrameProxy> *messenger_;
        bool launched_;
+       bool launchFailed_;
 };
 
 }
index bb7ada213dbf3219015a35679a768d6669a48dbd..51526aee3a0fc442eb2f66936e4107a9a6f7ef57 100644 (file)
@@ -119,23 +119,10 @@ struct MessengerLogger : public IMessengerLogger
        std::string preamble_;
 };
 
-static IMessengerLogger* sLogger = nullptr;
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-static void setMessengerLogger(IMessengerLogger* logger)
-{
-       delete sLogger;
-       sLogger = logger;
-}
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-static IMessengerLogger* getMessengerLogger(void)
-{
-       return sLogger;
-}
+extern IMessengerLogger* sLogger;
+void setMessengerLogger(IMessengerLogger* logger);
+IMessengerLogger* getMessengerLogger(void);
+
 struct MessengerInit
 {
        MessengerInit(const std::string &outBuf, const std::string &outSent,
@@ -543,7 +530,7 @@ struct Messenger
                sendQueue.push(oss.str());
        }
 
-       void launchGrok(
+       bool launchGrok(
                boost::filesystem::path const& dir,
                uint32_t width,
                uint32_t stride,
@@ -562,7 +549,7 @@ struct Messenger
 
                std::unique_lock<std::mutex> lk(shutdownMutex_);
                if (async_result_.valid())
-                       return;
+                       return true;
                if(MessengerInit::firstLaunch(true))
                        init_.unlink();
                startThreads();
@@ -570,11 +557,12 @@ struct Messenger
                auto fullServer = server + ":" + std::to_string(port);
                sprintf(_cmd,
                                "./grk_compress -batch_src %s,%d,%d,%d,%d,%d -out_fmt j2k -k 1 "
-                               "-G %d -%s %d,%d -j %s -J %s",
+                               "-G %d -%s %d,%d -j %s -J %s -v",
                                GRK_MSGR_BATCH_IMAGE.c_str(), width, stride, height, samplesPerPixel, depth,
                                device, is4K ? "cinema4K" : "cinema2K", fps, bandwidth,
                                license.c_str(), fullServer.c_str());
-               launch(_cmd, dir);
+
+               return launch(_cmd, dir);
        }
        void initClient(size_t uncompressedFrameSize, size_t compressedFrameSize, size_t numFrames)
        {
@@ -597,19 +585,27 @@ struct Messenger
 
        bool waitForClientInit()
        {
-               if (_initialized) {
+               if(_initialized)
                        return true;
-               }
+               else if (_shutdown)
+                       return false;
 
                std::unique_lock<std::mutex> lk(shutdownMutex_);
-
-               if (_initialized) {
+               if(_initialized)
                        return true;
-               } else if (_shutdown) {
+               else if (_shutdown)
                        return false;
-               }
 
-               clientInitializedCondition_.wait(lk, [this] { return _initialized || _shutdown; });
+        while (true) {
+               if (clientInitializedCondition_.wait_for(lk, std::chrono::seconds(1), [this]{ return _initialized || _shutdown; })) {
+                break;
+            }
+            auto status = async_result_.wait_for(std::chrono::milliseconds(100));
+            if (status == std::future_status::ready) {
+               getMessengerLogger()->error("Grok exited unexpectedly during initialization");
+                return false;
+            }
+        }
 
                return _initialized && !_shutdown;
        }
@@ -657,7 +653,7 @@ struct Messenger
   protected:
        std::condition_variable clientInitializedCondition_;
   private:
-       void launch(std::string const& cmd, boost::filesystem::path const& dir)
+       bool launch(std::string const& cmd, boost::filesystem::path const& dir)
        {
                // Change the working directory
                if(!dir.empty())
@@ -666,12 +662,19 @@ struct Messenger
                        boost::filesystem::current_path(dir, ec);
                        if (ec) {
                                getMessengerLogger()->error("Error: failed to change the working directory");
-                               return;
+                               return false;
                        }
                }
                // Execute the command using std::async and std::system
                cmd_ = cmd;
+               getMessengerLogger()->info(cmd.c_str());
                async_result_ = std::async(std::launch::async, [this]() { return std::system(cmd_.c_str()); });
+               bool success = async_result_.valid();
+               if (!success)
+                       getMessengerLogger()->error("Grok launch failed");
+
+               return success;
+
        }
        std::thread outbound;
        Synch* outboundSynch_;
index ad04ac0fa56e952948455f9b50a036e93bba916d..3bb7ccaedc4f99bd454656d08f49ebc14ebcbadc 100644 (file)
@@ -60,6 +60,33 @@ using boost::optional;
 using dcp::Data;
 using namespace dcpomatic;
 
+#ifdef DCPOMATIC_GROK
+
+namespace grk_plugin {
+
+IMessengerLogger* sLogger = nullptr;
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+void setMessengerLogger(grk_plugin::IMessengerLogger* logger)
+{
+       delete sLogger;
+       sLogger = logger;
+}
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+grk_plugin::IMessengerLogger* getMessengerLogger(void)
+{
+       return sLogger;
+}
+
+}
+
+#endif
+
 
 /** @param film Film that we are encoding.
  *  @param writer Writer that we are using.