summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-11-21 14:32:45 +0100
committerCarl Hetherington <cth@carlh.net>2021-11-25 00:55:02 +0100
commit72ee4688cbaef0832eb44dee78063bbc0df97bf8 (patch)
treebcc4d4325961936366458f749fb14f145d98a6f9 /src
parentd930131bac027fb37af01c2326f5a76ebc23fef7 (diff)
Add fastvideo J2K encoding backend.
Diffstat (limited to 'src')
-rw-r--r--src/lib/barrier.cc53
-rw-r--r--src/lib/barrier.h43
-rw-r--r--src/lib/config.cc6
-rw-r--r--src/lib/config.h14
-rw-r--r--src/lib/exceptions.cc9
-rw-r--r--src/lib/exceptions.h17
-rw-r--r--src/lib/j2k_encoder.cc75
-rw-r--r--src/lib/j2k_encoder.h6
-rw-r--r--src/lib/j2k_encoder_cpu_backend.h3
-rw-r--r--src/lib/j2k_encoder_fastvideo_backend.cc211
-rw-r--r--src/lib/j2k_encoder_fastvideo_backend.h63
-rw-r--r--src/lib/j2k_encoder_remote_backend.cc11
-rw-r--r--src/lib/j2k_encoder_remote_backend.h2
-rw-r--r--src/lib/wscript4
-rw-r--r--src/tools/wscript2
-rw-r--r--src/wx/full_config_dialog.cc24
-rw-r--r--src/wx/wscript2
17 files changed, 514 insertions, 31 deletions
diff --git a/src/lib/barrier.cc b/src/lib/barrier.cc
new file mode 100644
index 000000000..c00fdf0f0
--- /dev/null
+++ b/src/lib/barrier.cc
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2021 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 "barrier.h"
+
+
+Barrier::Barrier (int count)
+ : _count(count)
+{
+
+}
+
+
+void
+Barrier::wait ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ ++_waiting;
+ if (_waiting >= _count) {
+ _condition.notify_all();
+ _waiting = 0;
+ } else {
+ _condition.wait(lm);
+ }
+}
+
+
+void
+Barrier::lower ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ _count = 0;
+ _condition.notify_all();
+}
+
diff --git a/src/lib/barrier.h b/src/lib/barrier.h
new file mode 100644
index 000000000..3d05c7d5a
--- /dev/null
+++ b/src/lib/barrier.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2021 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 <boost/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+
+
+class Barrier
+{
+public:
+ Barrier (int count);
+ Barrier (Barrier const&) = delete;
+ Barrier& operator= (Barrier const&) = delete;
+
+ void wait ();
+ void lower ();
+
+private:
+ boost::mutex _mutex;
+ boost::condition _condition;
+ int _count;
+ int _waiting = 0;
+};
+
+
diff --git a/src/lib/config.cc b/src/lib/config.cc
index 78f35e821..9c31c0621 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -80,6 +80,7 @@ Config::Config ()
void
Config::set_defaults ()
{
+ _encoding_backend = EncodingBackend::CPU;
_master_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
_server_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
_server_port_base = 6192;
@@ -238,6 +239,10 @@ try
backup ();
}
+ if (auto encoding_backend = f.optional_string_child("EncodingBackend")) {
+ _encoding_backend = *encoding_backend == "cpu" ? EncodingBackend::CPU : EncodingBackend::FASTVIDEO;
+ }
+
if (f.optional_number_child<int>("NumLocalEncodingThreads")) {
_master_encoding_threads = _server_encoding_threads = f.optional_number_child<int>("NumLocalEncodingThreads").get();
} else {
@@ -609,6 +614,7 @@ Config::write_config () const
/* [XML] Version The version number of the configuration file format. */
root->add_child("Version")->add_child_text (raw_convert<string>(_current_version));
+ root->add_child("EncodingBackend")->add_child_text(_encoding_backend == EncodingBackend::CPU ? "cpu" : "fastvideo");
/* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
/* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */
diff --git a/src/lib/config.h b/src/lib/config.h
index 215e6a4db..26624ff04 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -50,6 +50,15 @@ class DKDMRecipient;
class Config : public State
{
public:
+ enum class EncodingBackend {
+ CPU,
+ FASTVIDEO
+ };
+
+ EncodingBackend encoding_backend() const {
+ return _encoding_backend;
+ }
+
/** @return number of threads which a master DoM should use for J2K encoding on the local machine */
int master_encoding_threads () const {
return _master_encoding_threads;
@@ -545,6 +554,10 @@ public:
/* SET (mostly) */
+ void set_encoding_backend (EncodingBackend backend) {
+ maybe_set (_encoding_backend, backend);
+ }
+
void set_master_encoding_threads (int n) {
maybe_set (_master_encoding_threads, n);
}
@@ -1122,6 +1135,7 @@ private:
changed (prop);
}
+ EncodingBackend _encoding_backend;
/** number of threads which a master DoM should use for J2K encoding on the local machine */
int _master_encoding_threads;
/** number of threads which a server should use for J2K encoding on the local machine */
diff --git a/src/lib/exceptions.cc b/src/lib/exceptions.cc
index 3f87a2ebe..630df7d5c 100644
--- a/src/lib/exceptions.cc
+++ b/src/lib/exceptions.cc
@@ -163,3 +163,12 @@ VerifyError::VerifyError (string m, int n)
}
+
+#ifdef DCPOMATIC_FASTVIDEO
+FastvideoError::FastvideoError (string s, string message)
+ : runtime_error (String::compose("Fastvideo error in %1 (%2)", s, message))
+{
+
+}
+#endif
+
diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h
index 9b7837a46..3e841a354 100644
--- a/src/lib/exceptions.h
+++ b/src/lib/exceptions.h
@@ -32,6 +32,9 @@
extern "C" {
#include <libavutil/pixfmt.h>
}
+#ifdef DCPOMATIC_FASTVIDEO
+#include <common/EnumToStringSdk.h>
+#endif
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include <cstring>
@@ -447,4 +450,18 @@ public:
};
+#ifdef DCPOMATIC_FASTVIDEO
+class FastvideoError : public std::runtime_error
+{
+public:
+ template <class T>
+ FastvideoError (std::string s, T code)
+ : std::runtime_error (String::compose("Fastvideo error in %1 (%2)", s, EnumToString(code)))
+ {}
+
+ FastvideoError (std::string s, std::string message);
+};
+#endif
+
+
#endif
diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc
index fae7752cf..70f3c32d4 100644
--- a/src/lib/j2k_encoder.cc
+++ b/src/lib/j2k_encoder.cc
@@ -26,6 +26,9 @@
#include "j2k_encoder_cpu_backend.h"
#include "j2k_encoder_remote_backend.h"
+#ifdef DCPOMATIC_FASTVIDEO
+#include "j2k_encoder_fastvideo_backend.h"
+#endif
#include "j2k_encoder.h"
#include "util.h"
#include "film.h"
@@ -60,6 +63,9 @@ using namespace dcpomatic;
*/
J2KEncoder::J2KEncoder (shared_ptr<const Film> film, shared_ptr<Writer> writer)
: _film (film)
+#ifdef DCPOMATIC_FASTVIDEO
+ , _gpu_barrier (Config::instance()->master_encoding_threads())
+#endif
, _history (200)
, _writer (writer)
{
@@ -105,6 +111,10 @@ J2KEncoder::end ()
LOG_GENERAL (N_("Clearing queue of %1"), _queue.size ());
+#ifdef DCPOMATIC_FASTVIDEO
+ _gpu_barrier.lower();
+#endif
+
/* Keep waking workers until the queue is empty */
while (!_queue.empty ()) {
rethrow ();
@@ -341,20 +351,12 @@ catch (...)
}
-void
-J2KEncoder::servers_list_changed ()
-try
+int
+J2KEncoder::create_cpu_threads ()
{
- boost::mutex::scoped_lock lm (_threads_mutex);
-
- terminate_threads ();
- _threads = make_shared<boost::thread_group>();
-
- _frames_in_parallel = 0;
-
- /* XXX: could re-use threads */
+ int parallel = 0;
- if (!Config::instance()->only_servers_encode ()) {
+ if (!Config::instance()->only_servers_encode()) {
auto backend = std::make_shared<J2KEncoderCPUBackend>();
for (int i = 0; i < Config::instance()->master_encoding_threads (); ++i) {
#ifdef DCPOMATIC_LINUX
@@ -363,7 +365,7 @@ try
#else
_threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, backend));
#endif
- _frames_in_parallel += backend->quantity();
+ parallel += backend->quantity();
}
}
@@ -377,11 +379,54 @@ try
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, backend));
- _frames_in_parallel += backend->quantity();
+ parallel += backend->quantity();
}
}
- _writer->set_encoder_threads (_threads->size());
+ return parallel;
+}
+
+
+#ifdef DCPOMATIC_FASTVIDEO
+int
+J2KEncoder::create_fastvideo_threads ()
+{
+ int parallel = 0;
+ for (int i = 0; i < Config::instance()->master_encoding_threads(); ++i) {
+ auto backend = std::make_shared<J2KEncoderFastvideoBackend>(_gpu_barrier);
+ _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, backend));
+ parallel += backend->quantity();
+ }
+ return parallel;
+}
+#endif
+
+
+void
+J2KEncoder::servers_list_changed ()
+try
+{
+ boost::mutex::scoped_lock lm (_threads_mutex);
+
+ terminate_threads ();
+ _threads = make_shared<boost::thread_group>();
+
+ /* XXX: could re-use threads */
+
+#ifdef DCPOMATIC_FASTVIDEO
+ switch (Config::instance()->encoding_backend()) {
+ case Config::EncodingBackend::CPU:
+ _frames_in_parallel = create_cpu_threads();
+ break;
+ case Config::EncodingBackend::FASTVIDEO:
+ _frames_in_parallel = create_fastvideo_threads();
+ break;
+ }
+#else
+ _frames_in_parallel = create_cpu_threads();
+#endif
+
+ _writer->set_encoder_threads (_frames_in_parallel);
}
catch (...) {
terminate_threads ();
diff --git a/src/lib/j2k_encoder.h b/src/lib/j2k_encoder.h
index 2139eee3d..22000424d 100644
--- a/src/lib/j2k_encoder.h
+++ b/src/lib/j2k_encoder.h
@@ -28,6 +28,7 @@
*/
+#include "barrier.h"
#include "cross.h"
#include "event_history.h"
#include "exception_store.h"
@@ -86,10 +87,15 @@ private:
void frame_done ();
void encoder_thread (std::shared_ptr<J2KEncoderBackend> backend);
+ int create_cpu_threads ();
void terminate_threads ();
std::shared_ptr<const Film> _film;
+#ifdef DCPOMATIC_FASTVIDEO
+ int create_fastvideo_threads ();
+ Barrier _gpu_barrier;
+#endif
EventHistory _history;
diff --git a/src/lib/j2k_encoder_cpu_backend.h b/src/lib/j2k_encoder_cpu_backend.h
index 82b8aeb48..c09905454 100644
--- a/src/lib/j2k_encoder_cpu_backend.h
+++ b/src/lib/j2k_encoder_cpu_backend.h
@@ -29,9 +29,6 @@
class J2KEncoderCPUBackend : public J2KEncoderBackend
{
public:
- J2KEncoderCPUBackend () = default;
- J2KEncoderCPUBackend (J2KEncoderCPUBackend&& other) = default;
-
std::vector<dcp::ArrayData> encode (std::vector<DCPVideo> const& video) override;
};
diff --git a/src/lib/j2k_encoder_fastvideo_backend.cc b/src/lib/j2k_encoder_fastvideo_backend.cc
new file mode 100644
index 000000000..68707ad62
--- /dev/null
+++ b/src/lib/j2k_encoder_fastvideo_backend.cc
@@ -0,0 +1,211 @@
+/*
+ Copyright (C) 2021 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 "barrier.h"
+#include "dcp_video.h"
+#include "dcpomatic_assert.h"
+#include "dcpomatic_log.h"
+#include "exceptions.h"
+#include "image.h"
+#include "j2k_encoder_fastvideo_backend.h"
+#include "player_video.h"
+#include <dcp/rgb_xyz.h>
+#include <fastvideo_encoder_j2k.h>
+#include <fastvideo_sdk.h>
+#include <common/EnumToStringSdk.h>
+
+
+using std::vector;
+using boost::optional;
+using dcp::ArrayData;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
+
+
+J2KEncoderFastvideoBackend::J2KEncoderFastvideoBackend (Barrier& barrier)
+ : _barrier (barrier)
+{
+ fastDeviceProperty* device_property;
+ int devices;
+ auto r = fastGetDevices(&device_property, &devices);
+ if (r != FAST_OK) {
+ throw FastvideoError ("GetDevices", r);
+ }
+
+ fastSdkParametersHandle_t sdk_parameters;
+ r = fastGetSdkParametersHandle(&sdk_parameters);
+ if (r != FAST_OK) {
+ throw FastvideoError ("GetSdkParametersHandle", r);
+ }
+ r = fastEncoderJ2kLibraryInit(sdk_parameters);
+ if (r != FAST_OK) {
+ throw FastvideoError ("DecoderJ2kLibraryInit", r);
+ }
+ fastTraceCreate("/home/carl/trace.log");
+}
+
+
+J2KEncoderFastvideoBackend::~J2KEncoderFastvideoBackend ()
+{
+ if (_setup_done) {
+ fastFree (_xyz_buffer);
+ fastEncoderJ2kDestroy (_encoder);
+ fastImportFromHostDestroy (_adapter);
+ }
+}
+
+
+void
+J2KEncoderFastvideoBackend::setup (dcp::Size size)
+{
+ auto r = fastImportFromHostCreate(
+ &_adapter, FAST_RGB12, size.width, size.height, &_src_buffer
+ );
+ if (r != FAST_OK) {
+ throw FastvideoError ("ImportFromHostCreate", r);
+ }
+
+ fastEncoderJ2kStaticParameters_t parameters;
+ parameters.lossless = false;
+ parameters.pcrdEnabled = true;
+ parameters.dwtLevels = 6;
+ parameters.codeblockSize = 32;
+ parameters.maxQuality = 1.5;
+ parameters.compressionRatio = 1;
+ parameters.info = false;
+ parameters.tier2Threads = 4;
+ parameters.tileWidth = size.width;
+ parameters.tileHeight = size.height;
+ parameters.noMCT = false;
+ parameters.ss1_x = 1;
+ parameters.ss1_y = 1;
+ parameters.ss2_x = 1;
+ parameters.ss2_y = 1;
+ parameters.ss3_x = 1;
+ parameters.ss3_y = 1;
+ parameters.yuvSubsampledFormat = false;
+
+ r = fastEncoderJ2kCreate(
+ &_encoder, &parameters, FAST_RGB12, size.width, size.height, quantity(), _src_buffer
+ );
+ if (r != FAST_OK) {
+ throw FastvideoError ("EncoderJ2kCreate", r);
+ }
+
+ bool success = false;
+
+ r = fastEncoderJ2kIsInitialized(_encoder, &success);
+ if (r != FAST_OK || !success) {
+ throw FastvideoError ("EncoderJ2kIsInitialized", r);
+ }
+
+ _xyz_buffer_stride = size.width * 6;
+ _xyz_buffer_stride += 4 - (_xyz_buffer_stride % 4);
+ r = fastMalloc(reinterpret_cast<void**>(&_xyz_buffer), _xyz_buffer_stride * size.height);
+ if (r != FAST_OK) {
+ throw FastvideoError ("Malloc", r);
+ }
+}
+
+
+vector<ArrayData>
+J2KEncoderFastvideoBackend::encode (vector<DCPVideo> const& video)
+{
+ DCPOMATIC_ASSERT (static_cast<int>(video.size()) <= quantity());
+ _barrier.wait();
+
+ if (!_setup_done) {
+ setup (video.front().frame()->out_size());
+ _setup_done = true;
+ }
+
+ for (auto const& i: video) {
+ auto image = i.frame()->image(boost::bind(&PlayerVideo::keep_xyz_or_rgb, _1), VideoRange::FULL, false);
+ if (i.frame()->colour_conversion()) {
+ dcp::rgb_to_xyz (
+ image->data()[0],
+ image->size(),
+ image->stride()[0],
+ _xyz_buffer,
+ _xyz_buffer_stride,
+ i.frame()->colour_conversion().get()
+ );
+ } else {
+ /* XXX */
+ }
+
+ auto r = fastImportFromHostCopy(
+ _adapter,
+ _xyz_buffer,
+ image->size().width,
+ _xyz_buffer_stride,
+ image->size().height
+ );
+ if (r != FAST_OK) {
+ throw FastvideoError ("ImportFromHostCopy", r);
+ }
+
+ fastEncoderJ2kDynamicParameters_t dynamic_parameters;
+ dynamic_parameters.targetStreamSize = i.j2k_bandwidth() / (8 * i.frames_per_second());
+ dynamic_parameters.quality = 1.0;
+ dynamic_parameters.writeHeader = false;
+
+ r = fastEncoderJ2kAddImageToBatch(
+ _encoder,
+ &dynamic_parameters,
+ image->size().width,
+ image->size().height
+ );
+ if (r != FAST_OK) {
+ throw FastvideoError ("EncoderJ2kAddImageToBatch", r);
+ }
+ }
+
+
+ fastEncoderJ2kReport_t report;
+ fastEncoderJ2kOutput_t output;
+ int constexpr max_j2k_size = 1024 * 1024 * 2;
+ output.bufferSize = max_j2k_size;
+ dcp::ArrayData data(output.bufferSize);
+ output.byteStream = data.data();
+
+ auto r = fastEncoderJ2kTransformBatch(_encoder, &output, &report);
+ if (r != FAST_OK) {
+ fastTraceClose();
+ throw FastvideoError ("EncoderJ2KTransformBatch", r);
+ }
+
+ vector<dcp::ArrayData> encoded;
+ for (size_t i = 0; i < video.size(); ++i) {
+ data.set_size (output.streamSize);
+ encoded.push_back (data);
+ data = dcp::ArrayData(output.bufferSize);
+ output.byteStream = data.data();
+ int images_left = 0;
+ r = fastEncoderJ2kGetNextEncodedImage (_encoder, &output, &report, &images_left);
+ }
+
+ return encoded;
+}
+
+
diff --git a/src/lib/j2k_encoder_fastvideo_backend.h b/src/lib/j2k_encoder_fastvideo_backend.h
new file mode 100644
index 000000000..0e5ccb3be
--- /dev/null
+++ b/src/lib/j2k_encoder_fastvideo_backend.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2021 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_ENCODER_FASTVIDEO_BACKEND_H
+#define DCPOMATIC_J2K_ENCODER_FASTVIDEO_BACKEND_H
+
+
+#include "j2k_encoder_backend.h"
+#include <dcp/util.h>
+#include <fastvideo_encoder_j2k.h>
+#include <fastvideo_sdk.h>
+#include <boost/thread.hpp>
+
+
+class Barrier;
+
+
+class J2KEncoderFastvideoBackend : public J2KEncoderBackend
+{
+public:
+ J2KEncoderFastvideoBackend (Barrier& barrier);
+ ~J2KEncoderFastvideoBackend ();
+
+ std::vector<dcp::ArrayData> encode (std::vector<DCPVideo> const& video) override;
+
+ int quantity () const override {
+ return 1;
+ }
+
+private:
+ void setup (dcp::Size size);
+
+ Barrier& _barrier;
+ bool _setup_done = false;
+ fastImportFromHostHandle_t _adapter;
+ fastDeviceSurfaceBufferHandle_t _src_buffer;
+ fastEncoderJ2kHandle_t _encoder;
+ uint16_t* _xyz_buffer;
+ int _xyz_buffer_stride;
+};
+
+
+#endif
+
+
diff --git a/src/lib/j2k_encoder_remote_backend.cc b/src/lib/j2k_encoder_remote_backend.cc
index df5d6e30d..b50ddad7b 100644
--- a/src/lib/j2k_encoder_remote_backend.cc
+++ b/src/lib/j2k_encoder_remote_backend.cc
@@ -38,22 +38,11 @@ DCPOMATIC_ENABLE_WARNINGS
using std::make_shared;
-using std::shared_ptr;
using std::string;
-using std::unique_ptr;
using std::vector;
-using boost::optional;
using dcp::raw_convert;
-J2KEncoderRemoteBackend::J2KEncoderRemoteBackend (J2KEncoderRemoteBackend&& other)
- : _server (other._server)
- , _backoff (other._backoff)
-{
-
-}
-
-
vector<dcp::ArrayData>
J2KEncoderRemoteBackend::encode (vector<DCPVideo> const& all_video)
{
diff --git a/src/lib/j2k_encoder_remote_backend.h b/src/lib/j2k_encoder_remote_backend.h
index 962944bbe..b034825d3 100644
--- a/src/lib/j2k_encoder_remote_backend.h
+++ b/src/lib/j2k_encoder_remote_backend.h
@@ -35,8 +35,6 @@ public:
, _timeout (timeout)
{}
- J2KEncoderRemoteBackend (J2KEncoderRemoteBackend&& other);
-
std::vector<dcp::ArrayData> encode (std::vector<DCPVideo> const& video) override;
private:
diff --git a/src/lib/wscript b/src/lib/wscript
index 9d7e1d11b..80eb7829e 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -44,6 +44,7 @@ sources = """
audio_processor.cc
audio_ring_buffers.cc
audio_stream.cc
+ barrier.cc
butler.cc
text_content.cc
text_decoder.cc
@@ -226,6 +227,9 @@ def build(bld):
obj.source += ' cross_linux.cc'
if bld.env.STATIC_DCPOMATIC:
obj.uselib += ' XMLPP'
+ if bld.env.ENABLE_FASTVIDEO:
+ obj.uselib += ' FASTVIDEO'
+ obj.source += ' j2k_encoder_fastvideo_backend.cc'
obj.target = 'dcpomatic2'
diff --git a/src/tools/wscript b/src/tools/wscript
index 018689e03..39c8279e7 100644
--- a/src/tools/wscript
+++ b/src/tools/wscript
@@ -41,6 +41,8 @@ def build(bld):
uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE WINSOCK2 OLE32 DSOUND WINMM KSUSER SETUPAPI '
if bld.env.TARGET_LINUX:
uselib += 'DL '
+ if bld.env.ENABLE_FASTVIDEO:
+ uselib += ' FASTVIDEO'
cli_tools = ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm_cli', 'dcpomatic_create']
if bld.env.ENABLE_DISK and not bld.env.DISABLE_GUI:
diff --git a/src/wx/full_config_dialog.cc b/src/wx/full_config_dialog.cc
index db499f575..d10b01d8e 100644
--- a/src/wx/full_config_dialog.cc
+++ b/src/wx/full_config_dialog.cc
@@ -94,6 +94,13 @@ private:
int r = 0;
add_language_controls (table, r);
+#ifdef DCPOMATIC_FASTVIDEO
+ add_label_to_sizer (table, _panel, _("Encode using"), true, wxGBPosition(r, 0));
+ _encoding_backend = new wxChoice (_panel, wxID_ANY);
+ table->Add (_encoding_backend, wxGBPosition(r, 1));
+ ++r;
+#endif
+
add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
_master_encoding_threads = new wxSpinCtrl (_panel);
table->Add (_master_encoding_threads, wxGBPosition (r, 1));
@@ -128,6 +135,11 @@ private:
add_update_controls (table, r);
+#ifdef DCPOMATIC_FASTVIDEO
+ _encoding_backend->Append ("CPU");
+ _encoding_backend->Append ("GPU");
+ _encoding_backend->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::encoding_backend_changed, this));
+#endif
_config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind(&FullGeneralPage::config_file_changed, this));
_cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind(&FullGeneralPage::cinemas_file_changed, this));
@@ -147,6 +159,10 @@ private:
{
auto config = Config::instance ();
+#ifdef DCPOMATIC_FASTVIDEO
+ checked_set (_encoding_backend, Config::instance()->encoding_backend() == Config::EncodingBackend::CPU ? 0 : 1);
+#endif
+
checked_set (_master_encoding_threads, config->master_encoding_threads ());
checked_set (_server_encoding_threads, config->server_encoding_threads ());
#ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
@@ -159,6 +175,11 @@ private:
GeneralPage::config_changed ();
}
+ void encoding_backend_changed ()
+ {
+ Config::instance()->set_encoding_backend(_encoding_backend->GetSelection() == 0 ? Config::EncodingBackend::CPU : Config::EncodingBackend::FASTVIDEO);
+ }
+
void export_cinemas_file ()
{
auto d = new wxFileDialog (
@@ -225,6 +246,9 @@ private:
Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
}
+#ifdef DCPOMATIC_FASTVIDEO
+ wxChoice* _encoding_backend;
+#endif
wxSpinCtrl* _master_encoding_threads;
wxSpinCtrl* _server_encoding_threads;
FilePickerCtrl* _config_file;
diff --git a/src/wx/wscript b/src/wx/wscript
index 50c078f2b..757772183 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -316,6 +316,8 @@ def build(bld):
obj.uselib += 'WINSOCK2 OLE32 DSOUND WINMM KSUSER GL GLU GLEW '
if bld.env.TARGET_OSX:
obj.framework = ['CoreAudio', 'OpenGL']
+ if bld.env.ENABLE_FASTVIDEO:
+ obj.uselib += ' FASTVIDEO'
obj.use = 'libdcpomatic2'
obj.source = sources
obj.target = 'dcpomatic2-wx'