From 07ea8ea982ca19ebbfcf21bb575e107fc0495588 Mon Sep 17 00:00:00 2001 From: Ronag Date: Sat, 27 Aug 2011 13:11:34 +0000 Subject: [PATCH] 2.0. stage: Changed error handling. 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 | 23 +++++++-- core/consumer/output.cpp | 51 ++++++++++++++++--- core/consumer/output.h | 2 +- core/video_channel.cpp | 18 ++++--- .../bluefish/consumer/bluefish_consumer.cpp | 21 +------- .../decklink/consumer/decklink_consumer.cpp | 21 +------- modules/decklink/interop/DeckLinkAPI_h.h | 2 +- modules/decklink/interop/DeckLinkAPI_i.c | 2 +- modules/ogl/consumer/ogl_consumer.cpp | 11 +--- shell/casparcg.config | 29 +++-------- 10 files changed, 85 insertions(+), 95 deletions(-) diff --git a/common/concurrency/com_context.h b/common/concurrency/com_context.h index 31ab5a162..b3b985ddf 100644 --- a/common/concurrency/com_context.h +++ b/common/concurrency/com_context.h @@ -3,6 +3,7 @@ #include "executor.h" #include "../log/log.h" +#include "../exception/exceptions.h" #define NOMINMAX #define WIN32_LEAN_AND_MEAN @@ -37,7 +38,7 @@ public: ::CoUninitialize(); }).timed_wait(boost::posix_time::milliseconds(500))) { - CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources"; + CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources."; } } @@ -51,11 +52,25 @@ public: }); } - T& operator*() const { return *instance_.get();} // noexcept + T& operator*() const + { + if(instance_ == nullptr) + BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context.")); + + return *instance_.get(); + } // noexcept - T* operator->() const { return instance_.get();} // noexcept + T* operator->() const + { + if(instance_ == nullptr) + BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context.")); + return instance_.get(); + } // noexcept - T* get() const { return instance_.get();} // noexcept + T* get() const + { + return instance_.get(); + } // noexcept operator bool() const {return get() != nullptr;} }; diff --git a/core/consumer/output.cpp b/core/consumer/output.cpp index dde9c009a..426013cac 100644 --- a/core/consumer/output.cpp +++ b/core/consumer/output.cpp @@ -45,7 +45,8 @@ struct output::implementation { typedef std::pair, safe_ptr> fill_and_key; - video_channel_context& channel_; + video_channel_context& channel_; + const std::function restart_channel_; std::map> consumers_; typedef std::map>::value_type layer_t; @@ -53,8 +54,11 @@ struct output::implementation high_prec_timer timer_; public: - implementation(video_channel_context& video_channel) - : channel_(video_channel){} + implementation(video_channel_context& video_channel, const std::function& restart_channel) + : channel_(video_channel) + , restart_channel_(restart_channel) + { + } void add(int index, safe_ptr&& consumer) { @@ -105,10 +109,41 @@ public: if(consumer->get_video_format_desc() != channel_.get_format_desc()) consumer->initialize(channel_.get_format_desc()); - if(consumer->send(frame)) - ++it; - else - consumers_.erase(it++); + try + { + if(consumer->send(frame)) + ++it; + else + consumers_.erase(it++); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(warning) << "Trying to restart consumer: " << consumer->print() << L"."; + try + { + consumer->initialize(channel_.get_format_desc()); + consumer->send(frame); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(warning) << "Consumer restart failed, trying to restart channel: " << consumer->print() << L"."; + + try + { + restart_channel_(); + consumer->initialize(channel_.get_format_desc()); + consumer->send(frame); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(error) << "Failed to recover consumer: " << consumer->print() << L". Removing it."; + consumers_.erase(it++); + } + } + } } } @@ -128,7 +163,7 @@ private: } }; -output::output(video_channel_context& video_channel) : impl_(new implementation(video_channel)){} +output::output(video_channel_context& video_channel, const std::function& restart_channel) : impl_(new implementation(video_channel, restart_channel)){} void output::add(int index, safe_ptr&& consumer){impl_->add(index, std::move(consumer));} void output::remove(int index){impl_->remove(index);} void output::execute(const safe_ptr& frame) {impl_->execute(frame); } diff --git a/core/consumer/output.h b/core/consumer/output.h index 7a41d5241..069a864be 100644 --- a/core/consumer/output.h +++ b/core/consumer/output.h @@ -32,7 +32,7 @@ class video_channel_context; class output : boost::noncopyable { public: - explicit output(video_channel_context& video_channel); + explicit output(video_channel_context& video_channel, const std::function& restart_channel); void add(int index, safe_ptr&& consumer); void remove(int index); diff --git a/core/video_channel.cpp b/core/video_channel.cpp index 267a821db..476a73eb3 100644 --- a/core/video_channel.cpp +++ b/core/video_channel.cpp @@ -59,7 +59,7 @@ public: implementation(int index, const video_format_desc& format_desc, ogl_device& ogl) : context_(index, ogl, format_desc) , diag_(diagnostics::create_graph(narrow(print()))) - , output_(new caspar::core::output(context_)) + , output_(new caspar::core::output(context_, [this]{restart();})) , mixer_(new caspar::core::mixer(context_)) , stage_(new caspar::core::stage(context_)) { @@ -118,16 +118,20 @@ public: { CASPAR_LOG_CURRENT_EXCEPTION(); CASPAR_LOG(error) << context_.print() << L" Unexpected exception. Clearing stage and freeing memory"; - - stage_->clear(); - context_.ogl().gc().wait(); - - mixer_ = nullptr; - mixer_.reset(new caspar::core::mixer(context_)); + restart(); } context_.execution().begin_invoke([this]{tick();}); } + + void restart() + { + stage_->clear(); + context_.ogl().gc().wait(); + + mixer_ = nullptr; + mixer_.reset(new caspar::core::mixer(context_)); + } std::wstring print() const { diff --git a/modules/bluefish/consumer/bluefish_consumer.cpp b/modules/bluefish/consumer/bluefish_consumer.cpp index ab73cac35..d04fc4351 100644 --- a/modules/bluefish/consumer/bluefish_consumer.cpp +++ b/modules/bluefish/consumer/bluefish_consumer.cpp @@ -319,14 +319,12 @@ struct bluefish_consumer_proxy : public core::frame_consumer const bool embedded_audio_; const bool key_only_; core::video_format_desc format_desc_; - size_t fail_count_; public: bluefish_consumer_proxy(size_t device_index, bool embedded_audio, bool key_only) : device_index_(device_index) , embedded_audio_(embedded_audio) , key_only_(key_only) - , fail_count_(0) { } @@ -338,24 +336,7 @@ public: virtual bool send(const safe_ptr& frame) { - if(!consumer_) - consumer_.reset(new bluefish_consumer(format_desc_, device_index_, embedded_audio_, key_only_)); - - try - { - consumer_->send(frame); - fail_count_ = 0; - } - catch(...) - { - consumer_.reset(); - - if(fail_count_++ > 3) - return false; // Outside didn't handle exception properly, just give up. - - throw; - } - + consumer_->send(frame); return true; } diff --git a/modules/decklink/consumer/decklink_consumer.cpp b/modules/decklink/consumer/decklink_consumer.cpp index d0949fd80..a68513157 100644 --- a/modules/decklink/consumer/decklink_consumer.cpp +++ b/modules/decklink/consumer/decklink_consumer.cpp @@ -412,13 +412,11 @@ struct decklink_consumer_proxy : public core::frame_consumer const configuration config_; com_context context_; core::video_format_desc format_desc_; - size_t fail_count_; public: decklink_consumer_proxy(const configuration& config) : config_(config) , context_(L"decklink_consumer[" + boost::lexical_cast(config.device_index) + L"]") - , fail_count_(0) { } @@ -439,24 +437,7 @@ public: virtual bool send(const safe_ptr& frame) { - if(!context_) - context_.reset([&]{return new decklink_consumer(config_, format_desc_);}); - - try - { - context_->send(frame); - fail_count_ = 0; - } - catch(...) - { - context_.reset(); - - if(fail_count_++ > 3) - return false; // Outside didn't handle exception properly, just give up. - - throw; - } - + context_->send(frame); return true; } diff --git a/modules/decklink/interop/DeckLinkAPI_h.h b/modules/decklink/interop/DeckLinkAPI_h.h index 2aefce8c5..0ce53ae02 100644 --- a/modules/decklink/interop/DeckLinkAPI_h.h +++ b/modules/decklink/interop/DeckLinkAPI_h.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Sun Aug 21 14:54:35 2011 +/* at Fri Aug 26 23:40:03 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/decklink/interop/DeckLinkAPI_i.c b/modules/decklink/interop/DeckLinkAPI_i.c index 3555647ec..60f49f045 100644 --- a/modules/decklink/interop/DeckLinkAPI_i.c +++ b/modules/decklink/interop/DeckLinkAPI_i.c @@ -6,7 +6,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Sun Aug 21 14:54:35 2011 +/* at Fri Aug 26 23:40:03 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/ogl/consumer/ogl_consumer.cpp b/modules/ogl/consumer/ogl_consumer.cpp index 98346a7d7..ab41584fc 100644 --- a/modules/ogl/consumer/ogl_consumer.cpp +++ b/modules/ogl/consumer/ogl_consumer.cpp @@ -441,16 +441,7 @@ public: virtual bool send(const safe_ptr& frame) { - try - { - consumer_->send(frame); - } - catch(...) - { - CASPAR_LOG_CURRENT_EXCEPTION() - return false; - } - + consumer_->send(frame); return true; } diff --git a/shell/casparcg.config b/shell/casparcg.config index 5730f9b0f..722dd55b4 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -1,7 +1,7 @@ - L:\casparcg\_media\ + C:\Lokala Filer\server\branches\2.0.0.2\bin\_media\ L:\casparcg\_log\ L:\casparcg\_data\ L:\casparcg\_templates\ @@ -32,32 +32,15 @@ - - 1080p5000 - - - 1 - true - true - true - - - 1 - true - - - - 1080p5000 + PAL - - 2 - true - true - + + 0 + - + 5250 -- 2.39.2