From: ronag Date: Mon, 15 Aug 2011 08:48:51 +0000 (+0000) Subject: 2.0. flash_producer: Improved error handling. X-Git-Tag: 2.0.1~161 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=9647d954c83b0f6930e99fe5cc64b0f73f0d5385;p=casparcg 2.0. flash_producer: Improved error handling. decklink_consumer: Fixed exception_ptr data-race. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1179 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- diff --git a/modules/decklink/consumer/decklink_consumer.cpp b/modules/decklink/consumer/decklink_consumer.cpp index e8de3b3b8..b4c63c655 100644 --- a/modules/decklink/consumer/decklink_consumer.cpp +++ b/modules/decklink/consumer/decklink_consumer.cpp @@ -103,6 +103,7 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLink CComQIPtr configuration_; CComQIPtr keyer_; + tbb::spin_mutex exception_mutex_; std::exception_ptr exception_; tbb::atomic is_running_; @@ -296,6 +297,7 @@ public: } catch(...) { + tbb::spin_mutex::scoped_lock lock(exception_mutex_); exception_ = std::current_exception(); return E_FAIL; } @@ -329,6 +331,7 @@ public: } catch(...) { + tbb::spin_mutex::scoped_lock lock(exception_mutex_); exception_ = std::current_exception(); return E_FAIL; } @@ -358,8 +361,11 @@ public: void send(const safe_ptr& frame) { - if(exception_ != nullptr) - std::rethrow_exception(exception_); + { + tbb::spin_mutex::scoped_lock lock(exception_mutex_); + if(exception_ != nullptr) + std::rethrow_exception(exception_); + } if(!is_running_) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Is not running.")); diff --git a/modules/flash/producer/flash_producer.cpp b/modules/flash/producer/flash_producer.cpp index aa21c1232..f24d6ef2f 100644 --- a/modules/flash/producer/flash_producer.cpp +++ b/modules/flash/producer/flash_producer.cpp @@ -45,6 +45,8 @@ #include #include +#include + #include namespace caspar { @@ -262,6 +264,9 @@ struct flash_producer : public core::frame_producer com_context context_; + tbb::spin_mutex exception_mutex_; + std::exception_ptr exception_; + int width_; int height_; public: @@ -282,8 +287,10 @@ public: graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f)); frame_buffer_.set_capacity(1); - - initialize(); + + context_.reset([&]{return new flash_renderer(safe_ptr(graph_), frame_factory_, filename_, width_, height_);}); + while(frame_buffer_.try_push(core::basic_frame::empty())){} + render(); } ~flash_producer() @@ -294,7 +301,13 @@ public: // frame_producer virtual safe_ptr receive(int) - { + { + { + tbb::spin_mutex::scoped_lock lock(exception_mutex_); + if(exception_ != nullptr) + std::rethrow_exception(exception_); + } + graph_->set_value("output-buffer", static_cast(frame_buffer_.size())/static_cast(frame_buffer_.capacity())); auto frame = core::basic_frame::late(); @@ -311,11 +324,14 @@ public: virtual void param(const std::wstring& param) { + { + tbb::spin_mutex::scoped_lock lock(exception_mutex_); + if(exception_ != nullptr) + std::rethrow_exception(exception_); + } + context_.begin_invoke([=] { - if(!context_) - initialize(); - try { context_->param(param); @@ -328,33 +344,24 @@ public: { CASPAR_LOG_CURRENT_EXCEPTION(); context_.reset(nullptr); - frame_buffer_.push(core::basic_frame::empty()); + + tbb::spin_mutex::scoped_lock lock(exception_mutex_); + exception_ = std::current_exception(); } }); } virtual std::wstring print() const { - return L"flash[" + boost::filesystem::wpath(filename_).filename() + L", " + - boost::lexical_cast(fps_) + L"]"; + return L"flash[" + boost::filesystem::wpath(filename_).filename() + L", " + boost::lexical_cast(fps_) + L"]"; } // flash_producer - void initialize() - { - context_.reset([&]{return new flash_renderer(safe_ptr(graph_), frame_factory_, filename_, width_, height_);}); - while(frame_buffer_.try_push(core::basic_frame::empty())){} - render(context_.get()); - } - - void render(const flash_renderer* renderer) - { + void render() + { context_.begin_invoke([=] { - if(context_.get() != renderer) // Since initialize will start a new recursive call make sure the recursive calls are only for a specific instance. - return; - try { const auto& format_desc = frame_factory_->get_video_format_desc(); @@ -380,13 +387,15 @@ public: graph_->set_value("output-buffer", static_cast(frame_buffer_.size())/static_cast(frame_buffer_.capacity())); fps_.fetch_and_store(static_cast(context_->fps()*100.0)); - render(renderer); + render(); } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); context_.reset(nullptr); - frame_buffer_.push(core::basic_frame::empty()); + + tbb::spin_mutex::scoped_lock lock(exception_mutex_); + exception_ = std::current_exception(); } }); } diff --git a/shell/casparcg.config b/shell/casparcg.config index 01a5d11cf..2c911b64c 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -13,7 +13,7 @@ 6 - 2 + 3 true @@ -22,6 +22,12 @@ 1280 720 + + 720p5000 + cg.fth.18 + 1280 + 720 + 1080i5000 cg.fth.18