From 444d0aa066758da92f000f434a53a1ba043dbfad Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 7 Jul 2023 23:24:45 +0200 Subject: Move grok headers into src/lib/grok --- src/lib/grok/context.h | 246 +++++++++++++ src/lib/grok/messenger.h | 930 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1176 insertions(+) create mode 100644 src/lib/grok/context.h create mode 100644 src/lib/grok/messenger.h (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h new file mode 100644 index 000000000..7a447d35a --- /dev/null +++ b/src/lib/grok/context.h @@ -0,0 +1,246 @@ +/* + Copyright (C) 2023 Grok Image Compression Inc. + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + +#pragma once + +#include "../config.h" +#include "../dcp_video.h" +#include "../log.h" +#include "../dcpomatic_log.h" +#include "../writer.h" +#include "messenger.h" + +class Film; +using dcp::Data; +using namespace dcpomatic; + +static std::mutex launchMutex; + +namespace grk_plugin +{ + +struct GrokLogger : public MessengerLogger { + explicit GrokLogger(const std::string &preamble) : MessengerLogger(preamble) + {} + virtual ~GrokLogger() = default; + void info(const char* fmt, ...) override{ + va_list arg; + va_start(arg, fmt); + dcpomatic_log->log(preamble_ + log_message(fmt, arg),LogEntry::TYPE_GENERAL); + va_end(arg); + } + void warn(const char* fmt, ...) override{ + va_list arg; + va_start(arg, fmt); + dcpomatic_log->log(preamble_ + log_message(fmt, arg),LogEntry::TYPE_WARNING); + va_end(arg); + } + void error(const char* fmt, ...) override{ + va_list arg; + va_start(arg, fmt); + dcpomatic_log->log(preamble_ + log_message(fmt, arg),LogEntry::TYPE_ERROR); + va_end(arg); + } +}; + +struct GrokInitializer { + GrokInitializer(void) { + setMessengerLogger(new GrokLogger("[GROK] ")); + } + ~GrokInitializer() = default; +}; + +struct FrameProxy { + FrameProxy(void) : FrameProxy(0,Eyes::LEFT,DCPVideo()) + {} + FrameProxy(int index, Eyes eyes, DCPVideo dcpv) : index_(index), eyes_(eyes), vf(dcpv) + {} + int index() const { + return index_; + } + Eyes eyes(void) const { + return eyes_; + } + int index_; + Eyes eyes_; + DCPVideo vf; +}; + +struct DcpomaticContext { + DcpomaticContext(std::shared_ptr film, Writer& writer, + EventHistory &history, const std::string &location) : + film_(film), writer_(writer), + history_(history), location_(location), + width_(0), height_(0) + {} + void setDimensions(uint32_t w, uint32_t h) { + width_ = w; + height_ = h; + } + std::shared_ptr film_; + Writer& writer_; + EventHistory &history_; + std::string location_; + uint32_t width_; + uint32_t height_; +}; + +class GrokContext { +public: + explicit GrokContext(const DcpomaticContext &dcpomaticContext) : + dcpomaticContext_(dcpomaticContext), + messenger_(nullptr), + launched_(false) + { + struct CompressedData : public dcp::Data { + explicit CompressedData(int dataLen) : data_(new uint8_t[dataLen]), dataLen_(dataLen) + {} + ~CompressedData(void){ + delete[] data_; + } + uint8_t const * data () const override { + return data_; + } + uint8_t * data () override { + return data_; + } + int size () const override { + return dataLen_; + } + uint8_t *data_; + int dataLen_; + }; + if (Config::instance()->enable_gpu ()) { + boost::filesystem::path folder(dcpomaticContext_.location_); + boost::filesystem::path binaryPath = folder / "grk_compress"; + if (!boost::filesystem::exists(binaryPath)) { + getMessengerLogger()->error("Invalid binary location %s", + dcpomaticContext_.location_.c_str()); + return; + } + auto proc = [this](const std::string& str) { + try { + Msg msg(str); + auto tag = msg.next(); + if(tag == GRK_MSGR_BATCH_SUBMIT_COMPRESSED) + { + auto clientFrameId = msg.nextUint(); + auto compressedFrameId = msg.nextUint(); + (void)compressedFrameId; + auto compressedFrameLength = msg.nextUint(); + auto processor = + [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) + { + auto compressedData = std::make_shared(compressedFrameLength); + memcpy(compressedData->data_,compressed,compressedFrameLength ); + dcpomaticContext_.writer_.write(compressedData, srcFrame.index(), srcFrame.eyes()); + frame_done (); + }; + int const minimum_size = 16384; + bool needsRecompression = compressedFrameLength < minimum_size; + messenger_->processCompressed(str, processor, needsRecompression); + if (needsRecompression) { + bool success = false; + auto fp = messenger_->retrieve(clientFrameId, success); + if (!success) + return; + + auto encoded = std::make_shared(fp.vf.encode_locally()); + dcpomaticContext_.writer_.write(encoded, fp.vf.index(), fp.vf.eyes()); + frame_done (); + } + } + } catch (std::exception &ex){ + getMessengerLogger()->error("%s",ex.what()); + } + }; + auto clientInit = + MessengerInit(clientToGrokMessageBuf, clientSentSynch, grokReceiveReadySynch, + grokToClientMessageBuf, grokSentSynch, clientReceiveReadySynch, proc, + std::thread::hardware_concurrency()); + messenger_ = new ScheduledMessenger(clientInit); + } + } + ~GrokContext(void) { + shutdown(); + } + bool launch(DCPVideo dcpv, int device){ + if (!messenger_ ) + return false; + if (launched_) + return true; + std::unique_lock lk_global(launchMutex); + if (!messenger_) + return false; + if (launched_) + return true; + if (MessengerInit::firstLaunch(true)) { + auto s = dcpv.get_size(); + dcpomaticContext_.setDimensions(s.width, s.height); + auto config = Config::instance(); + messenger_->launchGrok(dcpomaticContext_.location_, + dcpomaticContext_.width_,dcpomaticContext_.width_, + dcpomaticContext_.height_, + 3, 12, device, + dcpomaticContext_.film_->resolution() == Resolution::FOUR_K, + dcpomaticContext_.film_->video_frame_rate(), + dcpomaticContext_.film_->j2k_bandwidth(), + config->gpu_license_server(), + config->gpu_license_port(), + config->gpu_license()); + } + launched_ = messenger_->waitForClientInit(); + + return launched_; + } + bool scheduleCompress(const DCPVideo &vf){ + if (!messenger_) + return false; + + auto fp = FrameProxy(vf.index(),vf.eyes(),vf); + auto cvt = [this, &fp](BufferSrc src){ + // xyz conversion + fp.vf.convert_to_xyz((uint16_t*)src.framePtr_); + }; + return messenger_->scheduleCompress(fp, cvt); + } + void shutdown(void){ + if (!messenger_) + return; + + std::unique_lock lk_global(launchMutex); + if (!messenger_) + return; + if (launched_) + messenger_->shutdown(); + delete messenger_; + messenger_ = nullptr; + } + void frame_done () { + dcpomaticContext_.history_.event (); + } +private: + DcpomaticContext dcpomaticContext_; + ScheduledMessenger *messenger_; + bool launched_; +}; + +} + diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h new file mode 100644 index 000000000..45ee752e5 --- /dev/null +++ b/src/lib/grok/messenger.h @@ -0,0 +1,930 @@ +/* + Copyright (C) 2023 Grok Image Compression Inc. + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#include +#pragma warning(disable : 4100) +#else +#include +#include +#include +#include +#include +#endif + +namespace grk_plugin +{ +static std::string grokToClientMessageBuf = "Global\\grok_to_client_message"; +static std::string grokSentSynch = "Global\\grok_sent"; +static std::string clientReceiveReadySynch = "Global\\client_receive_ready"; +static std::string clientToGrokMessageBuf = "Global\\client_to_grok_message"; +static std::string clientSentSynch = "Global\\client_sent"; +static std::string grokReceiveReadySynch = "Global\\grok_receive_ready"; +static std::string grokUncompressedBuf = "Global\\grok_uncompressed_buf"; +static std::string grokCompressedBuf = "Global\\grok_compressed_buf"; +static const std::string GRK_MSGR_BATCH_IMAGE = "GRK_MSGR_BATCH_IMAGE"; +static const std::string GRK_MSGR_BATCH_COMPRESS_INIT = "GRK_MSGR_BATCH_COMPRESS_INIT"; +static const std::string GRK_MSGR_BATCH_SUBMIT_UNCOMPRESSED = "GRK_MSGR_BATCH_SUBMIT_UNCOMPRESSED"; +static const std::string GRK_MSGR_BATCH_PROCESSED_UNCOMPRESSED = + "GRK_MSGR_BATCH_PROCESSED_UNCOMPRESSED"; +static const std::string GRK_MSGR_BATCH_SUBMIT_COMPRESSED = "GRK_MSGR_BATCH_SUBMIT_COMPRESSED"; +static const std::string GRK_MSGR_BATCH_PROCESSSED_COMPRESSED = + "GRK_MSGR_BATCH_PROCESSSED_COMPRESSED"; +static const std::string GRK_MSGR_BATCH_SHUTDOWN = "GRK_MSGR_BATCH_SHUTDOWN"; +static const std::string GRK_MSGR_BATCH_FLUSH = "GRK_MSGR_BATCH_FLUSH"; +static const size_t messageBufferLen = 256; +struct IMessengerLogger +{ + virtual ~IMessengerLogger(void) = default; + virtual void info(const char* fmt, ...) = 0; + virtual void warn(const char* fmt, ...) = 0; + virtual void error(const char* fmt, ...) = 0; + + protected: + template + std::string log_message(char const* const format, Args&... args) noexcept + { + constexpr size_t message_size = 512; + char message[message_size]; + + std::snprintf(message, message_size, format, args...); + return std::string(message); + } +}; +struct MessengerLogger : public IMessengerLogger +{ + explicit MessengerLogger(const std::string &preamble) : preamble_(preamble) {} + virtual ~MessengerLogger() = default; + virtual void info(const char* fmt, ...) override + { + va_list args; + std::string new_fmt = preamble_ + fmt + "\n"; + va_start(args, fmt); + vfprintf(stdout, new_fmt.c_str(), args); + va_end(args); + } + virtual void warn(const char* fmt, ...) override + { + va_list args; + std::string new_fmt = preamble_ + fmt + "\n"; + va_start(args, fmt); + vfprintf(stdout, new_fmt.c_str(), args); + va_end(args); + } + virtual void error(const char* fmt, ...) override + { + va_list args; + std::string new_fmt = preamble_ + fmt + "\n"; + va_start(args, fmt); + vfprintf(stderr, new_fmt.c_str(), args); + va_end(args); + } + + protected: + 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; +} +struct MessengerInit +{ + MessengerInit(const std::string &outBuf, const std::string &outSent, + const std::string &outReceiveReady, const std::string &inBuf, + const std::string &inSent, + const std::string &inReceiveReady, + std::function processor, + size_t numProcessingThreads) + : outboundMessageBuf(outBuf), outboundSentSynch(outSent), + outboundReceiveReadySynch(outReceiveReady), inboundMessageBuf(inBuf), + inboundSentSynch(inSent), inboundReceiveReadySynch(inReceiveReady), processor_(processor), + numProcessingThreads_(numProcessingThreads), + uncompressedFrameSize_(0), compressedFrameSize_(0), + numFrames_(0) + { + if(firstLaunch(true)) + unlink(); + } + void unlink(void) + { +#ifndef _WIN32 + shm_unlink(grokToClientMessageBuf.c_str()); + shm_unlink(clientToGrokMessageBuf.c_str()); +#endif + } + static bool firstLaunch(bool isClient) + { + bool debugGrok = false; + return debugGrok != isClient; + } + std::string outboundMessageBuf; + std::string outboundSentSynch; + std::string outboundReceiveReadySynch; + + std::string inboundMessageBuf; + std::string inboundSentSynch; + std::string inboundReceiveReadySynch; + + std::function processor_; + size_t numProcessingThreads_; + + size_t uncompressedFrameSize_; + size_t compressedFrameSize_; + size_t numFrames_; +}; + +/*************************** Synchronization *******************************/ +enum SynchDirection +{ + SYNCH_SENT, + SYNCH_RECEIVE_READY +}; + +typedef int grk_handle; +struct Synch +{ + Synch(const std::string &sentSemName, const std::string &receiveReadySemName) + : sentSemName_(sentSemName), receiveReadySemName_(receiveReadySemName) + { + // unlink semaphores in case of previous crash + if(MessengerInit::firstLaunch(true)) + unlink(); + open(); + } + ~Synch() + { + close(); + if(MessengerInit::firstLaunch(true)) + unlink(); + } + void post(SynchDirection dir) + { + auto sem = (dir == SYNCH_SENT ? sentSem_ : receiveReadySem_); + int rc = sem_post(sem); + if(rc) + getMessengerLogger()->error("Error posting to semaphore: %s", strerror(errno)); + } + void wait(SynchDirection dir) + { + auto sem = dir == SYNCH_SENT ? sentSem_ : receiveReadySem_; + int rc = sem_wait(sem); + if(rc) + getMessengerLogger()->error("Error waiting for semaphore: %s", strerror(errno)); + } + void open(void) + { + sentSem_ = sem_open(sentSemName_.c_str(), O_CREAT, 0666, 0); + if(!sentSem_) + getMessengerLogger()->error("Error opening shared memory: %s", strerror(errno)); + receiveReadySem_ = sem_open(receiveReadySemName_.c_str(), O_CREAT, 0666, 1); + if(!receiveReadySem_) + getMessengerLogger()->error("Error opening shared memory: %s", strerror(errno)); + } + void close(void) + { + int rc = sem_close(sentSem_); + if(rc) + getMessengerLogger()->error("Error closing semaphore %s: %s", sentSemName_.c_str(), + strerror(errno)); + rc = sem_close(receiveReadySem_); + if(rc) + getMessengerLogger()->error("Error closing semaphore %s: %s", + receiveReadySemName_.c_str(), strerror(errno)); + } + void unlink(void) + { + int rc = sem_unlink(sentSemName_.c_str()); + if(rc == -1 && errno != ENOENT) + getMessengerLogger()->error("Error unlinking semaphore %s: %s", sentSemName_.c_str(), + strerror(errno)); + rc = sem_unlink(receiveReadySemName_.c_str()); + if(rc == -1 && errno != ENOENT) + getMessengerLogger()->error("Error unlinking semaphore %s: %s", + receiveReadySemName_.c_str(), strerror(errno)); + } + sem_t* sentSem_; + sem_t* receiveReadySem_; + + private: + std::string sentSemName_; + std::string receiveReadySemName_; +}; +struct SharedMemoryManager +{ + static bool initShm(const std::string &name, size_t len, grk_handle* shm_fd, char** buffer) + { + *shm_fd = shm_open(name.c_str(), O_CREAT | O_RDWR, 0666); + if(*shm_fd < 0) + { + getMessengerLogger()->error("Error opening shared memory: %s", strerror(errno)); + return false; + } + int rc = ftruncate(*shm_fd, sizeof(char) * len); + if(rc) + { + getMessengerLogger()->error("Error truncating shared memory: %s", strerror(errno)); + rc = close(*shm_fd); + if(rc) + getMessengerLogger()->error("Error closing shared memory: %s", strerror(errno)); + rc = shm_unlink(name.c_str()); + if(rc) + getMessengerLogger()->error("Error unlinking shared memory: %s", strerror(errno)); + return false; + } + *buffer = static_cast(mmap(0, len, PROT_WRITE, MAP_SHARED, *shm_fd, 0)); + if(!*buffer) + { + getMessengerLogger()->error("Error mapping shared memory: %s", strerror(errno)); + rc = close(*shm_fd); + if(rc) + getMessengerLogger()->error("Error closing shared memory: %s", strerror(errno)); + rc = shm_unlink(name.c_str()); + if(rc) + getMessengerLogger()->error("Error unlinking shared memory: %s", strerror(errno)); + } + + return *buffer != nullptr; + } + static bool deinitShm(const std::string &name, size_t len, grk_handle &shm_fd, char** buffer) + { + if (!*buffer || !shm_fd) + return true; + + int rc = munmap(*buffer, len); + *buffer = nullptr; + if(rc) + getMessengerLogger()->error("Error unmapping shared memory %s: %s", name.c_str(), strerror(errno)); + rc = close(shm_fd); + shm_fd = 0; + if(rc) + getMessengerLogger()->error("Error closing shared memory %s: %s", name.c_str(), strerror(errno)); + rc = shm_unlink(name.c_str()); + if(rc) + fprintf(stderr,"Error unlinking shared memory %s : %s\n", name.c_str(), strerror(errno)); + + return true; + } +}; + +template +class MessengerBlockingQueue +{ + public: + explicit MessengerBlockingQueue(size_t max) : active_(true), max_size_(max) {} + MessengerBlockingQueue() : MessengerBlockingQueue(UINT_MAX) {} + size_t size() const + { + return queue_.size(); + } + // deactivate and clear queue + void deactivate() + { + { + std::lock_guard lk(mutex_); + active_ = false; + while(!queue_.empty()) + queue_.pop(); + } + + // release all waiting threads + can_pop_.notify_all(); + can_push_.notify_all(); + } + void activate() + { + std::lock_guard lk(mutex_); + active_ = true; + } + bool push(Data const& value) + { + bool rc; + { + std::unique_lock lk(mutex_); + rc = push_(value); + } + if(rc) + can_pop_.notify_one(); + + return rc; + } + bool waitAndPush(Data& value) + { + bool rc; + { + std::unique_lock lk(mutex_); + if(!active_) + return false; + // in case of spurious wakeup, loop until predicate in lambda + // is satisfied. + can_push_.wait(lk, [this] { return queue_.size() < max_size_ || !active_; }); + rc = push_(value); + } + if(rc) + can_pop_.notify_one(); + + return rc; + } + bool pop(Data& value) + { + bool rc; + { + std::unique_lock lk(mutex_); + rc = pop_(value); + } + if(rc) + can_push_.notify_one(); + + return rc; + } + bool waitAndPop(Data& value) + { + bool rc; + { + std::unique_lock lk(mutex_); + if(!active_) + return false; + // in case of spurious wakeup, loop until predicate in lambda + // is satisfied. + can_pop_.wait(lk, [this] { return !queue_.empty() || !active_; }); + rc = pop_(value); + } + if(rc) + can_push_.notify_one(); + + return rc; + } + + private: + bool push_(Data const& value) + { + if(queue_.size() == max_size_ || !active_) + return false; + queue_.push(value); + + return true; + } + bool pop_(Data& value) + { + if(queue_.empty() || !active_) + return false; + value = queue_.front(); + queue_.pop(); + + return true; + } + std::queue queue_; + mutable std::mutex mutex_; + std::condition_variable can_pop_; + std::condition_variable can_push_; + bool active_; + size_t max_size_; +}; +struct BufferSrc +{ + BufferSrc(void) : BufferSrc("") {} + explicit BufferSrc(const std::string &file) : file_(file), clientFrameId_(0), frameId_(0), framePtr_(nullptr) + {} + BufferSrc(size_t clientFrameId, size_t frameId, uint8_t* framePtr) + : file_(""), clientFrameId_(clientFrameId), frameId_(frameId), framePtr_(framePtr) + {} + bool fromDisk(void) + { + return !file_.empty() && framePtr_ == nullptr; + } + size_t index() const + { + return clientFrameId_; + } + std::string file_; + size_t clientFrameId_; + size_t frameId_; + uint8_t* framePtr_; +}; + +struct Messenger; +static void outboundThread(Messenger* messenger, const std::string &sendBuf, Synch* synch); +static void inboundThread(Messenger* messenger, const std::string &receiveBuf, Synch* synch); +static void processorThread(Messenger* messenger, std::function processor); + +struct Messenger +{ + explicit Messenger(MessengerInit init) + : running(true), initialized_(false), shutdown_(false), init_(init), + outboundSynch_(nullptr), + inboundSynch_(nullptr), uncompressed_buffer_(nullptr), compressed_buffer_(nullptr), + uncompressed_fd_(0), compressed_fd_(0) + {} + virtual ~Messenger(void) + { + running = false; + sendQueue.deactivate(); + receiveQueue.deactivate(); + + if (outboundSynch_) { + outboundSynch_->post(SYNCH_RECEIVE_READY); + outbound.join(); + } + + if (inboundSynch_) { + inboundSynch_->post(SYNCH_SENT); + inbound.join(); + } + + for(auto& p : processors_) + p.join(); + + delete outboundSynch_; + delete inboundSynch_; + + deinitShm(); + } + void startThreads(void) { + outboundSynch_ = + new Synch(init_.outboundSentSynch, init_.outboundReceiveReadySynch); + outbound = std::thread(outboundThread, this, init_.outboundMessageBuf, outboundSynch_); + + inboundSynch_ = + new Synch(init_.inboundSentSynch, init_.inboundReceiveReadySynch); + inbound = std::thread(inboundThread, this, init_.inboundMessageBuf, inboundSynch_); + + for(size_t i = 0; i < init_.numProcessingThreads_; ++i) + processors_.push_back(std::thread(processorThread, this, init_.processor_)); + } + size_t serialize(const std::string &dir, size_t clientFrameId, uint8_t* compressedPtr, + size_t compressedLength) + { + char fname[512]; + if(!compressedPtr || !compressedLength) + return 0; + sprintf(fname, "%s/test_%d.j2k", dir.c_str(), (int)clientFrameId); + auto fp = fopen(fname, "wb"); + if(!fp) + return 0; + size_t written = fwrite(compressedPtr, 1, compressedLength, fp); + if(written != compressedLength) + { + fclose(fp); + return 0; + } + fflush(fp); + fclose(fp); + + return written; + } + bool initBuffers(void) + { + bool rc = true; + if(init_.uncompressedFrameSize_) + { + rc = rc && SharedMemoryManager::initShm(grokUncompressedBuf, + init_.uncompressedFrameSize_ * init_.numFrames_, + &uncompressed_fd_, &uncompressed_buffer_); + } + if(init_.compressedFrameSize_) + { + rc = rc && SharedMemoryManager::initShm(grokCompressedBuf, + init_.compressedFrameSize_ * init_.numFrames_, + &compressed_fd_, &compressed_buffer_); + } + + return rc; + } + + bool deinitShm(void) + { + bool rc = SharedMemoryManager::deinitShm(grokUncompressedBuf, + init_.uncompressedFrameSize_ * init_.numFrames_, + uncompressed_fd_, &uncompressed_buffer_); + rc = rc && SharedMemoryManager::deinitShm(grokCompressedBuf, + init_.compressedFrameSize_ * init_.numFrames_, + compressed_fd_, &compressed_buffer_); + + return rc; + } + template + void send(const std::string& str, Args... args) + { + std::ostringstream oss; + oss << str; + int dummy[] = {0, ((void)(oss << ',' << args), 0)...}; + static_cast(dummy); + + sendQueue.push(oss.str()); + } + static pid_t get_pid_by_process_name(const char* name) + { + char command[256]; + snprintf(command, sizeof(command), "pgrep %s", name); + auto pgrep = popen(command, "r"); + if(!pgrep) + return -1; + pid_t pid; + if(fscanf(pgrep, "%d", &pid) != 1) + pid = -1; + pclose(pgrep); + + return pid; + } + static bool terminate_process(const char* name) + { + auto pid = get_pid_by_process_name(name); + + return (pid != -1 && kill(pid, SIGTERM) != -1); + } + static bool kill_process(const char* name) + { + auto pid = get_pid_by_process_name(name); + + return (pid != -1 && kill(pid, SIGKILL) != -1); + } + void launchGrok(const std::string &dir, uint32_t width, uint32_t stride, + uint32_t height, uint32_t samplesPerPixel, uint32_t depth, + int device, bool is4K, uint32_t fps, uint32_t bandwidth, + const std::string server, uint32_t port, + const std::string license) + { + + std::unique_lock lk(shutdownMutex_); + if (async_result_.valid()) + return; + if(MessengerInit::firstLaunch(true)) + init_.unlink(); + startThreads(); + char _cmd[4096]; + auto fullServer = server + ":" + std::to_string(port); + sprintf(_cmd, + "./grk_compress -batch_src %s,%d,%d,%d,%d,%d -out_fmt j2k -out_dir - -k 1 " + "-G %d -%s %d,%d -j %s -J %s", + 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); + } + void initClient(size_t uncompressedFrameSize, size_t compressedFrameSize, size_t numFrames) + { + // client fills queue with pending uncompressed buffers + init_.uncompressedFrameSize_ = uncompressedFrameSize; + init_.compressedFrameSize_ = compressedFrameSize; + init_.numFrames_ = numFrames; + initBuffers(); + auto ptr = uncompressed_buffer_; + for(size_t i = 0; i < init_.numFrames_; ++i) + { + availableBuffers_.push(BufferSrc(0, i, (uint8_t*)ptr)); + ptr += init_.uncompressedFrameSize_; + } + + std::unique_lock lk(shutdownMutex_); + initialized_ = true; + clientInitializedCondition_.notify_all(); + } + bool waitForClientInit(void) + { + if(initialized_) + return true; + + std::unique_lock lk(shutdownMutex_); + if(initialized_) + return true; + else if (shutdown_) + return false; + clientInitializedCondition_.wait(lk, [this]{return initialized_ || shutdown_;}); + + return initialized_ && !shutdown_; + } + static size_t uncompressedFrameSize(uint32_t w, uint32_t h, uint32_t samplesPerPixel) + { + return sizeof(uint16_t) * w * h * samplesPerPixel; + } + void reclaimCompressed(size_t frameId) + { + availableBuffers_.push(BufferSrc(0, frameId, getCompressedFrame(frameId))); + } + void reclaimUncompressed(size_t frameId) + { + availableBuffers_.push(BufferSrc(0, frameId, getUncompressedFrame(frameId))); + } + uint8_t* getUncompressedFrame(size_t frameId) + { + assert(frameId < init_.numFrames_); + if(frameId >= init_.numFrames_) + return nullptr; + + return (uint8_t*)(uncompressed_buffer_ + frameId * init_.uncompressedFrameSize_); + } + uint8_t* getCompressedFrame(size_t frameId) + { + assert(frameId < init_.numFrames_); + if(frameId >= init_.numFrames_) + return nullptr; + + return (uint8_t*)(compressed_buffer_ + frameId * init_.compressedFrameSize_); + } + std::atomic_bool running; + bool initialized_; + bool shutdown_; + MessengerBlockingQueue sendQueue; + MessengerBlockingQueue receiveQueue; + MessengerBlockingQueue availableBuffers_; + MessengerInit init_; + std::string cmd_; + std::future async_result_; + std::mutex shutdownMutex_; + std::condition_variable shutdownCondition_; + + protected: + std::condition_variable clientInitializedCondition_; + private: + void launch(const std::string &cmd, const std::string &dir) + { + // Change the working directory + if(!dir.empty()) + { + if(chdir(dir.c_str()) != 0) + { + getMessengerLogger()->error("Error: failed to change the working directory"); + return; + } + } + // Execute the command using std::async and std::system + cmd_ = cmd; + async_result_ = std::async(std::launch::async, [this]() { return std::system(cmd_.c_str()); }); + } + std::thread outbound; + Synch* outboundSynch_; + + std::thread inbound; + Synch* inboundSynch_; + + std::vector processors_; + char* uncompressed_buffer_; + char* compressed_buffer_; + + grk_handle uncompressed_fd_; + grk_handle compressed_fd_; +}; + +static void outboundThread(Messenger* messenger, const std::string &sendBuf, Synch* synch) +{ + grk_handle shm_fd = 0; + char* send_buffer = nullptr; + + if(!SharedMemoryManager::initShm(sendBuf, messageBufferLen, &shm_fd, &send_buffer)) + return; + while(messenger->running) + { + synch->wait(SYNCH_RECEIVE_READY); + if(!messenger->running) + break; + std::string message; + if(!messenger->sendQueue.waitAndPop(message)) + break; + if(!messenger->running) + break; + memcpy(send_buffer, message.c_str(), message.size() + 1); + synch->post(SYNCH_SENT); + } + SharedMemoryManager::deinitShm(sendBuf, messageBufferLen, shm_fd, &send_buffer); +} + +static void inboundThread(Messenger* messenger, const std::string &receiveBuf, Synch* synch) +{ + grk_handle shm_fd = 0; + char* receive_buffer = nullptr; + + if(!SharedMemoryManager::initShm(receiveBuf, messageBufferLen, &shm_fd, &receive_buffer)) + return; + while(messenger->running) + { + synch->wait(SYNCH_SENT); + if(!messenger->running) + break; + auto message = std::string(receive_buffer); + synch->post(SYNCH_RECEIVE_READY); + messenger->receiveQueue.push(message); + } + SharedMemoryManager::deinitShm(receiveBuf, messageBufferLen, shm_fd, &receive_buffer); +} +struct Msg +{ + explicit Msg(const std::string &msg) : ct_(0) + { + std::stringstream ss(msg); + while(ss.good()) + { + std::string substr; + std::getline(ss, substr, ','); + cs_.push_back(substr); + } + } + std::string next() + { + if(ct_ == cs_.size()) + { + getMessengerLogger()->error("Msg: comma separated list exhausted. returning empty."); + return ""; + } + return cs_[ct_++]; + } + + uint32_t nextUint(void) + { + return (uint32_t)std::stoi(next()); + } + + std::vector cs_; + size_t ct_; +}; +static void processorThread(Messenger* messenger, std::function processor) +{ + while(messenger->running) + { + std::string message; + if(!messenger->receiveQueue.waitAndPop(message)) + break; + if(!messenger->running) + break; + Msg msg(message); + auto tag = msg.next(); + if(tag == GRK_MSGR_BATCH_COMPRESS_INIT) + { + auto width = msg.nextUint(); + auto stride = msg.nextUint(); + (void)stride; + auto height = msg.nextUint(); + auto samplesPerPixel = msg.nextUint(); + auto depth = msg.nextUint(); + (void)depth; + messenger->init_.uncompressedFrameSize_ = + Messenger::uncompressedFrameSize(width, height, samplesPerPixel); + auto compressedFrameSize = msg.nextUint(); + auto numFrames = msg.nextUint(); + messenger->initClient(compressedFrameSize, compressedFrameSize, numFrames); + } + else if(tag == GRK_MSGR_BATCH_PROCESSED_UNCOMPRESSED) + { + messenger->reclaimUncompressed(msg.nextUint()); + } + else if(tag == GRK_MSGR_BATCH_PROCESSSED_COMPRESSED) + { + messenger->reclaimCompressed(msg.nextUint()); + } + processor(message); + } +} + +template +struct ScheduledFrames +{ + void store(F& val) + { + std::unique_lock lk(mapMutex_); + auto it = map_.find(val.index()); + if (it == map_.end()) + map_[val.index()] = val; + } + F retrieve(size_t index, bool &success) + { + std::unique_lock lk(mapMutex_); + success = false; + auto it = map_.find(index); + if(it == map_.end()) + return F(); + + success = true; + F val = it->second; + map_.erase(index); + + return val; + } + + private: + std::mutex mapMutex_; + std::map map_; +}; + +template +struct ScheduledMessenger : public Messenger +{ + explicit ScheduledMessenger(MessengerInit init) : Messenger(init), + framesScheduled_(0), + framesCompressed_(0) + {} + ~ScheduledMessenger(void) { + shutdown(); + } + bool scheduleCompress(F proxy, std::function converter){ + size_t frameSize = init_.uncompressedFrameSize_; + assert(frameSize >= init_.uncompressedFrameSize_); + BufferSrc src; + if(!availableBuffers_.waitAndPop(src)) + return false; + converter(src); + scheduledFrames_.store(proxy); + framesScheduled_++; + send(GRK_MSGR_BATCH_SUBMIT_UNCOMPRESSED, proxy.index(), src.frameId_); + + return true; + } + void processCompressed(const std::string &message, std::function processor, bool needsRecompression) { + Msg msg(message); + msg.next(); + auto clientFrameId = msg.nextUint(); + auto compressedFrameId = msg.nextUint(); + auto compressedFrameLength = msg.nextUint(); + if (!needsRecompression) { + bool success = false; + auto srcFrame = scheduledFrames_.retrieve(clientFrameId,success); + if (!success) + return; + processor(srcFrame, getCompressedFrame(compressedFrameId),compressedFrameLength); + } + ++framesCompressed_; + send(GRK_MSGR_BATCH_PROCESSSED_COMPRESSED, compressedFrameId); + if (shutdown_ && framesCompressed_ == framesScheduled_) + shutdownCondition_.notify_all(); + } + void shutdown(void){ + try { + std::unique_lock lk(shutdownMutex_); + if (!async_result_.valid()) + return; + shutdown_ = true; + if (framesScheduled_) { + uint32_t scheduled = framesScheduled_; + send(GRK_MSGR_BATCH_FLUSH, scheduled); + shutdownCondition_.wait(lk, [this] { return framesScheduled_ == framesCompressed_; }); + } + availableBuffers_.deactivate(); + send(GRK_MSGR_BATCH_SHUTDOWN); + int result = async_result_.get(); + if(result != 0) + getMessengerLogger()->error("Accelerator failed with return code: %d\n",result); + } catch (std::exception &ex) { + getMessengerLogger()->error("%s",ex.what()); + } + + } + F retrieve(size_t index, bool &success) { + return scheduledFrames_.retrieve(index, success); + } + void store(F& val) { + scheduledFrames_.store(val); + } + +private: + ScheduledFrames scheduledFrames_; + std::atomic framesScheduled_; + std::atomic framesCompressed_; +}; + +} // namespace grk_plugin -- cgit v1.2.3 From a651a17dd5e242d09111bee87e5e4864420dcdcd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 8 Jul 2023 01:13:04 +0200 Subject: Remove default constructor from DCPVideo. --- src/lib/dcp_video.h | 1 - src/lib/grok/context.h | 16 +++++++--------- src/lib/grok/messenger.h | 26 +++++++++++++------------- 3 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/dcp_video.h b/src/lib/dcp_video.h index b351fda1e..5f43dabb8 100644 --- a/src/lib/dcp_video.h +++ b/src/lib/dcp_video.h @@ -49,7 +49,6 @@ class PlayerVideo; class DCPVideo { public: - DCPVideo() : DCPVideo(nullptr, 0, 0, 0, Resolution::TWO_K) {} DCPVideo (std::shared_ptr, int index, int dcp_fps, int bandwidth, Resolution r); DCPVideo (std::shared_ptr, cxml::ConstNodePtr); diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 7a447d35a..cb913f58d 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -68,8 +68,6 @@ struct GrokInitializer { }; struct FrameProxy { - FrameProxy(void) : FrameProxy(0,Eyes::LEFT,DCPVideo()) - {} FrameProxy(int index, Eyes eyes, DCPVideo dcpv) : index_(index), eyes_(eyes), vf(dcpv) {} int index() const { @@ -157,13 +155,13 @@ public: bool needsRecompression = compressedFrameLength < minimum_size; messenger_->processCompressed(str, processor, needsRecompression); if (needsRecompression) { - bool success = false; - auto fp = messenger_->retrieve(clientFrameId, success); - if (!success) + auto fp = messenger_->retrieve(clientFrameId); + if (!fp) { return; + } - auto encoded = std::make_shared(fp.vf.encode_locally()); - dcpomaticContext_.writer_.write(encoded, fp.vf.index(), fp.vf.eyes()); + auto encoded = std::make_shared(fp->vf.encode_locally()); + dcpomaticContext_.writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); frame_done (); } } @@ -210,11 +208,11 @@ public: return launched_; } - bool scheduleCompress(const DCPVideo &vf){ + bool scheduleCompress(DCPVideo const& vf){ if (!messenger_) return false; - auto fp = FrameProxy(vf.index(),vf.eyes(),vf); + auto fp = FrameProxy(vf.index(), vf.eyes(), vf); auto cvt = [this, &fp](BufferSrc src){ // xyz conversion fp.vf.convert_to_xyz((uint16_t*)src.framePtr_); diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 45ee752e5..86a50d530 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -825,22 +825,20 @@ static void processorThread(Messenger* messenger, std::function struct ScheduledFrames { - void store(F& val) + void store(F const& val) { std::unique_lock lk(mapMutex_); auto it = map_.find(val.index()); if (it == map_.end()) - map_[val.index()] = val; + map_.emplace(std::make_pair(val.index(), val)); } - F retrieve(size_t index, bool &success) + boost::optional retrieve(size_t index) { std::unique_lock lk(mapMutex_); - success = false; auto it = map_.find(index); if(it == map_.end()) - return F(); + return {}; - success = true; F val = it->second; map_.erase(index); @@ -862,7 +860,7 @@ struct ScheduledMessenger : public Messenger ~ScheduledMessenger(void) { shutdown(); } - bool scheduleCompress(F proxy, std::function converter){ + bool scheduleCompress(F const& proxy, std::function converter){ size_t frameSize = init_.uncompressedFrameSize_; assert(frameSize >= init_.uncompressedFrameSize_); BufferSrc src; @@ -882,11 +880,11 @@ struct ScheduledMessenger : public Messenger auto compressedFrameId = msg.nextUint(); auto compressedFrameLength = msg.nextUint(); if (!needsRecompression) { - bool success = false; - auto srcFrame = scheduledFrames_.retrieve(clientFrameId,success); - if (!success) + auto src_frame = scheduledFrames_.retrieve(clientFrameId); + if (!src_frame) { return; - processor(srcFrame, getCompressedFrame(compressedFrameId),compressedFrameLength); + } + processor(*src_frame, getCompressedFrame(compressedFrameId),compressedFrameLength); } ++framesCompressed_; send(GRK_MSGR_BATCH_PROCESSSED_COMPRESSED, compressedFrameId); @@ -914,9 +912,11 @@ struct ScheduledMessenger : public Messenger } } - F retrieve(size_t index, bool &success) { - return scheduledFrames_.retrieve(index, success); + + boost::optional retrieve(size_t index) { + return scheduledFrames_.retrieve(index); } + void store(F& val) { scheduledFrames_.store(val); } -- cgit v1.2.3 From 1ee5e03a53149d9e3db032de39943b83c4bfa45c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 9 Jul 2023 23:25:36 +0200 Subject: Tidy up some includes / forward declarations. --- src/lib/grok/context.h | 1 + src/lib/j2k_encoder.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index cb913f58d..da2fd78de 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -22,6 +22,7 @@ #include "../config.h" #include "../dcp_video.h" +#include "../film.h" #include "../log.h" #include "../dcpomatic_log.h" #include "../writer.h" diff --git a/src/lib/j2k_encoder.h b/src/lib/j2k_encoder.h index 433a0498f..840602dbb 100644 --- a/src/lib/j2k_encoder.h +++ b/src/lib/j2k_encoder.h @@ -27,10 +27,9 @@ * @brief J2KEncoder class. */ -#include "grok/context.h" +#include "grok/context.h" #include "cross.h" -#include "dcp_video.h" #include "enum_indexed_vector.h" #include "event_history.h" #include "exception_store.h" @@ -43,6 +42,8 @@ #include #include + +class DCPVideo; class EncodeServerDescription; class Film; class Job; -- cgit v1.2.3 From 30cefe57adea0653cc85f6e04346355ec8ca739a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 4 Sep 2023 00:58:19 +0200 Subject: Further patch from Aaron. --- src/lib/grok/messenger.h | 58 ++++++------------------------------------------ 1 file changed, 7 insertions(+), 51 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 86a50d530..008e58dd2 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -276,7 +276,8 @@ struct SharedMemoryManager if(rc) getMessengerLogger()->error("Error closing shared memory: %s", strerror(errno)); rc = shm_unlink(name.c_str()); - if(rc) + // 2 == No such file or directory + if(rc && errno != 2) getMessengerLogger()->error("Error unlinking shared memory: %s", strerror(errno)); return false; } @@ -288,7 +289,8 @@ struct SharedMemoryManager if(rc) getMessengerLogger()->error("Error closing shared memory: %s", strerror(errno)); rc = shm_unlink(name.c_str()); - if(rc) + // 2 == No such file or directory + if(rc && errno != 2) getMessengerLogger()->error("Error unlinking shared memory: %s", strerror(errno)); } @@ -308,7 +310,8 @@ struct SharedMemoryManager if(rc) getMessengerLogger()->error("Error closing shared memory %s: %s", name.c_str(), strerror(errno)); rc = shm_unlink(name.c_str()); - if(rc) + // 2 == No such file or directory + if(rc && errno != 2) fprintf(stderr,"Error unlinking shared memory %s : %s\n", name.c_str(), strerror(errno)); return true; @@ -499,27 +502,6 @@ struct Messenger for(size_t i = 0; i < init_.numProcessingThreads_; ++i) processors_.push_back(std::thread(processorThread, this, init_.processor_)); } - size_t serialize(const std::string &dir, size_t clientFrameId, uint8_t* compressedPtr, - size_t compressedLength) - { - char fname[512]; - if(!compressedPtr || !compressedLength) - return 0; - sprintf(fname, "%s/test_%d.j2k", dir.c_str(), (int)clientFrameId); - auto fp = fopen(fname, "wb"); - if(!fp) - return 0; - size_t written = fwrite(compressedPtr, 1, compressedLength, fp); - if(written != compressedLength) - { - fclose(fp); - return 0; - } - fflush(fp); - fclose(fp); - - return written; - } bool initBuffers(void) { bool rc = true; @@ -560,32 +542,6 @@ struct Messenger sendQueue.push(oss.str()); } - static pid_t get_pid_by_process_name(const char* name) - { - char command[256]; - snprintf(command, sizeof(command), "pgrep %s", name); - auto pgrep = popen(command, "r"); - if(!pgrep) - return -1; - pid_t pid; - if(fscanf(pgrep, "%d", &pid) != 1) - pid = -1; - pclose(pgrep); - - return pid; - } - static bool terminate_process(const char* name) - { - auto pid = get_pid_by_process_name(name); - - return (pid != -1 && kill(pid, SIGTERM) != -1); - } - static bool kill_process(const char* name) - { - auto pid = get_pid_by_process_name(name); - - return (pid != -1 && kill(pid, SIGKILL) != -1); - } void launchGrok(const std::string &dir, uint32_t width, uint32_t stride, uint32_t height, uint32_t samplesPerPixel, uint32_t depth, int device, bool is4K, uint32_t fps, uint32_t bandwidth, @@ -602,7 +558,7 @@ struct Messenger char _cmd[4096]; auto fullServer = server + ":" + std::to_string(port); sprintf(_cmd, - "./grk_compress -batch_src %s,%d,%d,%d,%d,%d -out_fmt j2k -out_dir - -k 1 " + "./grk_compress -batch_src %s,%d,%d,%d,%d,%d -out_fmt j2k -k 1 " "-G %d -%s %d,%d -j %s -J %s", GRK_MSGR_BATCH_IMAGE.c_str(), width, stride, height, samplesPerPixel, depth, device, is4K ? "cinema4K" : "cinema2K", fps, bandwidth, -- cgit v1.2.3 From 0053d931a1293d4f663489f874a54fbcfbd5783b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Sep 2023 12:01:54 +0200 Subject: Remove unnecessary using statements. --- src/lib/grok/context.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index da2fd78de..8e03c1d54 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -29,8 +29,6 @@ #include "messenger.h" class Film; -using dcp::Data; -using namespace dcpomatic; static std::mutex launchMutex; -- cgit v1.2.3 From 5b4ff8ad597ab9b4ca5d5ee3190dce76c9451566 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Sep 2023 12:02:19 +0200 Subject: Explicitly set up Grok logger rather than relying on a static variable. --- src/lib/grok/context.h | 7 ------- src/lib/j2k_encoder.cc | 2 -- src/tools/dcpomatic.cc | 3 +++ src/tools/dcpomatic_batch.cc | 3 +++ src/tools/dcpomatic_server.cc | 3 +++ src/tools/dcpomatic_server_cli.cc | 3 +++ 6 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 8e03c1d54..2513f8863 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -59,13 +59,6 @@ struct GrokLogger : public MessengerLogger { } }; -struct GrokInitializer { - GrokInitializer(void) { - setMessengerLogger(new GrokLogger("[GROK] ")); - } - ~GrokInitializer() = default; -}; - struct FrameProxy { FrameProxy(int index, Eyes eyes, DCPVideo dcpv) : index_(index), eyes_(eyes), vf(dcpv) {} diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 7a01bfc4c..a3cab7c1c 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -58,8 +58,6 @@ using dcp::Data; using namespace dcpomatic; -static grk_plugin::GrokInitializer grokInitializer; - /** @param film Film that we are encoding. * @param writer Writer that we are using. */ diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 8f34b6836..af864ad09 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -75,6 +75,7 @@ #include "lib/ffmpeg_encoder.h" #include "lib/film.h" #include "lib/font_config.h" +#include "lib/grok/context.h" #include "lib/hints.h" #include "lib/job_manager.h" #include "lib/kdm_with_metadata.h" @@ -1712,6 +1713,8 @@ private: notes.Centre(); notes.ShowModal(); } + + grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); } catch (exception& e) { diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc index 16da43410..bf0ea5237 100644 --- a/src/tools/dcpomatic_batch.cc +++ b/src/tools/dcpomatic_batch.cc @@ -31,6 +31,7 @@ #include "lib/config.h" #include "lib/dcpomatic_socket.h" #include "lib/film.h" +#include "lib/grok/context.h" #include "lib/job.h" #include "lib/job_manager.h" #include "lib/make_dcp.h" @@ -496,6 +497,8 @@ class App : public wxApp } } + grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); + return true; } diff --git a/src/tools/dcpomatic_server.cc b/src/tools/dcpomatic_server.cc index e5e3a7e5a..528af8858 100644 --- a/src/tools/dcpomatic_server.cc +++ b/src/tools/dcpomatic_server.cc @@ -25,6 +25,7 @@ #include "lib/encoded_log_entry.h" #include "lib/encode_server.h" #include "lib/config.h" +#include "lib/grok/context.h" #include "lib/log.h" #include "lib/signaller.h" #include "lib/cross.h" @@ -326,6 +327,8 @@ private: SetExitOnFrameDelete (false); + grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); + return true; } diff --git a/src/tools/dcpomatic_server_cli.cc b/src/tools/dcpomatic_server_cli.cc index 6d7f6aba7..30f119a5e 100644 --- a/src/tools/dcpomatic_server_cli.cc +++ b/src/tools/dcpomatic_server_cli.cc @@ -25,6 +25,7 @@ #include "lib/config.h" #include "lib/image.h" #include "lib/file_log.h" +#include "lib/grok/context.h" #include "lib/null_log.h" #include "lib/version.h" #include "lib/encode_server.h" @@ -109,6 +110,8 @@ main (int argc, char* argv[]) dcpomatic_log.reset (new FileLog("dcpomatic_server_cli.log")); } + setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); + EncodeServer server (verbose, num_threads); try { -- cgit v1.2.3 From d8f3f1426cdd5903fae3ef9fc118068f40310316 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Sep 2023 17:04:21 +0200 Subject: Cleanup: remove unnecessary forward declaration. --- src/lib/grok/context.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 2513f8863..640ec2196 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -28,7 +28,6 @@ #include "../writer.h" #include "messenger.h" -class Film; static std::mutex launchMutex; -- cgit v1.2.3 From 9b3b2b5014c08ba5667ef4072b90e93a542b35d0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Sep 2023 17:04:34 +0200 Subject: Cleanup: use dcp::ArrayData instead of home-grown version. --- src/lib/grok/context.h | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 640ec2196..72e62c4fa 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -27,6 +27,7 @@ #include "../dcpomatic_log.h" #include "../writer.h" #include "messenger.h" +#include static std::mutex launchMutex; @@ -98,24 +99,6 @@ public: messenger_(nullptr), launched_(false) { - struct CompressedData : public dcp::Data { - explicit CompressedData(int dataLen) : data_(new uint8_t[dataLen]), dataLen_(dataLen) - {} - ~CompressedData(void){ - delete[] data_; - } - uint8_t const * data () const override { - return data_; - } - uint8_t * data () override { - return data_; - } - int size () const override { - return dataLen_; - } - uint8_t *data_; - int dataLen_; - }; if (Config::instance()->enable_gpu ()) { boost::filesystem::path folder(dcpomaticContext_.location_); boost::filesystem::path binaryPath = folder / "grk_compress"; @@ -137,9 +120,8 @@ public: auto processor = [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) { - auto compressedData = std::make_shared(compressedFrameLength); - memcpy(compressedData->data_,compressed,compressedFrameLength ); - dcpomaticContext_.writer_.write(compressedData, srcFrame.index(), srcFrame.eyes()); + auto compressed_data = std::make_shared(compressed, compressedFrameLength); + dcpomaticContext_.writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); frame_done (); }; int const minimum_size = 16384; -- cgit v1.2.3 From 9ba80f8c08dbfbf1b4eafa8fcb40001a55bbbf0e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Sep 2023 17:23:57 +0200 Subject: Use boost::filesystem::path for gpu_binary_location(). --- src/lib/config.cc | 2 +- src/lib/config.h | 13 +++++++--- src/lib/grok/context.h | 55 ++++++++++++++++++++++++++---------------- src/lib/grok/messenger.h | 28 +++++++++++++++------ src/wx/grok/gpu_config_panel.h | 12 ++++----- 5 files changed, 71 insertions(+), 39 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/config.cc b/src/lib/config.cc index bbb3eef27..a4ee4ad99 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -1133,7 +1133,7 @@ Config::write_config () const /* [XML] ISDCFNamePartLength Maximum length of the "name" part of an ISDCF name, which should be 14 according to the standard */ root->add_child("ISDCFNamePartLength")->add_child_text(raw_convert(_isdcf_name_part_length)); - root->add_child("GpuBinaryLocation")->add_child_text (_gpu_binary_location); + root->add_child("GpuBinaryLocation")->add_child_text (_gpu_binary_location.string()); root->add_child("EnableGpu")->add_child_text ((_enable_gpu ? "1" : "0")); root->add_child("SelectedGpu")->add_child_text (raw_convert (_selected_gpu)); root->add_child("GpuLicenseServer")->add_child_text (_gpu_license_server); diff --git a/src/lib/config.h b/src/lib/config.h index 0c9affbb6..9aba9e9d2 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -618,7 +618,7 @@ public: return _allow_smpte_bv20; } - std::string gpu_binary_location () const { + boost::filesystem::path gpu_binary_location() const { return _gpu_binary_location; } @@ -1220,24 +1220,31 @@ public: void set_allow_smpte_bv20(bool allow) { maybe_set(_allow_smpte_bv20, allow, ALLOW_SMPTE_BV20); } - void set_gpu_binary_location (std::string location) { + + void set_gpu_binary_location(boost::filesystem::path location) { maybe_set (_gpu_binary_location, location); } + void set_enable_gpu (bool enable) { maybe_set (_enable_gpu, enable); } + void set_selected_gpu (int selected) { maybe_set (_selected_gpu, selected); } + void set_gpu_license_server (std::string s) { maybe_set (_gpu_license_server, s); } + void set_gpu_license_port (int p) { maybe_set (_gpu_license_port, p); } + void set_gpu_license (std::string p) { maybe_set (_gpu_license, p); } + void set_isdcf_name_part_length(int length) { maybe_set(_isdcf_name_part_length, length, ISDCF_NAME_PART_LENGTH); } @@ -1485,7 +1492,7 @@ private: /* GPU */ bool _enable_gpu; - std::string _gpu_binary_location; + boost::filesystem::path _gpu_binary_location; int _selected_gpu; std::string _gpu_license_server; int _gpu_license_port; diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 72e62c4fa..3e4144d07 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -74,12 +74,22 @@ struct FrameProxy { }; struct DcpomaticContext { - DcpomaticContext(std::shared_ptr film, Writer& writer, - EventHistory &history, const std::string &location) : - film_(film), writer_(writer), - history_(history), location_(location), - width_(0), height_(0) - {} + DcpomaticContext( + std::shared_ptr film, + Writer& writer, + EventHistory& history, + boost::filesystem::path const& location + ) + : film_(film) + , writer_(writer) + , history_(history) + , _location(location) + , width_(0) + , height_(0) + { + + } + void setDimensions(uint32_t w, uint32_t h) { width_ = w; height_ = h; @@ -87,7 +97,7 @@ struct DcpomaticContext { std::shared_ptr film_; Writer& writer_; EventHistory &history_; - std::string location_; + boost::filesystem::path _location; uint32_t width_; uint32_t height_; }; @@ -100,12 +110,13 @@ public: launched_(false) { if (Config::instance()->enable_gpu ()) { - boost::filesystem::path folder(dcpomaticContext_.location_); + boost::filesystem::path folder(dcpomaticContext_._location); boost::filesystem::path binaryPath = folder / "grk_compress"; if (!boost::filesystem::exists(binaryPath)) { - getMessengerLogger()->error("Invalid binary location %s", - dcpomaticContext_.location_.c_str()); - return; + getMessengerLogger()->error( + "Invalid binary location %s", dcpomaticContext_._location.c_str() + ); + return; } auto proc = [this](const std::string& str) { try { @@ -166,16 +177,18 @@ public: auto s = dcpv.get_size(); dcpomaticContext_.setDimensions(s.width, s.height); auto config = Config::instance(); - messenger_->launchGrok(dcpomaticContext_.location_, - dcpomaticContext_.width_,dcpomaticContext_.width_, - dcpomaticContext_.height_, - 3, 12, device, - dcpomaticContext_.film_->resolution() == Resolution::FOUR_K, - dcpomaticContext_.film_->video_frame_rate(), - dcpomaticContext_.film_->j2k_bandwidth(), - config->gpu_license_server(), - config->gpu_license_port(), - config->gpu_license()); + messenger_->launchGrok( + dcpomaticContext_._location, + dcpomaticContext_.width_,dcpomaticContext_.width_, + dcpomaticContext_.height_, + 3, 12, device, + dcpomaticContext_.film_->resolution() == Resolution::FOUR_K, + dcpomaticContext_.film_->video_frame_rate(), + dcpomaticContext_.film_->j2k_bandwidth(), + config->gpu_license_server(), + config->gpu_license_port(), + config->gpu_license() + ); } launched_ = messenger_->waitForClientInit(); diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 008e58dd2..5cb21a1cd 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -542,11 +542,22 @@ struct Messenger sendQueue.push(oss.str()); } - void launchGrok(const std::string &dir, uint32_t width, uint32_t stride, - uint32_t height, uint32_t samplesPerPixel, uint32_t depth, - int device, bool is4K, uint32_t fps, uint32_t bandwidth, - const std::string server, uint32_t port, - const std::string license) + + void launchGrok( + boost::filesystem::path const& dir, + uint32_t width, + uint32_t stride, + uint32_t height, + uint32_t samplesPerPixel, + uint32_t depth, + int device, + bool is4K, + uint32_t fps, + uint32_t bandwidth, + const std::string server, + uint32_t port, + const std::string license + ) { std::unique_lock lk(shutdownMutex_); @@ -640,13 +651,14 @@ struct Messenger protected: std::condition_variable clientInitializedCondition_; private: - void launch(const std::string &cmd, const std::string &dir) + void launch(std::string const& cmd, boost::filesystem::path const& dir) { // Change the working directory if(!dir.empty()) { - if(chdir(dir.c_str()) != 0) - { + boost::system::error_code ec; + boost::filesystem::current_path(dir, ec); + if (ec) { getMessengerLogger()->error("Error: failed to change the working directory"); return; } diff --git a/src/wx/grok/gpu_config_panel.h b/src/wx/grok/gpu_config_panel.h index 88163ae0c..a0f2a1f7f 100644 --- a/src/wx/grok/gpu_config_panel.h +++ b/src/wx/grok/gpu_config_panel.h @@ -21,15 +21,15 @@ #pragma once -static std::vector get_gpu_names(std::string binary, std::string filename) +static std::vector get_gpu_names(boost::filesystem::path binary, boost::filesystem::path filename) { // Execute the GPU listing program and redirect its output to a file - if (std::system((binary + " > " + filename).c_str()) < 0) { + if (std::system((binary.string() + " > " + filename.string()).c_str()) < 0) { return {}; } std::vector gpu_names; - std::ifstream file(filename); + std::ifstream file(filename.c_str()); if (file.is_open()) { std::string line; @@ -57,8 +57,8 @@ public: } void update(void) { auto cfg = Config::instance(); - auto lister_binary = cfg->gpu_binary_location() + "/" + "gpu_lister"; - auto lister_file = cfg->gpu_binary_location () + "/" + "gpus.txt"; + auto lister_binary = cfg->gpu_binary_location() / "gpu_lister"; + auto lister_file = cfg->gpu_binary_location () / "gpus.txt"; if (boost::filesystem::exists(lister_binary)) { auto gpu_names = get_gpu_names(lister_binary, lister_file); @@ -160,7 +160,7 @@ private: auto config = Config::instance (); checked_set (_enable_gpu, config->enable_gpu()); - _binary_location->SetPath(config->gpu_binary_location ()); + _binary_location->SetPath(std_to_wx(config->gpu_binary_location().string())); _gpu_list_control->update(); _gpu_list_control->setSelection(config->selected_gpu()); checked_set (_server, config->gpu_license_server()); -- cgit v1.2.3 From 6937ba070d10e07c5a0c31bf75edd1d2b9d15307 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Sep 2023 13:11:36 +0200 Subject: Cleanup: reformat and rename dcpomaticContext_ -> _dcpomatic_context --- src/lib/grok/context.h | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 3e4144d07..1aac6f177 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -102,19 +102,21 @@ struct DcpomaticContext { uint32_t height_; }; -class GrokContext { + +class GrokContext +{ public: - explicit GrokContext(const DcpomaticContext &dcpomaticContext) : - dcpomaticContext_(dcpomaticContext), - messenger_(nullptr), - launched_(false) + explicit GrokContext(DcpomaticContext const& dcpomatic_context) + : _dcpomatic_context(dcpomatic_context) + , messenger_(nullptr) + , launched_(false) { if (Config::instance()->enable_gpu ()) { - boost::filesystem::path folder(dcpomaticContext_._location); + boost::filesystem::path folder(_dcpomatic_context._location); boost::filesystem::path binaryPath = folder / "grk_compress"; if (!boost::filesystem::exists(binaryPath)) { getMessengerLogger()->error( - "Invalid binary location %s", dcpomaticContext_._location.c_str() + "Invalid binary location %s", _dcpomatic_context._location.c_str() ); return; } @@ -132,7 +134,7 @@ public: [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) { auto compressed_data = std::make_shared(compressed, compressedFrameLength); - dcpomaticContext_.writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); + _dcpomatic_context.writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); frame_done (); }; int const minimum_size = 16384; @@ -145,7 +147,7 @@ public: } auto encoded = std::make_shared(fp->vf.encode_locally()); - dcpomaticContext_.writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); + _dcpomatic_context.writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); frame_done (); } } @@ -175,16 +177,16 @@ public: return true; if (MessengerInit::firstLaunch(true)) { auto s = dcpv.get_size(); - dcpomaticContext_.setDimensions(s.width, s.height); + _dcpomatic_context.setDimensions(s.width, s.height); auto config = Config::instance(); messenger_->launchGrok( - dcpomaticContext_._location, - dcpomaticContext_.width_,dcpomaticContext_.width_, - dcpomaticContext_.height_, + _dcpomatic_context._location, + _dcpomatic_context.width_,_dcpomatic_context.width_, + _dcpomatic_context.height_, 3, 12, device, - dcpomaticContext_.film_->resolution() == Resolution::FOUR_K, - dcpomaticContext_.film_->video_frame_rate(), - dcpomaticContext_.film_->j2k_bandwidth(), + _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() @@ -218,10 +220,10 @@ public: messenger_ = nullptr; } void frame_done () { - dcpomaticContext_.history_.event (); + _dcpomatic_context.history_.event(); } private: - DcpomaticContext dcpomaticContext_; + DcpomaticContext _dcpomatic_context; ScheduledMessenger *messenger_; bool launched_; }; -- cgit v1.2.3 From 0cab88e322be99b58317b74d2b10def745e8d183 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Sep 2023 13:29:59 +0200 Subject: Create a single DcpomaticContext for all GrokContexts, rather than copying them. I think this makes sense, and also allows us to forward-declare the contexts in a forthcoming commit. --- src/lib/grok/context.h | 28 ++++++++++++++-------------- src/lib/j2k_encoder.cc | 3 ++- src/lib/j2k_encoder.h | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 1aac6f177..96477d597 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -106,17 +106,17 @@ struct DcpomaticContext { class GrokContext { public: - explicit GrokContext(DcpomaticContext const& dcpomatic_context) + explicit GrokContext(DcpomaticContext* dcpomatic_context) : _dcpomatic_context(dcpomatic_context) , messenger_(nullptr) , launched_(false) { if (Config::instance()->enable_gpu ()) { - boost::filesystem::path folder(_dcpomatic_context._location); + boost::filesystem::path folder(_dcpomatic_context->_location); boost::filesystem::path binaryPath = folder / "grk_compress"; if (!boost::filesystem::exists(binaryPath)) { getMessengerLogger()->error( - "Invalid binary location %s", _dcpomatic_context._location.c_str() + "Invalid binary location %s", _dcpomatic_context->_location.c_str() ); return; } @@ -134,7 +134,7 @@ public: [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) { auto compressed_data = std::make_shared(compressed, compressedFrameLength); - _dcpomatic_context.writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); + _dcpomatic_context->writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); frame_done (); }; int const minimum_size = 16384; @@ -147,7 +147,7 @@ public: } auto encoded = std::make_shared(fp->vf.encode_locally()); - _dcpomatic_context.writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); + _dcpomatic_context->writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); frame_done (); } } @@ -177,16 +177,16 @@ public: return true; if (MessengerInit::firstLaunch(true)) { auto s = dcpv.get_size(); - _dcpomatic_context.setDimensions(s.width, s.height); + _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_, + _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(), + _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() @@ -220,10 +220,10 @@ public: messenger_ = nullptr; } void frame_done () { - _dcpomatic_context.history_.event(); + _dcpomatic_context->history_.event(); } private: - DcpomaticContext _dcpomatic_context; + DcpomaticContext* _dcpomatic_context; ScheduledMessenger *messenger_; bool launched_; }; diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 22f2ea6d7..fe63deacd 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -68,7 +68,7 @@ J2KEncoder::J2KEncoder(shared_ptr film, Writer& writer) , _history (200) , _writer (writer) #ifdef DCPOMATIC_GROK - , _dcpomatic_context(film, writer, _history, Config::instance()->gpu_binary_location()) + , _dcpomatic_context(new grk_plugin::DcpomaticContext(film, writer, _history, Config::instance()->gpu_binary_location())) , _context(Config::instance()->enable_gpu() ? new grk_plugin::GrokContext(_dcpomatic_context) : nullptr) #endif { @@ -84,6 +84,7 @@ J2KEncoder::~J2KEncoder () #ifdef DCPOMATIC_GROK delete _context; + delete _dcpomatic_context; #endif } diff --git a/src/lib/j2k_encoder.h b/src/lib/j2k_encoder.h index 9d9d85894..913beb5a9 100644 --- a/src/lib/j2k_encoder.h +++ b/src/lib/j2k_encoder.h @@ -125,7 +125,7 @@ private: boost::signals2::scoped_connection _server_found_connection; #ifdef DCPOMATIC_GROK - grk_plugin::DcpomaticContext _dcpomatic_context; + grk_plugin::DcpomaticContext* _dcpomatic_context; grk_plugin::GrokContext *_context; #endif -- cgit v1.2.3 From e7d983c4a39b53cc6feae13701400904916eea94 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Sep 2023 20:53:43 +0200 Subject: Cleanup: coding style. --- src/lib/grok/messenger.h | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 5cb21a1cd..50d44e251 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -461,7 +461,7 @@ static void processorThread(Messenger* messenger, std::function lk(shutdownMutex_); - initialized_ = true; + _initialized = true; clientInitializedCondition_.notify_all(); } - bool waitForClientInit(void) + + bool waitForClientInit() { - if(initialized_) + if (_initialized) { return true; + } 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_;}); + } + + clientInitializedCondition_.wait(lk, [this] { return _initialized || _shutdown; }); - return initialized_ && !shutdown_; + return _initialized && !_shutdown; } + static size_t uncompressedFrameSize(uint32_t w, uint32_t h, uint32_t samplesPerPixel) { return sizeof(uint16_t) * w * h * samplesPerPixel; @@ -637,8 +643,8 @@ struct Messenger return (uint8_t*)(compressed_buffer_ + frameId * init_.compressedFrameSize_); } std::atomic_bool running; - bool initialized_; - bool shutdown_; + bool _initialized; + bool _shutdown; MessengerBlockingQueue sendQueue; MessengerBlockingQueue receiveQueue; MessengerBlockingQueue availableBuffers_; @@ -754,11 +760,11 @@ struct Msg }; static void processorThread(Messenger* messenger, std::function processor) { - while(messenger->running) - { + while (messenger->running) { std::string message; - if(!messenger->receiveQueue.waitAndPop(message)) + if (!messenger->receiveQueue.waitAndPop(message)) { break; + } if(!messenger->running) break; Msg msg(message); @@ -856,7 +862,7 @@ struct ScheduledMessenger : public Messenger } ++framesCompressed_; send(GRK_MSGR_BATCH_PROCESSSED_COMPRESSED, compressedFrameId); - if (shutdown_ && framesCompressed_ == framesScheduled_) + if (_shutdown && framesCompressed_ == framesScheduled_) shutdownCondition_.notify_all(); } void shutdown(void){ @@ -864,7 +870,7 @@ struct ScheduledMessenger : public Messenger std::unique_lock lk(shutdownMutex_); if (!async_result_.valid()) return; - shutdown_ = true; + _shutdown = true; if (framesScheduled_) { uint32_t scheduled = framesScheduled_; send(GRK_MSGR_BATCH_FLUSH, scheduled); -- cgit v1.2.3 From a89d5d001f2ef44b86780a1dd074ac7458a4d284 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Sep 2023 20:59:39 +0200 Subject: Cleanup: coding style. --- src/lib/grok/messenger.h | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 50d44e251..bb7ada213 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -758,6 +758,7 @@ struct Msg std::vector cs_; size_t ct_; }; + static void processorThread(Messenger* messenger, std::function processor) { while (messenger->running) { @@ -765,31 +766,26 @@ static void processorThread(Messenger* messenger, std::functionreceiveQueue.waitAndPop(message)) { break; } - if(!messenger->running) + + if (!messenger->running) { break; + } + Msg msg(message); auto tag = msg.next(); - if(tag == GRK_MSGR_BATCH_COMPRESS_INIT) - { + if (tag == GRK_MSGR_BATCH_COMPRESS_INIT) { auto width = msg.nextUint(); - auto stride = msg.nextUint(); - (void)stride; + msg.nextUint(); // stride auto height = msg.nextUint(); - auto samplesPerPixel = msg.nextUint(); - auto depth = msg.nextUint(); - (void)depth; - messenger->init_.uncompressedFrameSize_ = - Messenger::uncompressedFrameSize(width, height, samplesPerPixel); - auto compressedFrameSize = msg.nextUint(); - auto numFrames = msg.nextUint(); - messenger->initClient(compressedFrameSize, compressedFrameSize, numFrames); - } - else if(tag == GRK_MSGR_BATCH_PROCESSED_UNCOMPRESSED) - { + auto samples_per_pixel = msg.nextUint(); + msg.nextUint(); // depth + messenger->init_.uncompressedFrameSize_ = Messenger::uncompressedFrameSize(width, height, samples_per_pixel); + auto compressed_frame_size = msg.nextUint(); + auto num_frames = msg.nextUint(); + messenger->initClient(compressed_frame_size, compressed_frame_size, num_frames); + } else if (tag == GRK_MSGR_BATCH_PROCESSED_UNCOMPRESSED) { messenger->reclaimUncompressed(msg.nextUint()); - } - else if(tag == GRK_MSGR_BATCH_PROCESSSED_COMPRESSED) - { + } else if (tag == GRK_MSGR_BATCH_PROCESSSED_COMPRESSED) { messenger->reclaimCompressed(msg.nextUint()); } processor(message); -- cgit v1.2.3 From ec1758d615a0f6ca837e960e1d2c0492a546523d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Oct 2023 19:11:45 +0200 Subject: 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(-) (limited to 'src/lib/grok') 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. -- cgit v1.2.3 From 7dd4fb0e9c8024c4ccd67e2aa5cda8eaccc52477 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Oct 2023 19:47:32 +0200 Subject: Don't pollute the global namespace with a namespace called fs. --- src/lib/grok/context.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index e7b5dbcbc..85ed385bd 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -21,7 +21,6 @@ #pragma once #include -namespace fs = boost::filesystem; #include "../config.h" #include "../dcp_video.h" @@ -170,6 +169,8 @@ public: shutdown(); } bool launch(DCPVideo dcpv, int device){ + namespace fs = boost::filesystem; + if (!messenger_ ) return false; if (launched_) -- cgit v1.2.3 From 252f378dda893da1e1a7d94beceeed141c0c7d0b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Oct 2023 19:51:45 +0200 Subject: Cleanup: include ordering. --- src/lib/grok/context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 85ed385bd..6b27eb7a8 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -20,7 +20,6 @@ #pragma once -#include #include "../config.h" #include "../dcp_video.h" @@ -30,6 +29,7 @@ #include "../writer.h" #include "messenger.h" #include +#include static std::mutex launchMutex; -- cgit v1.2.3 From 3d897c8d329a96c3c7af2ad7e8d8973d732fc0c4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Oct 2023 19:51:54 +0200 Subject: Cleanup: whitespace to reduce the diff. --- src/lib/grok/context.h | 13 +++++++------ src/lib/grok/messenger.h | 11 +++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index 6b27eb7a8..ecb9d1f98 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -108,11 +108,11 @@ struct DcpomaticContext { class GrokContext { public: - explicit GrokContext(DcpomaticContext* dcpomatic_context) : - _dcpomatic_context(dcpomatic_context), - messenger_(nullptr), - launched_(false), - launchFailed_(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); @@ -193,7 +193,8 @@ public: auto s = dcpv.get_size(); _dcpomatic_context->setDimensions(s.width, s.height); auto config = Config::instance(); - if (!messenger_->launchGrok(_dcpomatic_context->_location, + if (!messenger_->launchGrok( + _dcpomatic_context->_location, _dcpomatic_context->width_,_dcpomatic_context->width_, _dcpomatic_context->height_, 3, 12, device, diff --git a/src/lib/grok/messenger.h b/src/lib/grok/messenger.h index 51526aee3..eb2fe9560 100644 --- a/src/lib/grok/messenger.h +++ b/src/lib/grok/messenger.h @@ -585,16 +585,19 @@ struct Messenger bool waitForClientInit() { - if(_initialized) + if (_initialized) { return true; - else if (_shutdown) + } else if (_shutdown) { return false; + } std::unique_lock lk(shutdownMutex_); - if(_initialized) + + if (_initialized) { return true; - else if (_shutdown) + } else if (_shutdown) { return false; + } while (true) { if (clientInitializedCondition_.wait_for(lk, std::chrono::seconds(1), [this]{ return _initialized || _shutdown; })) { -- cgit v1.2.3 From 8c68fd3d1b861ac6d5fd5451cd693f2230969cad Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 6 Oct 2023 21:27:39 +0200 Subject: Cleanup: whitespace / coding style. --- src/lib/grok/context.h | 262 ++++++++++++++++++++++++----------------- src/wx/grok/gpu_config_panel.h | 186 +++++++++++++++-------------- 2 files changed, 246 insertions(+), 202 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index ecb9d1f98..d27caa5f6 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -75,33 +75,34 @@ struct FrameProxy { DCPVideo vf; }; -struct DcpomaticContext { +struct DcpomaticContext +{ DcpomaticContext( - std::shared_ptr film, - Writer& writer, - EventHistory& history, - boost::filesystem::path const& location + std::shared_ptr film_, + Writer& writer_, + EventHistory& history_, + boost::filesystem::path const& location_ ) - : film_(film) - , writer_(writer) - , history_(history) - , _location(location) - , width_(0) - , height_(0) + : film(film_) + , writer(writer_) + , history(history_) + , location(location_) { } - void setDimensions(uint32_t w, uint32_t h) { - width_ = w; - height_ = h; + void set_dimensions(uint32_t w, uint32_t h) + { + width = w; + height = h; } - std::shared_ptr film_; - Writer& writer_; - EventHistory &history_; - boost::filesystem::path _location; - uint32_t width_; - uint32_t height_; + + std::shared_ptr film; + Writer& writer; + EventHistory& history; + boost::filesystem::path location; + uint32_t width = 0; + uint32_t height = 0; }; @@ -110,140 +111,179 @@ class GrokContext public: 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); - boost::filesystem::path binaryPath = folder / "grk_compress"; - if (!boost::filesystem::exists(binaryPath)) { - getMessengerLogger()->error( - "Invalid binary location %s", _dcpomatic_context->_location.c_str() - ); - return; - } - auto proc = [this](const std::string& str) { - try { - Msg msg(str); - auto tag = msg.next(); - if(tag == GRK_MSGR_BATCH_SUBMIT_COMPRESSED) - { - auto clientFrameId = msg.nextUint(); - auto compressedFrameId = msg.nextUint(); - (void)compressedFrameId; - auto compressedFrameLength = msg.nextUint(); - auto processor = - [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) - { - auto compressed_data = std::make_shared(compressed, compressedFrameLength); - _dcpomatic_context->writer_.write(compressed_data, srcFrame.index(), srcFrame.eyes()); - frame_done (); - }; - int const minimum_size = 16384; - bool needsRecompression = compressedFrameLength < minimum_size; - messenger_->processCompressed(str, processor, needsRecompression); - if (needsRecompression) { - auto fp = messenger_->retrieve(clientFrameId); - if (!fp) { - return; - } - - auto encoded = std::make_shared(fp->vf.encode_locally()); - _dcpomatic_context->writer_.write(encoded, fp->vf.index(), fp->vf.eyes()); - frame_done (); + if (!Config::instance()->enable_gpu()) { + return; + } + + boost::filesystem::path folder(_dcpomatic_context->location); + boost::filesystem::path binary_path = folder / "grk_compress"; + if (!boost::filesystem::exists(binary_path)) { + getMessengerLogger()->error( + "Invalid binary location %s", _dcpomatic_context->location.c_str() + ); + return; + } + + auto proc = [this](const std::string& str) { + try { + Msg msg(str); + auto tag = msg.next(); + if (tag == GRK_MSGR_BATCH_SUBMIT_COMPRESSED) { + auto clientFrameId = msg.nextUint(); + msg.nextUint(); // compressed frame ID + auto compressedFrameLength = msg.nextUint(); + auto processor = [this](FrameProxy srcFrame, uint8_t* compressed, uint32_t compressedFrameLength) { + auto compressed_data = std::make_shared(compressed, compressedFrameLength); + _dcpomatic_context->writer.write(compressed_data, srcFrame.index(), srcFrame.eyes()); + frame_done (); + }; + + int const minimum_size = 16384; + + bool needsRecompression = compressedFrameLength < minimum_size; + _messenger->processCompressed(str, processor, needsRecompression); + + if (needsRecompression) { + auto fp = _messenger->retrieve(clientFrameId); + if (!fp) { + return; } + + auto encoded = std::make_shared(fp->vf.encode_locally()); + _dcpomatic_context->writer.write(encoded, fp->vf.index(), fp->vf.eyes()); + frame_done (); } - } catch (std::exception &ex){ - getMessengerLogger()->error("%s",ex.what()); } - }; - auto clientInit = - MessengerInit(clientToGrokMessageBuf, clientSentSynch, grokReceiveReadySynch, - grokToClientMessageBuf, grokSentSynch, clientReceiveReadySynch, proc, - std::thread::hardware_concurrency()); - messenger_ = new ScheduledMessenger(clientInit); - } + } catch (std::exception& ex) { + getMessengerLogger()->error("%s",ex.what()); + } + }; + + auto clientInit = MessengerInit( + clientToGrokMessageBuf, + clientSentSynch, + grokReceiveReadySynch, + grokToClientMessageBuf, + grokSentSynch, + clientReceiveReadySynch, + proc, + std::thread::hardware_concurrency() + ); + + _messenger = new ScheduledMessenger(clientInit); } - ~GrokContext(void) { + + ~GrokContext() + { shutdown(); } - bool launch(DCPVideo dcpv, int device){ + + bool launch(DCPVideo dcpv, int device) + { namespace fs = boost::filesystem; - if (!messenger_ ) + if (!_messenger) { return false; - if (launched_) + } + if (_launched) { return true; - if (launchFailed_) + } + if (_launch_failed) { return false; + } + std::unique_lock lk_global(launchMutex); - if (!messenger_) + + if (!_messenger) { return false; - if (launched_) + } + if (_launched) { return true; - if (launchFailed_) + } + if (_launch_failed) { 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()); + 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); + _dcpomatic_context->set_dimensions(s.width, s.height); auto config = Config::instance(); - 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(), + 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; + _launch_failed = true; return false; } } - launched_ = messenger_->waitForClientInit(); - launchFailed_ = launched_; - return launched_; + _launched = _messenger->waitForClientInit(); + _launch_failed = _launched; + + return _launched; } - bool scheduleCompress(DCPVideo const& vf){ - if (!messenger_) + + bool scheduleCompress(DCPVideo const& vf) + { + if (!_messenger) { return false; + } auto fp = FrameProxy(vf.index(), vf.eyes(), vf); - auto cvt = [this, &fp](BufferSrc src){ - // xyz conversion + auto cvt = [this, &fp](BufferSrc src) { fp.vf.convert_to_xyz((uint16_t*)src.framePtr_); }; - return messenger_->scheduleCompress(fp, cvt); + + return _messenger->scheduleCompress(fp, cvt); } - void shutdown(void){ - if (!messenger_) + + void shutdown() + { + if (!_messenger) { return; + } std::unique_lock lk_global(launchMutex); - if (!messenger_) + + if (!_messenger) { return; - if (launched_) - messenger_->shutdown(); - delete messenger_; - messenger_ = nullptr; + } + + if (_launched) { + _messenger->shutdown(); + } + + delete _messenger; + _messenger = nullptr; } - void frame_done () { - _dcpomatic_context->history_.event(); + + void frame_done() + { + _dcpomatic_context->history.event(); } + private: DcpomaticContext* _dcpomatic_context; - ScheduledMessenger *messenger_; - bool launched_; - bool launchFailed_; + ScheduledMessenger* _messenger = nullptr; + bool _launched = false; + bool _launch_failed = false; }; } diff --git a/src/wx/grok/gpu_config_panel.h b/src/wx/grok/gpu_config_panel.h index a0f2a1f7f..40e999181 100644 --- a/src/wx/grok/gpu_config_panel.h +++ b/src/wx/grok/gpu_config_panel.h @@ -41,111 +41,121 @@ static std::vector get_gpu_names(boost::filesystem::path binary, bo return gpu_names; } + class GpuList : public wxPanel { public: - GpuList(wxPanel* parent) : wxPanel(parent, wxID_ANY), selection(0) { - comboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(400, -1)); - comboBox->Bind(wxEVT_COMBOBOX, &GpuList::OnComboBox, this); - update(); - - wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + GpuList(wxPanel* parent) + : wxPanel(parent, wxID_ANY) + { + _combo_box = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(400, -1)); + _combo_box->Bind(wxEVT_COMBOBOX, &GpuList::OnComboBox, this); + update(); - sizer->Add(comboBox, 0, wxALIGN_CENTER_VERTICAL); // Vertically center the comboBox + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(_combo_box, 0, wxALIGN_CENTER_VERTICAL); + SetSizerAndFit(sizer); + } - this->SetSizerAndFit(sizer); - } - void update(void) { - auto cfg = Config::instance(); - auto lister_binary = cfg->gpu_binary_location() / "gpu_lister"; - auto lister_file = cfg->gpu_binary_location () / "gpus.txt"; - if (boost::filesystem::exists(lister_binary)) { + void update() + { + auto cfg = Config::instance(); + auto lister_binary = cfg->gpu_binary_location() / "gpu_lister"; + auto lister_file = cfg->gpu_binary_location () / "gpus.txt"; + if (boost::filesystem::exists(lister_binary)) { auto gpu_names = get_gpu_names(lister_binary, lister_file); - comboBox->Clear(); - for (const auto& name : gpu_names) - comboBox->Append(name); - } - } + _combo_box->Clear(); + for (auto const& name: gpu_names) { + _combo_box->Append(name); + } + } + } - int getSelection(void) { - return selection; - } - void setSelection(int sel) { - if ((int)comboBox->GetCount() > sel) - comboBox->SetSelection(sel); - } + void set_selection(int sel) + { + if (sel < static_cast(_combo_box->GetCount())) { + _combo_box->SetSelection(sel); + } + } private: - void OnComboBox(wxCommandEvent&) - { - selection = comboBox->GetSelection(); - if (selection != wxNOT_FOUND) - Config::instance ()->set_selected_gpu(selection); - } + void OnComboBox(wxCommandEvent&) + { + auto selection = _combo_box->GetSelection(); + if (selection != wxNOT_FOUND) { + Config::instance()->set_selected_gpu(selection); + } + } - wxComboBox* comboBox; - int selection; + wxComboBox* _combo_box; + int _selection = 0; }; + class GPUPage : public Page { public: - GPUPage (wxSize panel_size, int border) - : Page (panel_size, border), - _enable_gpu(nullptr), _binary_location(nullptr), _gpu_list_control(nullptr) + GPUPage(wxSize panel_size, int border) + : Page(panel_size, border) {} - wxString GetName () const override + wxString GetName() const override { return _("GPU"); } #ifdef DCPOMATIC_OSX - wxBitmap GetLargeIcon () const override + /* XXX: this icon does not exist */ + wxBitmap GetLargeIcon() const override { - return wxBitmap(icon_path("tms"), wxBITMAP_TYPE_PNG); + return wxBitmap(icon_path("gpu"), wxBITMAP_TYPE_PNG); } #endif private: - void setup () override + void setup() override { - auto config = Config::instance (); - _enable_gpu = new CheckBox(_panel, _("Enable GPU acceleration")); - _panel->GetSizer()->Add (_enable_gpu, 0, wxALL | wxEXPAND, _border); + _panel->GetSizer()->Add(_enable_gpu, 0, wxALL | wxEXPAND, _border); - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border); + wxFlexGridSizer* table = new wxFlexGridSizer(2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol(1, 1); + _panel->GetSizer()->Add(table, 1, wxALL | wxEXPAND, _border); add_label_to_sizer(table, _panel, _("Acceleration binary folder"), true, 0, wxLEFT | wxLEFT | wxALIGN_CENTRE_VERTICAL); - _binary_location = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST); - table->Add (_binary_location, 1, wxEXPAND); + _binary_location = new wxDirPickerCtrl(_panel, wxDD_DIR_MUST_EXIST); + table->Add(_binary_location, 1, wxEXPAND); add_label_to_sizer(table, _panel, _("GPU selection"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); _gpu_list_control = new GpuList(_panel); - table->Add (_gpu_list_control, 1, wxEXPAND); + table->Add(_gpu_list_control, 1, wxEXPAND); add_label_to_sizer(table, _panel, _("License server"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); - _server = new wxTextCtrl (_panel, wxID_ANY); - table->Add (_server, 1, wxEXPAND | wxALL); + _server = new wxTextCtrl(_panel, wxID_ANY); + table->Add(_server, 1, wxEXPAND | wxALL); - add_label_to_sizer (table, _panel, _("Port"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); - _port = new wxSpinCtrl (_panel, wxID_ANY); - _port->SetRange (0, 65535); - table->Add (_port); + add_label_to_sizer(table, _panel, _("Port"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); + _port = new wxSpinCtrl(_panel, wxID_ANY); + _port->SetRange(0, 65535); + table->Add(_port); - add_label_to_sizer (table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); - _license = new PasswordEntry (_panel); - table->Add (_license->get_panel(), 1, wxEXPAND | wxALL); + add_label_to_sizer(table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); + _license = new PasswordEntry(_panel); + table->Add(_license->get_panel(), 1, wxEXPAND | wxALL); _enable_gpu->bind(&GPUPage::enable_gpu_changed, this); - _binary_location->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&GPUPage::binary_location_changed, this)); - _server->Bind (wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this)); - _port->Bind (wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this)); - _license->Changed.connect (boost::bind(&GPUPage::license_changed, this)); + _binary_location->Bind(wxEVT_DIRPICKER_CHANGED, boost::bind (&GPUPage::binary_location_changed, this)); + _server->Bind(wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this)); + _port->Bind(wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this)); + _license->Changed.connect(boost::bind(&GPUPage::license_changed, this)); + + setup_sensitivity(); + } + + void setup_sensitivity() + { + auto config = Config::instance(); _binary_location->Enable(config->enable_gpu()); _gpu_list_control->Enable(config->enable_gpu()); @@ -154,57 +164,51 @@ private: _license->get_panel()->Enable(config->enable_gpu()); } - - void config_changed () override + void config_changed() override { - auto config = Config::instance (); + auto config = Config::instance(); - checked_set (_enable_gpu, config->enable_gpu()); + checked_set(_enable_gpu, config->enable_gpu()); _binary_location->SetPath(std_to_wx(config->gpu_binary_location().string())); _gpu_list_control->update(); - _gpu_list_control->setSelection(config->selected_gpu()); - checked_set (_server, config->gpu_license_server()); - checked_set (_port, config->gpu_license_port()); - checked_set (_license, config->gpu_license()); + _gpu_list_control->set_selection(config->selected_gpu()); + checked_set(_server, config->gpu_license_server()); + checked_set(_port, config->gpu_license_port()); + checked_set(_license, config->gpu_license()); } - void enable_gpu_changed () + void enable_gpu_changed() { - auto config = Config::instance (); - - config->set_enable_gpu (_enable_gpu->GetValue()); - _binary_location->Enable(config->enable_gpu()); - _gpu_list_control->Enable(config->enable_gpu()); - _server->Enable(config->enable_gpu()); - _port->Enable(config->enable_gpu()); - _license->get_panel()->Enable(config->enable_gpu()); + auto config = Config::instance(); + config->set_enable_gpu(_enable_gpu->GetValue()); + setup_sensitivity(); } - void binary_location_changed () + void binary_location_changed() { - Config::instance()->set_gpu_binary_location (wx_to_std (_binary_location->GetPath ())); + Config::instance()->set_gpu_binary_location(wx_to_std(_binary_location->GetPath())); _gpu_list_control->update(); } - void server_changed () + void server_changed() { Config::instance()->set_gpu_license_server(wx_to_std(_server->GetValue())); } - void port_changed () + void port_changed() { Config::instance()->set_gpu_license_port(_port->GetValue()); } - void license_changed () + void license_changed() { Config::instance()->set_gpu_license(_license->get()); } - CheckBox* _enable_gpu; - wxDirPickerCtrl* _binary_location; - GpuList *_gpu_list_control; - wxTextCtrl* _server; - wxSpinCtrl* _port; - PasswordEntry* _license; + CheckBox* _enable_gpu = nullptr; + wxDirPickerCtrl* _binary_location = nullptr; + GpuList* _gpu_list_control = nullptr; + wxTextCtrl* _server = nullptr; + wxSpinCtrl* _port = nullptr; + PasswordEntry* _license = nullptr; }; -- cgit v1.2.3 From 617b8cd303b4a96621a207724c55bed1d749b10c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 6 Oct 2023 22:42:44 +0200 Subject: Clean up grok's presence in the config file and make sure it's optional. It should be allowed to not have any grok stuff in the config file, and we should generally call it grok rather than GPU in case other non-grok GPU stuff arrives in the future. --- src/lib/config.cc | 66 ++++++++++++++++++++++++---------- src/lib/config.h | 74 +++++++++++++------------------------- src/lib/grok/context.h | 11 +++--- src/lib/grok_j2k_encoder_thread.cc | 4 ++- src/lib/j2k_encoder.cc | 31 ++++++++++------ src/lib/j2k_encoder.h | 4 +-- src/wx/grok/gpu_config_panel.h | 69 ++++++++++++++++++++--------------- 7 files changed, 145 insertions(+), 114 deletions(-) (limited to 'src/lib/grok') diff --git a/src/lib/config.cc b/src/lib/config.cc index 3a7442c39..938be090c 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -212,12 +212,9 @@ Config::set_defaults () set_notification_email_to_default (); set_cover_sheet_to_default (); - _gpu_binary_location = ""; - _enable_gpu = false; - _selected_gpu = 0; - _gpu_license_server = ""; - _gpu_license_port = 5000; - _gpu_license = ""; +#ifdef DCPOMATIC_GROK + _grok = boost::none; +#endif _main_divider_sash_position = {}; _main_content_divider_sash_position = {}; @@ -640,12 +637,11 @@ try _allow_smpte_bv20 = f.optional_bool_child("AllowSMPTEBv20").get_value_or(false); _isdcf_name_part_length = f.optional_number_child("ISDCFNamePartLength").get_value_or(14); - _enable_gpu = f.optional_bool_child("EnableGPU").get_value_or(false); - _gpu_binary_location = f.string_child("GPUBinaryLocation"); - _selected_gpu = f.number_child("SelectedGPU"); - _gpu_license_server = f.string_child ("GPULicenseServer"); - _gpu_license_port = f.number_child ("GPULicensePort"); - _gpu_license = f.string_child("GPULicense"); +#ifdef DCPOMATIC_GROK + if (auto grok = f.optional_node_child("Grok")) { + _grok = Grok(grok); + } +#endif _export.read(f.optional_node_child("Export")); } @@ -1133,12 +1129,11 @@ Config::write_config () const /* [XML] ISDCFNamePartLength Maximum length of the "name" part of an ISDCF name, which should be 14 according to the standard */ root->add_child("ISDCFNamePartLength")->add_child_text(raw_convert(_isdcf_name_part_length)); - root->add_child("GPUBinaryLocation")->add_child_text (_gpu_binary_location.string()); - root->add_child("EnableGPU")->add_child_text ((_enable_gpu ? "1" : "0")); - root->add_child("SelectedGPU")->add_child_text (raw_convert (_selected_gpu)); - root->add_child("GPULicenseServer")->add_child_text (_gpu_license_server); - root->add_child("GPULicensePort")->add_child_text (raw_convert (_gpu_license_port)); - root->add_child("GPULicense")->add_child_text (_gpu_license); +#ifdef DCPOMATIC_GROK + if (_grok) { + _grok->as_xml(root->add_child("Grok")); + } +#endif _export.write(root->add_child("Export")); @@ -1660,3 +1655,38 @@ Config::initial_path(string id) const return iter->second; } + +#ifdef DCPOMATIC_GROK + +Config::Grok::Grok(cxml::ConstNodePtr node) + : enable(node->bool_child("Enable")) + , binary_location(node->string_child("BinaryLocation")) + , selected(node->number_child("Selected")) + , licence_server(node->string_child("LicenceServer")) + , licence_port(node->number_child("LicencePort")) + , licence(node->string_child("Licence")) +{ + +} + + +void +Config::Grok::as_xml(xmlpp::Element* node) const +{ + node->add_child("BinaryLocation")->add_child_text(binary_location.string()); + node->add_child("Enable")->add_child_text((enable ? "1" : "0")); + node->add_child("Selected")->add_child_text(raw_convert(selected)); + node->add_child("LicenceServer")->add_child_text(licence_server); + node->add_child("LicencePort")->add_child_text(raw_convert(licence_port)); + node->add_child("Licence")->add_child_text(licence); +} + + +void +Config::set_grok(Grok const& grok) +{ + _grok = grok; + changed(OTHER); +} + +#endif diff --git a/src/lib/config.h b/src/lib/config.h index 9aba9e9d2..eaf85451d 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -618,27 +618,27 @@ public: return _allow_smpte_bv20; } - boost::filesystem::path gpu_binary_location() const { - return _gpu_binary_location; - } - - bool enable_gpu () const { - return _enable_gpu; - } - - int selected_gpu () const { - return _selected_gpu; - } - std::string gpu_license_server () const { - return _gpu_license_server; - } +#ifdef DCPOMATIC_GROK + class Grok + { + public: + Grok() = default; + Grok(cxml::ConstNodePtr node); + + void as_xml(xmlpp::Element* node) const; + + bool enable = false; + boost::filesystem::path binary_location; + int selected = 0; + std::string licence_server; + int licence_port = 5000; + std::string licence; + }; - int gpu_license_port () const { - return _gpu_license_port; - } - std::string gpu_license () const { - return _gpu_license; + boost::optional grok() const { + return _grok; } +#endif int isdcf_name_part_length() const { return _isdcf_name_part_length; @@ -1221,29 +1221,9 @@ public: maybe_set(_allow_smpte_bv20, allow, ALLOW_SMPTE_BV20); } - void set_gpu_binary_location(boost::filesystem::path location) { - maybe_set (_gpu_binary_location, location); - } - - void set_enable_gpu (bool enable) { - maybe_set (_enable_gpu, enable); - } - - void set_selected_gpu (int selected) { - maybe_set (_selected_gpu, selected); - } - - void set_gpu_license_server (std::string s) { - maybe_set (_gpu_license_server, s); - } - - void set_gpu_license_port (int p) { - maybe_set (_gpu_license_port, p); - } - - void set_gpu_license (std::string p) { - maybe_set (_gpu_license, p); - } +#ifdef DCPOMATIC_GROK + void set_grok(Grok const& grok); +#endif void set_isdcf_name_part_length(int length) { maybe_set(_isdcf_name_part_length, length, ISDCF_NAME_PART_LENGTH); @@ -1490,13 +1470,9 @@ private: bool _allow_smpte_bv20; int _isdcf_name_part_length; - /* GPU */ - bool _enable_gpu; - boost::filesystem::path _gpu_binary_location; - int _selected_gpu; - std::string _gpu_license_server; - int _gpu_license_port; - std::string _gpu_license; +#ifdef DCPOMATIC_GROK + boost::optional _grok; +#endif ExportConfig _export; diff --git a/src/lib/grok/context.h b/src/lib/grok/context.h index d27caa5f6..521faae8d 100644 --- a/src/lib/grok/context.h +++ b/src/lib/grok/context.h @@ -112,7 +112,8 @@ public: explicit GrokContext(DcpomaticContext* dcpomatic_context) : _dcpomatic_context(dcpomatic_context) { - if (!Config::instance()->enable_gpu()) { + auto grok = Config::instance()->grok().get_value_or({}); + if (!grok.enable) { return; } @@ -214,7 +215,7 @@ public: auto s = dcpv.get_size(); _dcpomatic_context->set_dimensions(s.width, s.height); - auto config = Config::instance(); + auto grok = Config::instance()->grok().get_value_or({}); if (!_messenger->launchGrok( _dcpomatic_context->location, _dcpomatic_context->width, @@ -226,9 +227,9 @@ public: _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())) { + grok.licence_server, + grok.licence_port, + grok.licence)) { _launch_failed = true; return false; } diff --git a/src/lib/grok_j2k_encoder_thread.cc b/src/lib/grok_j2k_encoder_thread.cc index 79b80f694..79fb1bbae 100644 --- a/src/lib/grok_j2k_encoder_thread.cc +++ b/src/lib/grok_j2k_encoder_thread.cc @@ -39,7 +39,9 @@ try LOG_TIMING("encoder-pop thread=%1 frame=%2 eyes=%3", thread_id(), frame.index(), static_cast(frame.eyes())); - if (_context->launch(frame, Config::instance()->selected_gpu()) && _context->scheduleCompress(frame)) { + auto grok = Config::instance()->grok().get_value_or({}); + + if (_context->launch(frame, grok.selected) && _context->scheduleCompress(frame)) { frame_guard.cancel(); } } diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 3bb7ccaed..e68402483 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -95,11 +95,14 @@ J2KEncoder::J2KEncoder(shared_ptr film, Writer& writer) : _film (film) , _history (200) , _writer (writer) +{ #ifdef DCPOMATIC_GROK - , _dcpomatic_context(new grk_plugin::DcpomaticContext(film, writer, _history, Config::instance()->gpu_binary_location())) - , _context(Config::instance()->enable_gpu() ? new grk_plugin::GrokContext(_dcpomatic_context) : nullptr) + auto grok = Config::instance()->grok().get_value_or({}); + _dcpomatic_context = new grk_plugin::DcpomaticContext(film, writer, _history, grok.binary_location); + if (grok.enable) { + _context = new grk_plugin::GrokContext(_dcpomatic_context); + } #endif -{ servers_list_changed (); } @@ -121,9 +124,14 @@ void J2KEncoder::servers_list_changed() { auto config = Config::instance(); +#ifdef DCPOMATIC_GROK + auto const grok_enable = config->grok().get_value_or({}).enable; +#else + auto const grok_enable = false; +#endif - auto const cpu = (config->enable_gpu() || config->only_servers_encode()) ? 0 : config->master_encoding_threads(); - auto const gpu = config->enable_gpu() ? config->master_encoding_threads() : 0; + auto const cpu = (grok_enable || config->only_servers_encode()) ? 0 : config->master_encoding_threads(); + auto const gpu = grok_enable ? config->master_encoding_threads() : 0; remake_threads(cpu, gpu, EncodeServerFinder::instance()->servers()); } @@ -141,16 +149,17 @@ J2KEncoder::begin () void J2KEncoder::pause() { - if (!Config::instance()->enable_gpu()) { +#ifdef DCPOMATIC_GROK + if (!Config::instance()->grok().get_value_or({}).enable) { return; } + return; terminate_threads (); /* Something might have been thrown during terminate_threads */ rethrow (); -#ifdef DCPOMATIC_GROK delete _context; _context = nullptr; #endif @@ -159,14 +168,14 @@ J2KEncoder::pause() void J2KEncoder::resume() { - if (!Config::instance()->enable_gpu()) { +#ifdef DCPOMATIC_GROK + if (!Config::instance()->grok().get_value_or({}).enable) { return; } -#ifdef DCPOMATIC_GROK _context = new grk_plugin::GrokContext(_dcpomatic_context); -#endif servers_list_changed(); +#endif } @@ -203,7 +212,7 @@ J2KEncoder::end() */ for (auto & i: _queue) { #ifdef DCPOMATIC_GROK - if (Config::instance()->enable_gpu ()) { + if (Config::instance()->grok().get_value_or({}).enable) { if (!_context->scheduleCompress(i)){ LOG_GENERAL (N_("[%1] J2KEncoder thread pushes frame %2 back onto queue after failure"), thread_id(), i.index()); // handle error diff --git a/src/lib/j2k_encoder.h b/src/lib/j2k_encoder.h index 0dbe654a4..6bfbaea49 100644 --- a/src/lib/j2k_encoder.h +++ b/src/lib/j2k_encoder.h @@ -127,8 +127,8 @@ private: boost::signals2::scoped_connection _server_found_connection; #ifdef DCPOMATIC_GROK - grk_plugin::DcpomaticContext* _dcpomatic_context; - grk_plugin::GrokContext *_context; + grk_plugin::DcpomaticContext* _dcpomatic_context = nullptr; + grk_plugin::GrokContext *_context = nullptr; #endif bool _ending = false; diff --git a/src/wx/grok/gpu_config_panel.h b/src/wx/grok/gpu_config_panel.h index 40e999181..cbf037592 100644 --- a/src/wx/grok/gpu_config_panel.h +++ b/src/wx/grok/gpu_config_panel.h @@ -59,9 +59,9 @@ public: void update() { - auto cfg = Config::instance(); - auto lister_binary = cfg->gpu_binary_location() / "gpu_lister"; - auto lister_file = cfg->gpu_binary_location () / "gpus.txt"; + auto grok = Config::instance()->grok().get_value_or({}); + auto lister_binary = grok.binary_location / "gpu_lister"; + auto lister_file = grok.binary_location / "gpus.txt"; if (boost::filesystem::exists(lister_binary)) { auto gpu_names = get_gpu_names(lister_binary, lister_file); @@ -84,7 +84,9 @@ private: { auto selection = _combo_box->GetSelection(); if (selection != wxNOT_FOUND) { - Config::instance()->set_selected_gpu(selection); + auto grok = Config::instance()->grok().get_value_or({}); + grok.selected = selection; + Config::instance()->set_grok(grok); } } @@ -141,68 +143,79 @@ private: table->Add(_port); add_label_to_sizer(table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); - _license = new PasswordEntry(_panel); - table->Add(_license->get_panel(), 1, wxEXPAND | wxALL); + _licence = new PasswordEntry(_panel); + table->Add(_licence->get_panel(), 1, wxEXPAND | wxALL); _enable_gpu->bind(&GPUPage::enable_gpu_changed, this); _binary_location->Bind(wxEVT_DIRPICKER_CHANGED, boost::bind (&GPUPage::binary_location_changed, this)); _server->Bind(wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this)); _port->Bind(wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this)); - _license->Changed.connect(boost::bind(&GPUPage::license_changed, this)); + _licence->Changed.connect(boost::bind(&GPUPage::licence_changed, this)); setup_sensitivity(); } void setup_sensitivity() { - auto config = Config::instance(); + auto grok = Config::instance()->grok().get_value_or({}); - _binary_location->Enable(config->enable_gpu()); - _gpu_list_control->Enable(config->enable_gpu()); - _server->Enable(config->enable_gpu()); - _port->Enable(config->enable_gpu()); - _license->get_panel()->Enable(config->enable_gpu()); + _binary_location->Enable(grok.enable); + _gpu_list_control->Enable(grok.enable); + _server->Enable(grok.enable); + _port->Enable(grok.enable); + _licence->get_panel()->Enable(grok.enable); } void config_changed() override { - auto config = Config::instance(); + auto grok = Config::instance()->grok().get_value_or({}); - checked_set(_enable_gpu, config->enable_gpu()); - _binary_location->SetPath(std_to_wx(config->gpu_binary_location().string())); + checked_set(_enable_gpu, grok.enable); + _binary_location->SetPath(std_to_wx(grok.binary_location.string())); _gpu_list_control->update(); - _gpu_list_control->set_selection(config->selected_gpu()); - checked_set(_server, config->gpu_license_server()); - checked_set(_port, config->gpu_license_port()); - checked_set(_license, config->gpu_license()); + _gpu_list_control->set_selection(grok.selected); + checked_set(_server, grok.licence_server); + checked_set(_port, grok.licence_port); + checked_set(_licence, grok.licence); } void enable_gpu_changed() { - auto config = Config::instance(); - config->set_enable_gpu(_enable_gpu->GetValue()); + auto grok = Config::instance()->grok().get_value_or({}); + grok.enable = _enable_gpu->GetValue(); + Config::instance()->set_grok(grok); + setup_sensitivity(); } void binary_location_changed() { - Config::instance()->set_gpu_binary_location(wx_to_std(_binary_location->GetPath())); + auto grok = Config::instance()->grok().get_value_or({}); + grok.binary_location = wx_to_std(_binary_location->GetPath()); + Config::instance()->set_grok(grok); + _gpu_list_control->update(); } void server_changed() { - Config::instance()->set_gpu_license_server(wx_to_std(_server->GetValue())); + auto grok = Config::instance()->grok().get_value_or({}); + grok.licence_server = wx_to_std(_server->GetValue()); + Config::instance()->set_grok(grok); } void port_changed() { - Config::instance()->set_gpu_license_port(_port->GetValue()); + auto grok = Config::instance()->grok().get_value_or({}); + grok.licence_port = _port->GetValue(); + Config::instance()->set_grok(grok); } - void license_changed() + void licence_changed() { - Config::instance()->set_gpu_license(_license->get()); + auto grok = Config::instance()->grok().get_value_or({}); + grok.licence = wx_to_std(_licence->get()); + Config::instance()->set_grok(grok); } CheckBox* _enable_gpu = nullptr; @@ -210,5 +223,5 @@ private: GpuList* _gpu_list_control = nullptr; wxTextCtrl* _server = nullptr; wxSpinCtrl* _port = nullptr; - PasswordEntry* _license = nullptr; + PasswordEntry* _licence = nullptr; }; -- cgit v1.2.3