diff options
| author | Carl Hetherington <cth@carlh.net> | 2021-11-21 14:51:09 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2021-11-22 23:59:43 +0100 |
| commit | 0a49cc2ebbfc3809313f252208a0050a3fce1e97 (patch) | |
| tree | eabde99894ed4caa25970a8b967eb69ebac4a08a /src/lib/dcp_video.cc | |
| parent | 0254f2d12acb2ff8d770b4e47dc15599d145fe17 (diff) | |
Separate out local/remote encode code from DCPVideo.
Now we have a J2KEncoderCPUBackend and a J2KEncoderRemoteBackend.
Diffstat (limited to 'src/lib/dcp_video.cc')
| -rw-r--r-- | src/lib/dcp_video.cc | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/src/lib/dcp_video.cc b/src/lib/dcp_video.cc index 4a41e17b9..9b0c76ceb 100644 --- a/src/lib/dcp_video.cc +++ b/src/lib/dcp_video.cc @@ -121,138 +121,6 @@ DCPVideo::convert_to_xyz (shared_ptr<const PlayerVideo> frame, dcp::NoteHandler return xyz; } -/** J2K-encode this frame on the local host. - * @return Encoded data. - */ -ArrayData -DCPVideo::encode_locally () const -{ - auto const comment = Config::instance()->dcp_j2k_comment(); - - ArrayData enc = {}; - /* This was empirically derived by a user: see #1902 */ - int const minimum_size = 16384; - LOG_GENERAL ("Using minimum frame size %1", minimum_size); - - auto xyz = convert_to_xyz (_frame, boost::bind(&Log::dcp_log, dcpomatic_log.get(), _1, _2)); - int noise_amount = 2; - int pixel_skip = 16; - while (true) { - enc = dcp::compress_j2k ( - xyz, - _j2k_bandwidth, - _frames_per_second, - _frame->eyes() == Eyes::LEFT || _frame->eyes() == Eyes::RIGHT, - _resolution == Resolution::FOUR_K, - comment.empty() ? "libdcp" : comment - ); - - if (enc.size() >= minimum_size) { - LOG_GENERAL (N_("Frame %1 encoded size was OK (%2)"), _index, enc.size()); - break; - } - - LOG_GENERAL (N_("Frame %1 encoded size was small (%2); adding noise at level %3 with pixel skip %4"), _index, enc.size(), noise_amount, pixel_skip); - - /* The JPEG2000 is too low-bitrate for some decoders <cough>DSS200</cough> so add some noise - * and try again. This is slow but hopefully won't happen too often. We have to do - * convert_to_xyz() again because compress_j2k() corrupts its xyz parameter. - */ - - xyz = convert_to_xyz (_frame, boost::bind(&Log::dcp_log, dcpomatic_log.get(), _1, _2)); - auto size = xyz->size (); - auto pixels = size.width * size.height; - dcpomatic::RNG rng(42); - for (auto c = 0; c < 3; ++c) { - auto p = xyz->data(c); - auto e = xyz->data(c) + pixels; - while (p < e) { - *p = std::min(4095, std::max(0, *p + (rng.get() % noise_amount))); - p += pixel_skip; - } - } - - if (pixel_skip > 1) { - --pixel_skip; - } else { - ++noise_amount; - } - /* Something's gone badly wrong if this much noise doesn't help */ - DCPOMATIC_ASSERT (noise_amount < 16); - } - - switch (_frame->eyes()) { - case Eyes::BOTH: - LOG_DEBUG_ENCODE (N_("Finished locally-encoded frame %1 for mono"), _index); - break; - case Eyes::LEFT: - LOG_DEBUG_ENCODE (N_("Finished locally-encoded frame %1 for L"), _index); - break; - case Eyes::RIGHT: - LOG_DEBUG_ENCODE (N_("Finished locally-encoded frame %1 for R"), _index); - break; - default: - break; - } - - return enc; -} - -/** Send this frame to a remote server for J2K encoding, then read the result. - * @param serv Server to send to. - * @param timeout timeout in seconds. - * @return Encoded data. - */ -ArrayData -DCPVideo::encode_remotely (EncodeServerDescription serv, int timeout) const -{ - boost::asio::io_service io_service; - boost::asio::ip::tcp::resolver resolver (io_service); - boost::asio::ip::tcp::resolver::query query (serv.host_name(), raw_convert<string> (ENCODE_FRAME_PORT)); - boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query); - - auto socket = make_shared<Socket>(timeout); - - socket->connect (*endpoint_iterator); - - /* Collect all XML metadata */ - xmlpp::Document doc; - auto root = doc.create_root_node ("EncodingRequest"); - root->add_child("Version")->add_child_text (raw_convert<string> (SERVER_LINK_VERSION)); - add_metadata (root); - - LOG_DEBUG_ENCODE (N_("Sending frame %1 to remote"), _index); - - { - Socket::WriteDigestScope ds (socket); - - /* Send XML metadata */ - auto xml = doc.write_to_string ("UTF-8"); - socket->write (xml.length() + 1); - socket->write ((uint8_t *) xml.c_str(), xml.bytes() + 1); - - /* Send binary data */ - LOG_TIMING("start-remote-send thread=%1", thread_id ()); - _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 ()); - ArrayData e (socket->read_uint32 ()); - LOG_TIMING("start-remote-receive thread=%1", thread_id ()); - socket->read (e.data(), 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"), _index); - - return e; -} void DCPVideo::add_metadata (xmlpp::Element* el) const |
