X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fbutler.cc;h=270abd2d6348dc32f6d7009cfde5683c3f4b8c91;hb=be2e6e017d853069f02a83f5fe67423235c3096c;hp=20180330e5f68d2a048402328ccc32d7da64fd7b;hpb=ea6b2dae46caa1da829fbf499e83cd6ae3b3773a;p=dcpomatic.git diff --git a/src/lib/butler.cc b/src/lib/butler.cc index 20180330e..270abd2d6 100644 --- a/src/lib/butler.cc +++ b/src/lib/butler.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2018 Carl Hetherington + Copyright (C) 2016-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -26,6 +26,7 @@ #include "cross.h" #include "compose.hpp" #include "exceptions.h" +#include "video_content.h" #include #include @@ -39,6 +40,9 @@ using boost::bind; using boost::optional; using boost::function; using namespace dcpomatic; +#if BOOST_VERSION >= 106100 +using namespace boost::placeholders; +#endif /** Minimum video readahead in frames */ #define MINIMUM_VIDEO_READAHEAD 10 @@ -55,14 +59,17 @@ using namespace dcpomatic; * @param fast Same as above for the `fast' flag. */ Butler::Butler ( + weak_ptr film, shared_ptr player, AudioMapping audio_mapping, int audio_channels, function pixel_format, + VideoRange video_range, bool aligned, bool fast ) - : _player (player) + : _film (film) + , _player (player) , _prepare_work (new boost::asio::io_service::work (_prepare_service)) , _pending_seek_accurate (false) , _suspended (0) @@ -73,6 +80,7 @@ Butler::Butler ( , _audio_channels (audio_channels) , _disable_audio (false) , _pixel_format (pixel_format) + , _video_range (video_range) , _aligned (aligned) , _fast (fast) { @@ -82,7 +90,7 @@ Butler::Butler ( /* The butler must hear about things first, otherwise it might not sort out suspensions in time for get_video() to be called in response to this signal. */ - _player_change_connection = _player->Change.connect (bind (&Butler::player_change, this, _1), boost::signals2::at_front); + _player_change_connection = _player->Change.connect (bind (&Butler::player_change, this, _1, _2), boost::signals2::at_front); _thread = boost::thread (bind(&Butler::thread, this)); #ifdef DCPOMATIC_LINUX pthread_setname_np (_thread.native_handle(), "butler"); @@ -101,6 +109,8 @@ Butler::Butler ( Butler::~Butler () { + boost::this_thread::disable_interruption dis; + { boost::mutex::scoped_lock lm (_mutex); _stop_thread = true; @@ -113,9 +123,7 @@ Butler::~Butler () _thread.interrupt (); try { _thread.join (); - } catch (...) { - - } + } catch (...) {} } /** Caller must hold a lock on _mutex */ @@ -208,6 +216,12 @@ try boost::mutex::scoped_lock lm (_mutex); _finished = true; _arrived.notify_all (); +} catch (std::exception& e) { + store_current (); + boost::mutex::scoped_lock lm (_mutex); + _died = true; + _died_message = e.what (); + _arrived.notify_all (); } catch (...) { store_current (); boost::mutex::scoped_lock lm (_mutex); @@ -226,7 +240,7 @@ Butler::get_video (bool blocking, Error* e) if (_suspended || (_video.empty() && !blocking)) { if (e) { - *e = AGAIN; + e->code = Error::AGAIN; } return make_pair(shared_ptr(), DCPTime()); } @@ -238,7 +252,14 @@ Butler::get_video (bool blocking, Error* e) if (_video.empty()) { if (e) { - *e = NONE; + if (_died) { + e->code = Error::DIED; + e->message = _died_message; + } else if (_finished) { + e->code = Error::FINISHED; + } else { + e->code = Error::NONE; + } } return make_pair(shared_ptr(), DCPTime()); } @@ -289,10 +310,17 @@ try /* If the weak_ptr cannot be locked the video obviously no longer requires any work */ if (video) { LOG_TIMING("start-prepare in %1", thread_id()); - video->prepare (_pixel_format, _aligned, _fast); + video->prepare (_pixel_format, _video_range, _aligned, _fast); LOG_TIMING("finish-prepare in %1", thread_id()); } } +catch (std::exception& e) +{ + store_current (); + boost::mutex::scoped_lock lm (_mutex); + _died = true; + _died_message = e.what (); +} catch (...) { store_current (); @@ -354,8 +382,18 @@ Butler::memory_used () const } void -Butler::player_change (ChangeType type) +Butler::player_change (ChangeType type, int property) { + if (property == VideoContentProperty::CROP) { + if (type == CHANGE_TYPE_DONE) { + shared_ptr film = _film.lock(); + if (film) { + _video.reset_metadata (film, _player->video_container_size()); + } + } + return; + } + boost::mutex::scoped_lock lm (_mutex); if (type == CHANGE_TYPE_PENDING) { @@ -400,3 +438,22 @@ Butler::text (PlayerText pt, TextType type, optional track, DCPTim _closed_caption.put (pt, *track, period); } + +string +Butler::Error::summary () const +{ + switch (code) + { + case Error::NONE: + return "No error registered"; + case Error::AGAIN: + return "Butler not ready"; + case Error::DIED: + return String::compose("Butler died (%1)", message); + case Error::FINISHED: + return "Butler finished"; + } + + return ""; +} +