Report more detailed errors when the butler dies.
authorCarl Hetherington <cth@carlh.net>
Mon, 17 Aug 2020 07:58:04 +0000 (07:58 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 17 Aug 2020 11:17:24 +0000 (13:17 +0200)
src/lib/butler.cc
src/lib/butler.h
src/lib/ffmpeg_encoder.cc
src/wx/film_viewer.cc

index ab3e9b94ebf6221780619cdacbf7cf123b31550f..76193a1ae93f1920a506610d50babd7c231b0a5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2020 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -30,6 +30,7 @@
 #include <boost/shared_ptr.hpp>
 
 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<PlayerVideo>(), 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<PlayerVideo>(), 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<DCPTextTrack> 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 "";
+}
index 4d4fa4a0939d86186e54c2488e9478fa4f29baeb..a62eb0525f18fbc2f5c6d53709b4daf057d1d73e 100644 (file)
@@ -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<boost::shared_ptr<PlayerVideo>, 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;
index 25ad4a54c1b22e577d96d206be83720a807d9599..8ab56a592f122ee9ca8339cf77997c47ff8a42a4 100644 (file)
@@ -155,7 +155,7 @@ FFmpegEncoder::go ()
                        Butler::Error e;
                        pair<shared_ptr<PlayerVideo>, DCPTime> v = _butler->get_video (&e);
                        if (!v.first) {
-                               throw ProgrammingError(__FILE__, __LINE__, String::compose("butler returned no video; error was %1", static_cast<int>(e)));
+                               throw ProgrammingError(__FILE__, __LINE__, String::compose("butler returned no video; error was %1", e.summary()));
                        }
                        shared_ptr<FFmpegFileEncoder> fe = encoder->get (v.first->eyes());
                        if (fe) {
index f68b213091e7d26ab8f527552ba2081892bd09ef..6ae582366f37afb336c1fbe0b919441aa346eacf 100644 (file)
@@ -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;
                }