X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fj2k_encoder.cc;h=e6dab582801fd7177ecea144d294510261c9f41a;hb=82c6dfe9f286e07bdaf3434593ce1c9bd0ee2677;hp=a7fa657f84172fe398c3f8d0a170aa1a572ceedb;hpb=8fedaaa75c4586a4cc7ffb393bd71d1fdb091dc8;p=dcpomatic.git diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index a7fa657f8..e6dab5828 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,39 +18,42 @@ */ + /** @file src/j2k_encoder.cc * @brief J2K encoder class. */ -#include "j2k_encoder.h" -#include "util.h" -#include "film.h" -#include "log.h" -#include "dcpomatic_log.h" + +#include "compose.hpp" #include "config.h" -#include "dcp_video.h" #include "cross.h" -#include "writer.h" +#include "dcp_video.h" +#include "dcpomatic_log.h" +#include "encode_server_description.h" #include "encode_server_finder.h" -#include "player.h" +#include "film.h" +#include "j2k_encoder.h" +#include "log.h" #include "player_video.h" -#include "encode_server_description.h" -#include "compose.hpp" +#include "util.h" +#include "writer.h" #include #include #include "i18n.h" -using std::list; + using std::cout; using std::exception; +using std::list; +using std::make_shared; using std::shared_ptr; using std::weak_ptr; -using std::make_shared; using boost::optional; using dcp::Data; using namespace dcpomatic; + /** @param film Film that we are encoding. * @param writer Writer that we are using. */ @@ -62,12 +65,14 @@ J2KEncoder::J2KEncoder (shared_ptr film, shared_ptr writer) servers_list_changed (); } + J2KEncoder::~J2KEncoder () { boost::mutex::scoped_lock lm (_threads_mutex); terminate_threads (); } + void J2KEncoder::begin () { @@ -77,6 +82,7 @@ J2KEncoder::begin () ); } + /* We don't want the servers-list-changed callback trying to do things during destruction of J2KEncoder, and I think this is the neatest way to achieve that. @@ -90,6 +96,7 @@ J2KEncoder::call_servers_list_changed (weak_ptr encoder) } } + void J2KEncoder::end () { @@ -127,13 +134,13 @@ J2KEncoder::end () So just mop up anything left in the queue here. */ - for (auto i: _queue) { - LOG_GENERAL(N_("Encode left-over frame %1"), i->index()); + for (auto const& i: _queue) { + LOG_GENERAL(N_("Encode left-over frame %1"), i.index()); try { _writer->write ( - make_shared(i->encode_locally()), - i->index(), - i->eyes() + make_shared(i.encode_locally()), + i.index(), + i.eyes() ); frame_done (); } catch (std::exception& e) { @@ -142,6 +149,7 @@ J2KEncoder::end () } } + /** @return an estimate of the current number of frames we are encoding per second, * if known. */ @@ -151,6 +159,7 @@ J2KEncoder::current_encoding_rate () const return _history.rate (); } + /** @return Number of video frames that have been queued for encoding */ int J2KEncoder::video_frames_enqueued () const @@ -162,6 +171,7 @@ J2KEncoder::video_frames_enqueued () const return _last_player_video_time->frames_floor (_film->video_frame_rate ()); } + /** Should be called when a frame has been encoded successfully */ void J2KEncoder::frame_done () @@ -169,6 +179,7 @@ J2KEncoder::frame_done () _history.event (); } + /** Called to request encoding of the next video frame in the DCP. This is called in order, * so each time the supplied frame is the one after the previous one. * pv represents one video frame, and could be empty if there is nothing to encode @@ -225,7 +236,7 @@ J2KEncoder::encode (shared_ptr pv, DCPTime time) LOG_DEBUG_ENCODE("Frame @ %1 ENCODE", to_string(time)); /* Queue this new frame for encoding */ LOG_TIMING ("add-frame-to-queue queue=%1", _queue.size ()); - _queue.push_back (make_shared( + _queue.push_back (DCPVideo( pv, position, _film->video_frame_rate(), @@ -266,10 +277,13 @@ J2KEncoder::terminate_threads () _threads.reset (); } + void J2KEncoder::encoder_thread (optional server) try { + start_of_thread ("J2KEncoder"); + if (server) { LOG_TIMING ("start-encoder-thread thread=%1 server=%2", thread_id (), server->host_name ()); } else { @@ -300,7 +314,7 @@ try { boost::this_thread::disable_interruption dis; - LOG_TIMING ("encoder-pop thread=%1 frame=%2 eyes=%3", thread_id(), vf->index(), (int) vf->eyes ()); + LOG_TIMING ("encoder-pop thread=%1 frame=%2 eyes=%3", thread_id(), vf.index(), static_cast(vf.eyes())); _queue.pop_front (); lock.unlock (); @@ -310,7 +324,7 @@ try /* We need to encode this input */ if (server) { try { - encoded = make_shared(vf->encode_remotely(server.get())); + encoded = make_shared(vf.encode_remotely(server.get())); if (remote_backoff > 0) { LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", server->host_name ()); @@ -326,15 +340,15 @@ try } LOG_ERROR ( N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"), - vf->index(), server->host_name(), e.what(), remote_backoff + 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(vf->encode_locally()); - LOG_TIMING ("finish-local-encode thread=%1 frame=%2", thread_id(), vf->index()); + LOG_TIMING ("start-local-encode thread=%1 frame=%2", thread_id(), vf.index()); + encoded = make_shared(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 ()); @@ -343,11 +357,11 @@ try } if (encoded) { - _writer->write (encoded, vf->index(), vf->eyes()); + _writer->write (encoded, vf.index(), vf.eyes()); frame_done (); } else { lock.lock (); - LOG_GENERAL (N_("[%1] J2KEncoder thread pushes frame %2 back onto queue after failure"), thread_id(), vf->index()); + LOG_GENERAL (N_("[%1] J2KEncoder thread pushes frame %2 back onto queue after failure"), thread_id(), vf.index()); _queue.push_front (vf); lock.unlock (); } @@ -373,6 +387,7 @@ catch (...) _full_condition.notify_all (); } + void J2KEncoder::servers_list_changed () {