From bd23f55d8cd73adda823d0a2fcabc129b8845a81 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 17 Aug 2020 07:58:04 +0000 Subject: [PATCH] Report more detailed errors when the butler dies. --- src/lib/butler.cc | 40 +++++++++++++++++++++++++++++++++++---- src/lib/butler.h | 21 ++++++++++++++++---- src/lib/ffmpeg_encoder.cc | 2 +- src/wx/film_viewer.cc | 5 ++++- 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/lib/butler.cc b/src/lib/butler.cc index ab3e9b94e..76193a1ae 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. @@ -30,6 +30,7 @@ #include using std::cout; +using std::exception; using std::pair; using std::make_pair; using std::string; @@ -208,6 +209,12 @@ try boost::mutex::scoped_lock lm (_mutex); _finished = true; _arrived.notify_all (); +} catch (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); @@ -222,7 +229,7 @@ Butler::get_video (Error* e) if (_suspended) { if (e) { - *e = AGAIN; + e->code = Error::AGAIN; } return make_pair(shared_ptr(), DCPTime()); } @@ -233,8 +240,9 @@ Butler::get_video (Error* e) } if (_video.empty()) { - if (e) { - *e = _died ? DIED : NONE; + if (e && _died) { + e->code = Error::DIED; + e->message = _died_message; } return make_pair(shared_ptr(), DCPTime()); } @@ -292,6 +300,13 @@ try LOG_TIMING("finish-prepare in %1", thread_id()); } } +catch (exception& e) +{ + store_current (); + boost::mutex::scoped_lock lm (_mutex); + _died = true; + _died_message = e.what(); +} catch (...) { store_current (); @@ -404,3 +419,20 @@ Butler::text (PlayerText pt, TextType type, optional track, DCPTim boost::mutex::scoped_lock lm2 (_buffers_mutex); _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); + } + + return ""; +} diff --git a/src/lib/butler.h b/src/lib/butler.h index 4d4fa4a09..a62eb0525 100644 --- a/src/lib/butler.h +++ b/src/lib/butler.h @@ -49,10 +49,22 @@ public: void seek (DCPTime position, bool accurate); - enum Error { - NONE, - AGAIN, - DIED + class Error { + public: + enum Code { + NONE, + AGAIN, + DIED + }; + + Error () + : code(NONE) + {} + + Code code; + std::string message; + + std::string summary () const; }; std::pair, DCPTime> get_video (Error* e = 0); @@ -99,6 +111,7 @@ private: int _suspended; bool _finished; bool _died; + std::string _died_message; bool _stop_thread; AudioMapping _audio_mapping; diff --git a/src/lib/ffmpeg_encoder.cc b/src/lib/ffmpeg_encoder.cc index 25ad4a54c..8ab56a592 100644 --- a/src/lib/ffmpeg_encoder.cc +++ b/src/lib/ffmpeg_encoder.cc @@ -155,7 +155,7 @@ FFmpegEncoder::go () Butler::Error e; pair, DCPTime> v = _butler->get_video (&e); if (!v.first) { - throw ProgrammingError(__FILE__, __LINE__, String::compose("butler returned no video; error was %1", static_cast(e))); + throw ProgrammingError(__FILE__, __LINE__, String::compose("butler returned no video; error was %1", e.summary())); } shared_ptr fe = encoder->get (v.first->eyes()); if (fe) { diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f68b21309..6ae582366 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -239,7 +239,10 @@ FilmViewer::get () do { Butler::Error e; _player_video = _butler->get_video (&e); - if (!_player_video.first && e == Butler::AGAIN) { + if (e.code == Butler::Error::DIED) { + LOG_ERROR ("Butler died with %1", e.message); + } + if (!_player_video.first && e.code == Butler::Error::Code::AGAIN) { signal_manager->when_idle (boost::bind(&FilmViewer::get, this)); return; } -- 2.30.2