#pragma once
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
#include "../config.h"
#include "../dcp_video.h"
#include "../film.h"
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);
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_;
}
DcpomaticContext* _dcpomatic_context;
ScheduledMessenger<FrameProxy> *messenger_;
bool launched_;
+ bool launchFailed_;
};
}
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,
sendQueue.push(oss.str());
}
- void launchGrok(
+ bool launchGrok(
boost::filesystem::path const& dir,
uint32_t width,
uint32_t stride,
std::unique_lock<std::mutex> lk(shutdownMutex_);
if (async_result_.valid())
- return;
+ return true;
if(MessengerInit::firstLaunch(true))
init_.unlink();
startThreads();
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)
{
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;
}
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())
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_;