From 179f018d8e472a5014bb79aafd93d06641577dfa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Oct 2023 19:11:45 +0200 Subject: [PATCH] Another patch from Aaron. --- src/lib/grok/context.h | 48 ++++++++++++++++++++---------- src/lib/grok/messenger.h | 63 +++++++++++++++++++++------------------- src/lib/j2k_encoder.cc | 27 +++++++++++++++++ 3 files changed, 92 insertions(+), 46 deletions(-) diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 96477d597..e7b5dbcbc 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -20,6 +20,9 @@ #pragma once +#include +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 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 *messenger_; bool launched_; + bool launchFailed_; }; } diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index bb7ada213..51526aee3 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -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 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 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_; diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index ad04ac0fa..3bb7ccaed 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -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. -- 2.30.2