X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fencoder.cc;h=0c41d8d806a8ec9bf627a54b2ac579315edab074;hb=57d00c880094b1dfebaee18f4ecafb1dd44b0afb;hp=8f2aa58f70ebbe53db9fb1ef3bd3418d23af1a68;hpb=0b6f2d7b04819711228ed5fbc5d299b58cef997e;p=dcpomatic.git diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 8f2aa58f7..0c41d8d80 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -53,7 +53,7 @@ using boost::weak_ptr; using boost::optional; using dcp::Data; -int const Encoder::_history_size = 25; +int const Encoder::_history_size = 200; /** @param f Film that we are encoding */ Encoder::Encoder (shared_ptr film, shared_ptr writer) @@ -65,14 +65,35 @@ Encoder::Encoder (shared_ptr film, shared_ptr writer) Encoder::~Encoder () { - terminate_threads (); + try { + terminate_threads (); + } catch (...) { + /* Destructors must not throw exceptions; anything bad + happening now is too late to worry about anyway, + I think. + */ + } } void Encoder::begin () { - if (!EncodeServerFinder::instance()->disabled ()) { - _server_found_connection = EncodeServerFinder::instance()->ServersListChanged.connect (boost::bind (&Encoder::servers_list_changed, this)); + weak_ptr wp = shared_from_this (); + _server_found_connection = EncodeServerFinder::instance()->ServersListChanged.connect ( + boost::bind (&Encoder::call_servers_list_changed, wp) + ); +} + +/* We don't want the servers-list-changed callback trying to do things + during destruction of Encoder, and I think this is the neatest way + to achieve that. +*/ +void +Encoder::call_servers_list_changed (weak_ptr encoder) +{ + shared_ptr e = encoder.lock (); + if (e) { + e->servers_list_changed (); } } @@ -143,6 +164,10 @@ Encoder::current_encoding_rate () const int Encoder::video_frames_enqueued () const { + if (!_last_player_video) { + return 0; + } + return _last_player_video->time().frames_floor (_film->video_frame_rate ()); } @@ -180,11 +205,13 @@ Encoder::encode (shared_ptr pv) boost::mutex::scoped_lock queue_lock (_queue_mutex); - /* Wait until the queue has gone down a bit */ - while (_queue.size() >= threads * 2) { - LOG_TIMING ("decoder-sleep queue=%1", _queue.size()); + /* Wait until the queue has gone down a bit. Allow one thing in the queue even + when there are no threads. + */ + while (_queue.size() >= (threads * 2) + 1) { + LOG_TIMING ("decoder-sleep queue=%1 threads=%2", _queue.size(), threads); _full_condition.wait (queue_lock); - LOG_TIMING ("decoder-wake queue=%1", _queue.size()); + LOG_TIMING ("decoder-wake queue=%1 threads=%2", _queue.size(), threads); } _writer->rethrow (); @@ -238,7 +265,11 @@ Encoder::terminate_threads () LOG_GENERAL ("Terminating thread %1 of %2", n + 1, _threads.size ()); (*i)->interrupt (); DCPOMATIC_ASSERT ((*i)->joinable ()); - (*i)->join (); + try { + (*i)->join (); + } catch (boost::thread_interrupted& e) { + /* This is to be expected */ + } delete *i; LOG_GENERAL_NC ("Thread terminated"); ++n; @@ -333,6 +364,10 @@ try _full_condition.notify_all (); } } +catch (boost::thread_interrupted& e) { + /* Ignore these and just stop the thread */ + _full_condition.notify_all (); +} catch (...) { store_current ();