diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-02-22 23:14:26 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-08-23 20:32:01 +0200 |
| commit | 90154a126c2b71b4a574ab21b366bd6c72ff6d17 (patch) | |
| tree | 8e4eba7d29243fec4ce9cc0d8099b3c1a4811df4 | |
| parent | 5d3c9573914a61db10b24ce7e0cef00902c2912c (diff) | |
Make class hierarchy to handle different J2K encoder 'worker's.
| -rw-r--r-- | src/lib/cpu_j2k_encode_worker.cc | 54 | ||||
| -rw-r--r-- | src/lib/cpu_j2k_encode_worker.h | 29 | ||||
| -rw-r--r-- | src/lib/j2k_encode_worker.h | 36 | ||||
| -rw-r--r-- | src/lib/j2k_encoder.cc | 65 | ||||
| -rw-r--r-- | src/lib/j2k_encoder.h | 6 | ||||
| -rw-r--r-- | src/lib/remote_j2k_encode_worker.cc | 65 | ||||
| -rw-r--r-- | src/lib/remote_j2k_encode_worker.h | 41 | ||||
| -rw-r--r-- | src/lib/wscript | 2 |
8 files changed, 251 insertions, 47 deletions
diff --git a/src/lib/cpu_j2k_encode_worker.cc b/src/lib/cpu_j2k_encode_worker.cc new file mode 100644 index 000000000..6b0af3511 --- /dev/null +++ b/src/lib/cpu_j2k_encode_worker.cc @@ -0,0 +1,54 @@ +/* + Copyright (C) 2019 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_encode_worker.h" +#include "cross.h" +#include "dcp_video.h" +#include "dcpomatic_log.h" + +#include "i18n.h" + +using dcp::Data; +using boost::optional; +using boost::shared_ptr; + +optional<Data> +CPUJ2KEncodeWorker::encode (shared_ptr<DCPVideo> vf) +{ + optional<Data> 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 +CPUJ2KEncodeWorker::log_thread_start () +{ + LOG_TIMING ("start-encoder-thread thread=%1 server=localhost", thread_id()); +} diff --git a/src/lib/cpu_j2k_encode_worker.h b/src/lib/cpu_j2k_encode_worker.h new file mode 100644 index 000000000..5117ff9dd --- /dev/null +++ b/src/lib/cpu_j2k_encode_worker.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2019 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 "j2k_encode_worker.h" +#include <dcp/data.h> + +class CPUJ2KEncodeWorker : public J2KEncodeWorker +{ +public: + boost::optional<dcp::Data> encode (boost::shared_ptr<DCPVideo>); + void log_thread_start (); +}; diff --git a/src/lib/j2k_encode_worker.h b/src/lib/j2k_encode_worker.h new file mode 100644 index 000000000..29d873634 --- /dev/null +++ b/src/lib/j2k_encode_worker.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2019 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_ENCODE_WORKER_H +#define DCPOMATIC_J2K_ENCODE_WORKER_H + +#include <dcp/data.h> +#include <boost/optional.hpp> + +class DCPVideo; + +class J2KEncodeWorker +{ +public: + virtual boost::optional<dcp::Data> encode (boost::shared_ptr<DCPVideo>) = 0; + virtual void log_thread_start () = 0; +}; + +#endif diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 4e2a30ef7..e906a2e1a 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -23,6 +23,8 @@ */ #include "j2k_encoder.h" +#include "cpu_j2k_encode_worker.h" +#include "remote_j2k_encode_worker.h" #include "util.h" #include "film.h" #include "log.h" @@ -258,15 +260,16 @@ J2KEncoder::terminate_threads () } void -J2KEncoder::encoder_thread (optional<EncodeServerDescription> server) +J2KEncoder::encoder_thread (weak_ptr<J2KEncodeWorker> weak_worker) try { - 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 ()); + shared_ptr<J2KEncodeWorker> worker = weak_worker.lock (); + if (!worker) { + return; } + worker->log_thread_start (); + /* Number of seconds that we currently wait between attempts to connect to the server; not relevant for localhost encodings. @@ -296,42 +299,7 @@ try lock.unlock (); - optional<Data> encoded; - - /* We need to encode this input */ - if (server) { - try { - encoded = 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 = 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; - } - } + optional<Data> encoded = worker->encode (vf); if (encoded) { _writer->write (encoded.get(), vf->index (), vf->eyes ()); @@ -382,17 +350,21 @@ J2KEncoder::servers_list_changed () } #endif + _workers.clear (); + if (!Config::instance()->only_servers_encode ()) { for (int i = 0; i < Config::instance()->master_encoding_threads (); ++i) { + shared_ptr<CPUJ2KEncodeWorker> w (new CPUJ2KEncodeWorker()); + _workers.push_back (w); #ifdef DCPOMATIC_LINUX - boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>())); + boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, w)); pthread_setname_np (t->native_handle(), "encode-worker"); #endif #ifdef DCPOMATIC_OSX - _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>())); + _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, w)); #endif #ifdef DCPOMATIC_WINDOWS - boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>())); + boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, w)); if (windows_xp) { SetThreadAffinityMask (t->native_handle(), 1 << i); } @@ -407,7 +379,10 @@ J2KEncoder::servers_list_changed () 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)); + shared_ptr<RemoteJ2KEncodeWorker> w (new RemoteJ2KEncodeWorker(i)); + _workers.push_back (w); + _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, w)); + _threads.push_back (new boost::thread(boost::bind(&J2KEncoder::encoder_thread, this, w))); } } diff --git a/src/lib/j2k_encoder.h b/src/lib/j2k_encoder.h index d56fc1aec..ff48ebbda 100644 --- a/src/lib/j2k_encoder.h +++ b/src/lib/j2k_encoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -45,6 +45,7 @@ class DCPVideo; class Writer; class Job; class PlayerVideo; +class J2KEncodeWorker; /** @class J2KEncoder * @brief Class to manage encoding to J2K. @@ -79,7 +80,7 @@ private: void frame_done (); - void encoder_thread (boost::optional<EncodeServerDescription>); + void encoder_thread (boost::weak_ptr<J2KEncodeWorker>); void terminate_threads (); /** Film that we are encoding */ @@ -91,6 +92,7 @@ private: mutable boost::mutex _queue_mutex; std::list<boost::shared_ptr<DCPVideo> > _queue; + std::list<boost::shared_ptr<J2KEncodeWorker> > _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 */ diff --git a/src/lib/remote_j2k_encode_worker.cc b/src/lib/remote_j2k_encode_worker.cc new file mode 100644 index 000000000..7ada26048 --- /dev/null +++ b/src/lib/remote_j2k_encode_worker.cc @@ -0,0 +1,65 @@ +/* + Copyright (C) 2019 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 "remote_j2k_encode_worker.h" +#include "dcp_video.h" +#include "dcpomatic_log.h" +#include "cross.h" + +#include "i18n.h" + +using dcp::Data; +using boost::optional; +using boost::shared_ptr; + +optional<Data> +RemoteJ2KEncodeWorker::encode (shared_ptr<DCPVideo> vf) +{ + optional<Data> 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 +RemoteJ2KEncodeWorker::log_thread_start () +{ + LOG_TIMING ("start-encoder-thread thread=%1 server=%2", thread_id(), _server.host_name()); +} diff --git a/src/lib/remote_j2k_encode_worker.h b/src/lib/remote_j2k_encode_worker.h new file mode 100644 index 000000000..9f860dabd --- /dev/null +++ b/src/lib/remote_j2k_encode_worker.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2019 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 "j2k_encode_worker.h" +#include "encode_server_description.h" +#include <dcp/data.h> + +class DCPVideo; + +class RemoteJ2KEncodeWorker : public J2KEncodeWorker +{ +public: + RemoteJ2KEncodeWorker (EncodeServerDescription s) + : _server(s) + , _remote_backoff(0) + {} + + boost::optional<dcp::Data> encode (boost::shared_ptr<DCPVideo>); + void log_thread_start (); + +private: + EncodeServerDescription _server; + int _remote_backoff; +}; diff --git a/src/lib/wscript b/src/lib/wscript index 0c9cddfa4..007bd9f51 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -56,6 +56,7 @@ sources = """ content.cc content_factory.cc copy_dcp_details_to_film.cc + cpu_j2k_encode_worker.cc create_cli.cc cross_common.cc crypto.cc @@ -144,6 +145,7 @@ sources = """ ratio.cc raw_image_proxy.cc reel_writer.cc + remote_j2k_encode_worker.cc render_text.cc resampler.cc rgba.cc |
