X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fj2k_encoder.cc;h=acd27932e226c87ed8a4572fbfa65b999b1f31ec;hb=a5d004b0773f633401528392fc28e66d70e13ac8;hp=4e2a30ef722cd7a45bcf42dc27c84b90da497a1d;hpb=e3c7656f9dc0acbaf518c051b847ee2e4eb7ba23;p=dcpomatic.git diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 4e2a30ef7..acd27932e 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -37,7 +37,6 @@ #include "encode_server_description.h" #include "compose.hpp" #include -#include #include #include "i18n.h" @@ -45,8 +44,8 @@ using std::list; using std::cout; using std::exception; -using boost::shared_ptr; -using boost::weak_ptr; +using std::shared_ptr; +using std::weak_ptr; using boost::optional; using dcp::Data; using namespace dcpomatic; @@ -64,6 +63,7 @@ J2KEncoder::J2KEncoder (shared_ptr film, shared_ptr writer) J2KEncoder::~J2KEncoder () { + boost::mutex::scoped_lock lm (_threads_mutex); terminate_threads (); } @@ -107,7 +107,10 @@ J2KEncoder::end () LOG_GENERAL_NC (N_("Terminating encoder threads")); - terminate_threads (); + { + boost::mutex::scoped_lock lm (_threads_mutex); + terminate_threads (); + } /* Something might have been thrown during terminate_threads */ rethrow (); @@ -127,7 +130,7 @@ J2KEncoder::end () LOG_GENERAL (N_("Encode left-over frame %1"), (*i)->index ()); try { _writer->write ( - (*i)->encode_locally(), + shared_ptr(new dcp::ArrayData((*i)->encode_locally())), (*i)->index(), (*i)->eyes() ); @@ -178,7 +181,11 @@ J2KEncoder::encode (shared_ptr pv, DCPTime time) { _waker.nudge (); - size_t threads = _threads->size(); + size_t threads = 0; + { + boost::mutex::scoped_lock lm (_threads_mutex); + threads = _threads->size(); + } boost::mutex::scoped_lock queue_lock (_queue_mutex); @@ -209,6 +216,7 @@ J2KEncoder::encode (shared_ptr pv, DCPTime time) LOG_DEBUG_ENCODE("Frame @ %1 J2K", to_string(time)); /* This frame already has J2K data, so just write it */ _writer->write (pv->j2k(), position, pv->eyes ()); + frame_done (); } else if (_last_player_video[pv->eyes()] && _writer->can_repeat(position) && pv->same (_last_player_video[pv->eyes()])) { LOG_DEBUG_ENCODE("Frame @ %1 REPEAT", to_string(time)); _writer->repeat (position, pv->eyes ()); @@ -236,6 +244,8 @@ J2KEncoder::encode (shared_ptr pv, DCPTime time) _last_player_video_time = time; } + +/** Caller must hold a lock on _threads_mutex */ void J2KEncoder::terminate_threads () { @@ -296,12 +306,12 @@ try lock.unlock (); - optional encoded; + shared_ptr encoded; /* We need to encode this input */ if (server) { try { - encoded = vf->encode_remotely (server.get ()); + encoded.reset(new dcp::ArrayData(vf->encode_remotely(server.get()))); if (remote_backoff > 0) { LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", server->host_name ()); @@ -324,7 +334,7 @@ try } else { try { LOG_TIMING ("start-local-encode thread=%1 frame=%2", thread_id(), vf->index()); - encoded = vf->encode_locally (); + encoded.reset(new dcp::ArrayData(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 */ @@ -334,7 +344,7 @@ try } if (encoded) { - _writer->write (encoded.get(), vf->index (), vf->eyes ()); + _writer->write (encoded, vf->index(), vf->eyes()); frame_done (); } else { lock.lock (); @@ -367,40 +377,25 @@ catch (...) void J2KEncoder::servers_list_changed () { + boost::mutex::scoped_lock lm (_threads_mutex); + terminate_threads (); _threads.reset (new boost::thread_group()); /* XXX: could re-use threads */ -#ifdef BOOST_THREAD_PLATFORM_WIN32 - OSVERSIONINFO info; - info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - GetVersionEx (&info); - bool const windows_xp = (info.dwMajorVersion == 5 && info.dwMinorVersion == 1); - if (windows_xp) { - LOG_GENERAL_NC (N_("Setting thread affinity for Windows XP")); - } -#endif - if (!Config::instance()->only_servers_encode ()) { for (int i = 0; i < Config::instance()->master_encoding_threads (); ++i) { #ifdef DCPOMATIC_LINUX boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional())); pthread_setname_np (t->native_handle(), "encode-worker"); -#endif -#ifdef DCPOMATIC_OSX +#else _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional())); -#endif -#ifdef DCPOMATIC_WINDOWS - boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional())); - if (windows_xp) { - SetThreadAffinityMask (t->native_handle(), 1 << i); - } #endif } } - BOOST_FOREACH (EncodeServerDescription i, EncodeServerFinder::instance()->servers()) { + for (auto i: EncodeServerFinder::instance()->servers()) { if (!i.current_link_version()) { continue; }