--- /dev/null
+/*
+ Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "cpu_j2k_frame_encoder.h"
+#include "cross.h"
+#include "dcp_video.h"
+#include "dcpomatic_log.h"
+
+#include "i18n.h"
+
+
+using std::shared_ptr;
+using boost::optional;
+using dcp::ArrayData;
+
+
+optional<ArrayData>
+CPUJ2KFrameEncoder::encode (DCPVideo const& vf)
+{
+ optional<ArrayData> encoded;
+
+ try {
+ LOG_TIMING("start-local-encode thread=%1 frame=%2", thread_id(), vf.index());
+ encoded = vf.encode_locally();
+ LOG_TIMING("finish-local-encode thread=%1 frame=%2", thread_id(), vf.index());
+ } catch (std::exception& e) {
+ /* This is very bad, so don't cope with it, just pass it on */
+ LOG_ERROR(N_("Local encode failed (%1)"), e.what());
+ throw;
+ }
+
+ return encoded;
+}
+
+
+void
+CPUJ2KFrameEncoder::log_thread_start ()
+{
+ LOG_TIMING("start-encoder-thread thread=%1 server=localhost", thread_id());
+}
+
--- /dev/null
+/*
+ Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_CPU_J2K_FRAME_ENCODER
+#define DCPOMATIC_CPU_J2K_FRAME_ENCODER
+
+
+#include "j2k_frame_encoder.h"
+
+
+class CPUJ2KFrameEncoder : public J2KFrameEncoder
+{
+public:
+ boost::optional<dcp::ArrayData> encode (DCPVideo const &) override;
+ void log_thread_start () override;
+};
+
+
+#endif
+
#include "compose.hpp"
#include "config.h"
+#include "cpu_j2k_frame_encoder.h"
#include "cross.h"
#include "dcp_video.h"
#include "dcpomatic_log.h"
#include "log.h"
#include "player.h"
#include "player_video.h"
+#include "remote_j2k_frame_encoder.h"
#include "util.h"
#include "writer.h"
#include <libcxml/cxml.h>
void
-J2KEncoder::encoder_thread (optional<EncodeServerDescription> server)
+J2KEncoder::encoder_thread (weak_ptr<J2KFrameEncoder> weak_worker)
try
{
- start_of_thread ("J2KEncoder");
-
- if (server) {
- LOG_TIMING ("start-encoder-thread thread=%1 server=%2", thread_id (), server->host_name ());
- } else {
- LOG_TIMING ("start-encoder-thread thread=%1 server=localhost", thread_id ());
+ auto worker = weak_worker.lock();
+ if (!worker) {
+ return;
}
/* Number of seconds that we currently wait between attempts
lock.unlock ();
- shared_ptr<Data> encoded;
-
- /* We need to encode this input */
- if (server) {
- try {
- encoded = make_shared<dcp::ArrayData>(vf.encode_remotely(server.get()));
-
- if (remote_backoff > 0) {
- LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", server->host_name ());
- }
-
- /* This job succeeded, so remove any backoff */
- remote_backoff = 0;
-
- } catch (std::exception& e) {
- if (remote_backoff < 60) {
- /* back off more */
- remote_backoff += 10;
- }
- LOG_ERROR (
- N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"),
- vf.index(), server->host_name(), e.what(), remote_backoff
- );
- }
-
- } else {
- try {
- LOG_TIMING ("start-local-encode thread=%1 frame=%2", thread_id(), vf.index());
- encoded = make_shared<dcp::ArrayData>(vf.encode_locally());
- LOG_TIMING ("finish-local-encode thread=%1 frame=%2", thread_id(), vf.index());
- } catch (std::exception& e) {
- /* This is very bad, so don't cope with it, just pass it on */
- LOG_ERROR (N_("Local encode failed (%1)"), e.what ());
- throw;
- }
- }
+ auto encoded = worker->encode(vf);
if (encoded) {
- _writer->write (encoded, vf.index(), vf.eyes());
+ _writer->write (make_shared<dcp::ArrayData>(*encoded), vf.index(), vf.eyes());
frame_done ();
} else {
lock.lock ();
if (!Config::instance()->only_servers_encode ()) {
for (int i = 0; i < Config::instance()->master_encoding_threads (); ++i) {
+ auto worker = make_shared<CPUJ2KFrameEncoder>();
+ _workers.push_back(worker);
#ifdef DCPOMATIC_LINUX
- auto t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>()));
+ auto t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, worker));
pthread_setname_np (t->native_handle(), "encode-worker");
#else
- _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>()));
+ _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, worker));
#endif
}
}
LOG_GENERAL (N_("Adding %1 worker threads for remote %2"), i.threads(), i.host_name ());
for (int j = 0; j < i.threads(); ++j) {
- _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, i));
+ auto worker = make_shared<RemoteJ2KFrameEncoder>(i);
+ _workers.push_back(worker);
+ _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, worker));
}
}
#include <stdint.h>
-class Film;
-class EncodeServerDescription;
class DCPVideo;
-class Writer;
+class EncodeServerDescription;
+class Film;
+class J2KFrameEncoder;
class Job;
class PlayerVideo;
+class Writer;
/** @class J2KEncoder
void frame_done ();
- void encoder_thread (boost::optional<EncodeServerDescription>);
+ void encoder_thread (std::weak_ptr<J2KFrameEncoder> worker);
void terminate_threads ();
/** Film that we are encoding */
mutable boost::mutex _queue_mutex;
std::list<DCPVideo> _queue;
+ std::list<std::shared_ptr<J2KFrameEncoder>> _workers;
/** condition to manage thread wakeups when we have nothing to do */
boost::condition _empty_condition;
/** condition to manage thread wakeups when we have too much to do */
--- /dev/null
+/*
+ Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_J2K_FRAME_ENCODER
+#define DCPOMATIC_J2K_FRAME_ENCODER
+
+
+#include <dcp/array_data.h>
+#include <boost/optional.hpp>
+#include <memory>
+
+
+class DCPVideo;
+
+
+class J2KFrameEncoder
+{
+public:
+ virtual ~J2KFrameEncoder() {}
+
+ virtual boost::optional<dcp::ArrayData> encode (DCPVideo const &) = 0;
+ virtual void log_thread_start () = 0;
+};
+
+
+#endif
+
--- /dev/null
+/*
+ Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "cross.h"
+#include "dcp_video.h"
+#include "dcpomatic_log.h"
+#include "remote_j2k_frame_encoder.h"
+
+#include "i18n.h"
+
+
+using std::make_shared;
+using std::shared_ptr;
+using boost::optional;
+using dcp::Data;
+
+
+optional<dcp::ArrayData>
+RemoteJ2KFrameEncoder::encode(DCPVideo const& vf)
+{
+ optional<dcp::ArrayData> encoded;
+
+ try {
+ encoded = vf.encode_remotely(_server);
+
+ if (_remote_backoff > 0) {
+ LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", _server.host_name());
+ }
+
+ /* This job succeeded, so remove any backoff */
+ _remote_backoff = 0;
+
+ } catch (std::exception& e) {
+ if (_remote_backoff < 60) {
+ /* back off more */
+ _remote_backoff += 10;
+ }
+ LOG_ERROR (
+ N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"),
+ vf.index(), _server.host_name(), e.what(), _remote_backoff
+ );
+ }
+
+ return encoded;
+}
+
+
+void
+RemoteJ2KFrameEncoder::log_thread_start ()
+{
+ LOG_TIMING("start-encoder-thread thread=%1 server=%2", thread_id(), _server.host_name());
+}
+
--- /dev/null
+/*
+ Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_REMOTE_J2K_FRAME_ENCODER
+#define DCPOMATIC_REMOTE_J2K_FRAME_ENCODER
+
+
+#include "j2k_frame_encoder.h"
+
+
+class RemoteJ2KFrameEncoder : public J2KFrameEncoder
+{
+public:
+ RemoteJ2KFrameEncoder(EncodeServerDescription s)
+ : _server(s)
+ {}
+
+ boost::optional<dcp::ArrayData> encode (DCPVideo const &) override;
+ void log_thread_start () override;
+
+private:
+ EncodeServerDescription _server;
+ int _remote_backoff = 0;
+};
+
+
+#endif
+
content_factory.cc
combine_dcp_job.cc
copy_dcp_details_to_film.cc
+ cpu_j2k_frame_encoder.cc
create_cli.cc
cross_common.cc
crypto.cc
ratio.cc
raw_image_proxy.cc
reel_writer.cc
+ remote_j2k_frame_encoder.cc
render_text.cc
resampler.cc
rgba.cc