]> git.sesse.net Git - casparcg/commitdiff
2.0. stage: Changed error handling.
authorRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 27 Aug 2011 13:11:34 +0000 (13:11 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 27 Aug 2011 13:11:34 +0000 (13:11 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1301 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

common/concurrency/com_context.h
core/consumer/output.cpp
core/consumer/output.h
core/video_channel.cpp
modules/bluefish/consumer/bluefish_consumer.cpp
modules/decklink/consumer/decklink_consumer.cpp
modules/decklink/interop/DeckLinkAPI_h.h
modules/decklink/interop/DeckLinkAPI_i.c
modules/ogl/consumer/ogl_consumer.cpp
shell/casparcg.config

index 31ab5a1623b8845dc37a937aca256d6384b7865e..b3b985ddfc99ae28d415aeac9e8b88f433432511 100644 (file)
@@ -3,6 +3,7 @@
 #include "executor.h"\r
 \r
 #include "../log/log.h"\r
+#include "../exception/exceptions.h"\r
 \r
 #define NOMINMAX\r
 #define WIN32_LEAN_AND_MEAN\r
@@ -37,7 +38,7 @@ public:
                        ::CoUninitialize();\r
                }).timed_wait(boost::posix_time::milliseconds(500)))\r
                {\r
-                       CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources";\r
+                       CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources.";\r
                }\r
        }\r
        \r
@@ -51,11 +52,25 @@ public:
                });\r
        }\r
 \r
-       T& operator*() const { return *instance_.get();}  // noexcept\r
+       T& operator*() const \r
+       {\r
+               if(instance_ == nullptr)\r
+                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
+\r
+               return *instance_.get();\r
+       }  // noexcept\r
 \r
-       T* operator->() const { return instance_.get();}  // noexcept\r
+       T* operator->() const \r
+       {\r
+               if(instance_ == nullptr)\r
+                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
+               return instance_.get();\r
+       }  // noexcept\r
 \r
-       T* get() const { return instance_.get();}  // noexcept\r
+       T* get() const\r
+       {\r
+               return instance_.get();\r
+       }  // noexcept\r
 \r
        operator bool() const {return get() != nullptr;}\r
 };\r
index dde9c009aa9ab6189efe5129198ecf610fac2b2d..426013cac5e63790167c084bbfa36fac45b788ce 100644 (file)
@@ -45,7 +45,8 @@ struct output::implementation
 {      \r
        typedef std::pair<safe_ptr<read_frame>, safe_ptr<read_frame>> fill_and_key;\r
        \r
-       video_channel_context& channel_;\r
+       video_channel_context&          channel_;\r
+       const std::function<void()> restart_channel_;\r
 \r
        std::map<int, safe_ptr<frame_consumer>> consumers_;\r
        typedef std::map<int, safe_ptr<frame_consumer>>::value_type layer_t;\r
@@ -53,8 +54,11 @@ struct output::implementation
        high_prec_timer timer_;\r
                \r
 public:\r
-       implementation(video_channel_context& video_channel) \r
-               : channel_(video_channel){}     \r
+       implementation(video_channel_context& video_channel, const std::function<void()>& restart_channel) \r
+               : channel_(video_channel)\r
+               , restart_channel_(restart_channel)\r
+       {\r
+       }       \r
        \r
        void add(int index, safe_ptr<frame_consumer>&& consumer)\r
        {               \r
@@ -105,10 +109,41 @@ public:
                        if(consumer->get_video_format_desc() != channel_.get_format_desc())\r
                                consumer->initialize(channel_.get_format_desc());\r
 \r
-                       if(consumer->send(frame))\r
-                               ++it;\r
-                       else\r
-                               consumers_.erase(it++);\r
+                       try\r
+                       {\r
+                               if(consumer->send(frame))\r
+                                       ++it;\r
+                               else\r
+                                       consumers_.erase(it++);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                               CASPAR_LOG(warning) << "Trying to restart consumer: " << consumer->print() << L".";\r
+                               try\r
+                               {\r
+                                       consumer->initialize(channel_.get_format_desc());\r
+                                       consumer->send(frame);\r
+                               }\r
+                               catch(...)\r
+                               {       \r
+                                       CASPAR_LOG_CURRENT_EXCEPTION(); \r
+                                       CASPAR_LOG(warning) << "Consumer restart failed, trying to restart channel: " << consumer->print() << L".";     \r
+\r
+                                       try\r
+                                       {\r
+                                               restart_channel_();\r
+                                               consumer->initialize(channel_.get_format_desc());\r
+                                               consumer->send(frame);\r
+                                       }\r
+                                       catch(...)\r
+                                       {\r
+                                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                                               CASPAR_LOG(error) << "Failed to recover consumer: " << consumer->print() << L". Removing it.";\r
+                                               consumers_.erase(it++);\r
+                                       }\r
+                               }\r
+                       }\r
                }\r
        }\r
 \r
@@ -128,7 +163,7 @@ private:
        }\r
 };\r
 \r
-output::output(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
+output::output(video_channel_context& video_channel, const std::function<void()>& restart_channel) : impl_(new implementation(video_channel, restart_channel)){}\r
 void output::add(int index, safe_ptr<frame_consumer>&& consumer){impl_->add(index, std::move(consumer));}\r
 void output::remove(int index){impl_->remove(index);}\r
 void output::execute(const safe_ptr<read_frame>& frame) {impl_->execute(frame); }\r
index 7a41d52411017dde7240defd43c45c19be9e8dc1..069a864beb4a3177244d323f72963d70677a0d7e 100644 (file)
@@ -32,7 +32,7 @@ class video_channel_context;
 class output : boost::noncopyable\r
 {\r
 public:\r
-       explicit output(video_channel_context& video_channel);\r
+       explicit output(video_channel_context& video_channel, const std::function<void()>& restart_channel);\r
 \r
        void add(int index, safe_ptr<frame_consumer>&& consumer);\r
        void remove(int index);\r
index 267a821dbd50723cbc53edddbb2e18bdb2a5c2ae..476a73eb32190af8e0f2ba8954ebe2eb1a49829e 100644 (file)
@@ -59,7 +59,7 @@ public:
        implementation(int index, const video_format_desc& format_desc, ogl_device& ogl)  \r
                : context_(index, ogl, format_desc)\r
                , diag_(diagnostics::create_graph(narrow(print())))\r
-               , output_(new caspar::core::output(context_))\r
+               , output_(new caspar::core::output(context_, [this]{restart();}))\r
                , mixer_(new caspar::core::mixer(context_))\r
                , stage_(new caspar::core::stage(context_))     \r
        {\r
@@ -118,16 +118,20 @@ public:
                {\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                        CASPAR_LOG(error) << context_.print() << L" Unexpected exception. Clearing stage and freeing memory";\r
-\r
-                       stage_->clear();\r
-                       context_.ogl().gc().wait();\r
-\r
-                       mixer_ = nullptr;\r
-                       mixer_.reset(new caspar::core::mixer(context_));\r
+                       restart();\r
                }\r
 \r
                context_.execution().begin_invoke([this]{tick();});\r
        }\r
+\r
+       void restart()\r
+       {\r
+               stage_->clear();\r
+               context_.ogl().gc().wait();\r
+\r
+               mixer_ = nullptr;\r
+               mixer_.reset(new caspar::core::mixer(context_));\r
+       }\r
                \r
        std::wstring print() const\r
        {\r
index ab73cac358894d64ae3f9cf412d7e29f65185888..d04fc435135519a8bb5a273ae4f0bbf397b3ae6b 100644 (file)
@@ -319,14 +319,12 @@ struct bluefish_consumer_proxy : public core::frame_consumer
        const bool                                                      embedded_audio_;\r
        const bool                                                      key_only_;\r
        core::video_format_desc                         format_desc_;\r
-       size_t                                                          fail_count_;\r
 public:\r
 \r
        bluefish_consumer_proxy(size_t device_index, bool embedded_audio, bool key_only)\r
                : device_index_(device_index)\r
                , embedded_audio_(embedded_audio)\r
                , key_only_(key_only)\r
-               , fail_count_(0)\r
        {\r
        }\r
        \r
@@ -338,24 +336,7 @@ public:
        \r
        virtual bool send(const safe_ptr<core::read_frame>& frame)\r
        {\r
-               if(!consumer_)\r
-                       consumer_.reset(new bluefish_consumer(format_desc_, device_index_, embedded_audio_, key_only_));\r
-\r
-               try\r
-               {\r
-                       consumer_->send(frame);\r
-                       fail_count_ = 0;\r
-               }\r
-               catch(...)\r
-               {\r
-                       consumer_.reset();\r
-\r
-                       if(fail_count_++ > 3)\r
-                               return false;  // Outside didn't handle exception properly, just give up.\r
-\r
-                       throw;\r
-               }\r
-\r
+               consumer_->send(frame);\r
                return true;\r
        }\r
 \r
index d0949fd807a1ef4b43e5aa8650a32e0ca2ddd70c..a68513157bafad1383988aabfd2cc6e08b664be8 100644 (file)
@@ -412,13 +412,11 @@ struct decklink_consumer_proxy : public core::frame_consumer
        const configuration                             config_;\r
        com_context<decklink_consumer>  context_;\r
        core::video_format_desc                 format_desc_;\r
-       size_t                                                  fail_count_;\r
 public:\r
 \r
        decklink_consumer_proxy(const configuration& config)\r
                : config_(config)\r
                , context_(L"decklink_consumer[" + boost::lexical_cast<std::wstring>(config.device_index) + L"]")\r
-               , fail_count_(0)\r
        {\r
        }\r
 \r
@@ -439,24 +437,7 @@ public:
        \r
        virtual bool send(const safe_ptr<core::read_frame>& frame)\r
        {\r
-               if(!context_)\r
-                       context_.reset([&]{return new decklink_consumer(config_, format_desc_);});\r
-\r
-               try\r
-               {\r
-                       context_->send(frame);\r
-                       fail_count_ = 0;\r
-               }\r
-               catch(...)\r
-               {\r
-                       context_.reset();\r
-\r
-                       if(fail_count_++ > 3)\r
-                               return false;  // Outside didn't handle exception properly, just give up.\r
-                       \r
-                       throw;\r
-               }\r
-\r
+               context_->send(frame);\r
                return true;\r
        }\r
        \r
index 2aefce8c5e1c2ff17b831ee08994f40944c3b938..0ce53ae02463bb47b33484620e47137f0fc2fa09 100644 (file)
@@ -4,7 +4,7 @@
 \r
 \r
  /* File created by MIDL compiler version 7.00.0555 */\r
-/* at Sun Aug 21 14:54:35 2011\r
+/* at Fri Aug 26 23:40:03 2011\r
  */\r
 /* Compiler settings for interop\DeckLinkAPI.idl:\r
     Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
index 3555647ec3d09f51b6e25ca1f4d7842566a7521e..60f49f0451b3344c48c777dff7f1d370ad267aa8 100644 (file)
@@ -6,7 +6,7 @@
 \r
 \r
  /* File created by MIDL compiler version 7.00.0555 */\r
-/* at Sun Aug 21 14:54:35 2011\r
+/* at Fri Aug 26 23:40:03 2011\r
  */\r
 /* Compiler settings for interop\DeckLinkAPI.idl:\r
     Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
index 98346a7d7955ab68c2ace421f57ac7d81e2038ad..ab41584fc19a8e6b9069aefa36e27d21441c51f1 100644 (file)
@@ -441,16 +441,7 @@ public:
        \r
        virtual bool send(const safe_ptr<core::read_frame>& frame)\r
        {\r
-               try\r
-               {\r
-                       consumer_->send(frame);\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION()\r
-                       return false;\r
-               }\r
-\r
+               consumer_->send(frame);\r
                return true;\r
        }\r
        \r
index 5730f9b0fa377b9291dd7570a4708fbe9ce3ba43..722dd55b4191c43f636f8d0a96a765ef4f3ab988 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>\r
 <configuration>\r
   <paths>\r
-    <media-path>L:\casparcg\_media\</media-path>\r
+    <media-path>C:\Lokala Filer\server\branches\2.0.0.2\bin\_media\</media-path>\r
     <log-path>L:\casparcg\_log\</log-path>\r
     <data-path>L:\casparcg\_data\</data-path>\r
     <template-path>L:\casparcg\_templates\</template-path>\r
     </template-hosts>\r
     </producers>\r
     <channels>\r
-    <channel>\r
-      <video-mode>1080p5000</video-mode>\r
-      <consumers>\r
-        <decklink>\r
-          <device>1</device>\r
-          <embedded-audio>true</embedded-audio>\r
-          <external-key>true</external-key>\r
-          <key-only>true</key-only>\r
-        </decklink>\r
-        <screen>\r
-          <device>1</device>\r
-          <key-only>true</key-only>\r
-        </screen>\r
-      </consumers>\r
-    </channel>\r
       <channel>\r
-        <video-mode>1080p5000</video-mode>\r
+        <video-mode>PAL</video-mode>\r
         <consumers>\r
-          <decklink>\r
-            <device>2</device>\r
-            <embedded-audio>true</embedded-audio>\r
-            <external-key>true</external-key>\r
-          </decklink>\r
+          <screen>\r
+            <device>0</device>\r
+          </screen>\r
         </consumers>\r
       </channel>\r
-</channels>\r
+    </channels>\r
   <controllers>\r
     <tcp>\r
       <port>5250</port>\r