diff options
| author | Carl Hetherington <cth@carlh.net> | 2020-08-13 14:55:20 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-09-13 20:23:29 +0200 |
| commit | 50e85cf64504b7fc38b4129aa750c2def28b95fd (patch) | |
| tree | 12d30de6149bc7fa39ab388397da128a7d426a44 /src/lib/j2k_encoder_remote_backend.cc | |
| parent | dbb5577ff761cfd25f154fc54c2dc7e111a31c77 (diff) | |
Rearrange encoding so that the different methods / backends are not all crammed into DCPVideo.
Diffstat (limited to 'src/lib/j2k_encoder_remote_backend.cc')
| -rw-r--r-- | src/lib/j2k_encoder_remote_backend.cc | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/lib/j2k_encoder_remote_backend.cc b/src/lib/j2k_encoder_remote_backend.cc new file mode 100644 index 000000000..831134718 --- /dev/null +++ b/src/lib/j2k_encoder_remote_backend.cc @@ -0,0 +1,108 @@ +#include "config.h" +#include "cross.h" +#include "dcp_video.h" +#include "dcpomatic_log.h" +#include "dcpomatic_socket.h" +#include "encode_server_description.h" +#include "j2k_encoder_remote_backend.h" +#include "player_video.h" +#include "warnings.h" +#include <dcp/raw_convert.h> +DCPOMATIC_DISABLE_WARNINGS +#include <libxml++/libxml++.h> +DCPOMATIC_ENABLE_WARNINGS +#include <boost/asio.hpp> +#include <boost/thread.hpp> + +#include "i18n.h" + + +using std::string; +using boost::optional; +using boost::shared_ptr; +using dcp::Data; +using dcp::raw_convert; + + +J2KEncoderRemoteBackend::J2KEncoderRemoteBackend (EncodeServerDescription server) + : _server (server) + , _backoff (0) +{ + +} + + +optional<Data> +J2KEncoderRemoteBackend::encode (shared_ptr<DCPVideo> video) +{ + int const timeout = 30; + + try { + boost::asio::io_service io_service; + boost::asio::ip::tcp::resolver resolver (io_service); + boost::asio::ip::tcp::resolver::query query (_server.host_name(), raw_convert<string>(ENCODE_FRAME_PORT)); + boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query); + + shared_ptr<Socket> socket (new Socket(timeout)); + + socket->connect (*endpoint_iterator); + + /* Collect all XML metadata */ + xmlpp::Document doc; + xmlpp::Element* root = doc.create_root_node ("EncodingRequest"); + root->add_child("Version")->add_child_text(raw_convert<string> (SERVER_LINK_VERSION)); + video->add_metadata (root); + + LOG_DEBUG_ENCODE (N_("Sending frame %1 to remote"), video->index()); + + { + Socket::WriteDigestScope ds (socket); + + /* Send XML metadata */ + string xml = doc.write_to_string ("UTF-8"); + socket->write (xml.length() + 1); + socket->write ((uint8_t *) xml.c_str(), xml.length() + 1); + + /* Send binary data */ + LOG_TIMING("start-remote-send thread=%1", thread_id()); + video->frame()->write_to_socket(socket); + } + + /* Read the response (JPEG2000-encoded data); this blocks until the data + is ready and sent back. + */ + Socket::ReadDigestScope ds (socket); + LOG_TIMING("start-remote-encode thread=%1", thread_id()); + Data e (socket->read_uint32 ()); + LOG_TIMING("start-remote-receive thread=%1", thread_id()); + socket->read (e.data().get(), e.size()); + LOG_TIMING("finish-remote-receive thread=%1", thread_id()); + if (!ds.check()) { + throw NetworkError ("Checksums do not match"); + } + + LOG_DEBUG_ENCODE (N_("Finished remotely-encoded frame %1"), video->index()); + + if (_backoff > 0) { + LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", _server.host_name()); + } + + /* This job succeeded, so remove any backoff */ + _backoff = 0; + + return e; + + } catch (std::exception& e) { + if (_backoff < 60) { + _backoff += 10; + } + LOG_ERROR ( + N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"), + video->index(), _server.host_name(), e.what(), _backoff + ); + + boost::this_thread::sleep (boost::posix_time::seconds(_backoff)); + return optional<Data>(); + } +} + |
