]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Mayor flash producer readability and maintainability improvements.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 18 Dec 2010 22:47:57 +0000 (22:47 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 18 Dec 2010 22:47:57 +0000 (22:47 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@300 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

17 files changed:
common/concurrency/executor.h
core/processor/read_frame.cpp
core/processor/write_frame.cpp
core/producer/color/color_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/input.cpp
core/producer/ffmpeg/input.h
core/producer/flash/cg_producer.cpp
core/producer/flash/ct_producer.cpp
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/frame_producer_device.cpp
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
core/protocol/cii/CIIProtocolStrategy.cpp
core/protocol/media.cpp

index b922d54ade04353b550efdb02733eb56d3cc3ff9..3415ba003f2967e6d2d5b68c5c13e1c4fd617e48 100644 (file)
@@ -47,12 +47,12 @@ public:
                return is_running_;\r
        }\r
        \r
-       void stop(bool wait = true) // noexcept\r
+       void stop() // noexcept\r
        {\r
                is_running_ = false;    \r
                begin_invoke([]{}); // wake if sleeping\r
-               if(wait && boost::this_thread::get_id() != thread_.get_id())\r
-                       thread_.join();\r
+               assert(boost::this_thread::get_id() != thread_.get_id());\r
+               thread_.join();\r
        }\r
 \r
        void execute() // noexcept\r
index eefcee205c35f13b1abfbdaa477016ca9c30eb2b..d7c945fc3edcdc08d46fd0d11eef38dfa116388b 100644 (file)
@@ -14,7 +14,7 @@ struct read_frame::implementation : boost::noncopyable
 {\r
        implementation(size_t width, size_t height) : pbo_(width, height, GL_BGRA)\r
        {\r
-               CASPAR_LOG(trace) << "Allocated read_frame.";\r
+               CASPAR_LOG(trace) << "[read_frame] Allocated.";\r
        }                               \r
 \r
        const boost::iterator_range<const unsigned char*> pixel_data() const\r
index 3300d450e527c9796d3b4592034ee1ca526f48e3..7589cc0e7d95c29215b6addd42bb04917aba8168 100644 (file)
@@ -19,7 +19,7 @@ struct write_frame::implementation : boost::noncopyable
 {\r
        implementation(const pixel_format_desc& desc) : desc_(desc)\r
        {\r
-               CASPAR_LOG(trace) << "Allocated write_frame.";\r
+               CASPAR_LOG(trace) << "[write_frame] Allocated.";\r
 \r
                static GLenum mapping[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
                std::transform(desc_.planes.begin(), desc_.planes.end(), std::back_inserter(pbos_), [&](const pixel_format_desc::plane& plane)\r
index c41a307cdcbac9591903210fcc178f1971f60b29..35bb77677bf92bcb3e561c50d3b63715880e1ece 100644 (file)
@@ -83,7 +83,7 @@ public:
        \r
        std::wstring print() const\r
        {\r
-               return + L"color_producer. color: " + color_str_;\r
+               return + L"color[" + color_str_ + L"]";\r
        }\r
 \r
        safe_ptr<draw_frame> frame_;\r
index 2236f895bff0154331ac9cdc8de431d293c29b36..22675b1fee1664010206b379b7492105443be3fe 100644 (file)
@@ -52,7 +52,7 @@ struct ffmpeg_producer_impl
 {\r
 public:\r
        ffmpeg_producer_impl(const std::wstring& filename, const  std::vector<std::wstring>& params) : filename_(filename), last_frame_(transform_frame(draw_frame::empty())), underrun_count_(0),\r
-               input_(narrow(filename)), video_decoder_(input_.get_video_codec_context().get()), video_transformer_(input_.get_video_codec_context().get()), audio_decoder_(input_.get_audio_codec_context().get())\r
+               input_(filename), video_decoder_(input_.get_video_codec_context().get()), video_transformer_(input_.get_video_codec_context().get()), audio_decoder_(input_.get_audio_codec_context().get())\r
        {                               \r
                input_.set_loop(std::find(params.begin(), params.end(), L"LOOP") != params.end());\r
 \r
@@ -125,13 +125,13 @@ public:
                        if(ouput_channel_.empty() && video_packet.empty() && audio_packet.empty())\r
                        {\r
                                if(underrun_count_++ == 0)\r
-                                       CASPAR_LOG(warning) << "### File read underflow has STARTED.";\r
+                                       CASPAR_LOG(warning) << print() << "### Started File read underrun.";\r
 \r
                                return last_frame_;\r
                        }\r
                        else if(underrun_count_ > 0)\r
                        {\r
-                               CASPAR_LOG(trace) << "### File Read Underrun has ENDED with " << underrun_count_ << " ticks.";\r
+                               CASPAR_LOG(trace) << print() << "### Ended file read underrun with " << underrun_count_ << " ticks.";\r
                                underrun_count_ = 0;\r
                        }\r
                }\r
@@ -152,7 +152,7 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"ffmpeg_producer. filename " + filename_;\r
+               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
        }\r
 \r
        size_t                                                                  underrun_count_;\r
index 94d18cc22e312610a2f0e3e9beb6c233fd477e93..003a594e8f42db5caf833401fd0ab4772053893b 100644 (file)
@@ -34,19 +34,19 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
 {\r
        static const size_t BUFFER_SIZE = 2 << 25;\r
 \r
-       implementation(const std::string& filename) : video_s_index_(-1), audio_s_index_(-1), filename_(filename)\r
+       implementation(const std::wstring& filename) : video_s_index_(-1), audio_s_index_(-1), filename_(filename)\r
        {\r
                loop_ = false;  \r
                \r
                int errn;\r
                AVFormatContext* weak_format_context_;\r
-               if((errn = -av_open_input_file(&weak_format_context_, filename.c_str(), nullptr, 0, nullptr)) > 0)\r
+               if((errn = -av_open_input_file(&weak_format_context_, narrow(filename).c_str(), nullptr, 0, nullptr)) > 0)\r
                        BOOST_THROW_EXCEPTION(\r
                                file_read_error() << \r
                                msg_info("No format context found.") << \r
                                boost::errinfo_api_function("av_open_input_file") <<\r
                                boost::errinfo_errno(errn) <<\r
-                               boost::errinfo_file_name(filename));\r
+                               boost::errinfo_file_name(narrow(filename)));\r
 \r
                format_context_.reset(weak_format_context_, av_close_input_file);\r
                        \r
@@ -104,7 +104,7 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
        {       \r
                static tbb::atomic<size_t> instances(boost::initialized_value); // Dangling threads debug info.\r
 \r
-               CASPAR_LOG(info) << "Started ffmpeg_producer::read_file Thread for " << filename_.c_str() << " instances: " << ++instances;\r
+               CASPAR_LOG(info) << L"ffmpeg[" << boost::filesystem::wpath(filename_).filename().c_str() << L"] Started file buffer thread. Instances: " << ++instances;\r
                win32_exception::install_handler();\r
                \r
                try\r
@@ -153,7 +153,7 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
                \r
                is_running_ = false;\r
                \r
-               CASPAR_LOG(info) << " Ended ffmpeg_producer::read_file Thread for " << filename_.c_str() << " instances: " << --instances;\r
+               CASPAR_LOG(info) << L"ffmpeg[" << boost::filesystem::wpath(filename_).filename().c_str() << L"] Ended file buffer thread. Instances: " << --instances;\r
        }\r
 \r
        bool need_packet()\r
@@ -208,7 +208,7 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
 \r
        tbb::queuing_mutex                                      seek_mutex_;\r
 \r
-       const std::string                                       filename_;\r
+       const std::wstring                                      filename_;\r
 \r
        std::shared_ptr<AVCodecContext>         video_codec_context_;\r
 \r
@@ -229,7 +229,7 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
        tbb::atomic<bool> is_running_;\r
 };\r
 \r
-input::input(const std::string& filename) : impl_(new implementation(filename)){}\r
+input::input(const std::wstring& filename) : impl_(new implementation(filename)){}\r
 input::~input(){impl_->stop();}\r
 void input::set_loop(bool value){impl_->loop_ = value;}\r
 const std::shared_ptr<AVCodecContext>& input::get_video_codec_context() const{return impl_->video_codec_context_;}\r
index d610d9b52bb26a321e92488c364294deadd0d1b4..06b17be670c2b2aefbd790295d8e52c2df276309 100644 (file)
@@ -13,7 +13,7 @@ typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>>
 class input : boost::noncopyable\r
 {\r
 public:\r
-       input(const std::string& filename);\r
+       input(const std::wstring& filename);\r
        ~input();\r
        const std::shared_ptr<AVCodecContext>& get_video_codec_context() const;\r
        const std::shared_ptr<AVCodecContext>& get_audio_codec_context() const;\r
index 48ddb4d61257533a6375f5f90812639a9656d2ca..f85750c2a0fed9b1dc34f166c23b2e8864370433 100644 (file)
@@ -147,7 +147,7 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"cg_producer. back-end:" + flash_producer_->print();\r
+               return L"cg[" + flash_producer_->print() + L"]";\r
        }\r
 \r
        safe_ptr<flash_producer> flash_producer_;\r
index b089b868624d55eed56ceebaadcb535559d72439..e30329de92b34ab0222827c5ca0c5349e0d4dc83 100644 (file)
@@ -50,7 +50,7 @@ struct ct_producer : public cg_producer
 \r
        std::wstring print() const\r
        {\r
-               return L"ct_producer. filename: " + filename_;\r
+               return L"ct[" + filename_ + L"]";\r
        }\r
 \r
        bool initialized_;\r
index 349d53e169a8fe4bbda7b120c92dd031b5a02954..b6fd862f464478c6898bbd164aae18346436b89a 100644 (file)
 #include "../../server.h"\r
 #include "../../../common/concurrency/executor.h"\r
 #include "../../../common/concurrency/concurrent_queue.h"\r
-#include "../../../common/utility/scope_exit.h"\r
 \r
 #include "../../processor/draw_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 \r
-#include <boost/assign.hpp>\r
 #include <boost/filesystem.hpp>\r
 #include <boost/thread.hpp>\r
 \r
@@ -54,216 +52,181 @@ using namespace boost::assign;
 CComModule _AtlModule;\r
 extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule;\r
 \r
-struct flash_producer::implementation\r
-{      \r
-       implementation(flash_producer* self, const std::wstring& filename) \r
-               : flashax_container_(nullptr), filename_(filename), self_(self), executor_([=]{run();}), invalid_count_(0), last_frame_(draw_frame::empty())\r
-       {       \r
-               if(!boost::filesystem::exists(filename))\r
-                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));\r
-\r
-               frame_buffer_.set_capacity(3);\r
-       }\r
+class flash_renderer\r
+{\r
+public:\r
+       flash_renderer(const safe_ptr<frame_processor_device>& frame_processor, const std::wstring& filename) \r
+               : last_frame_(draw_frame::empty()), current_frame_(draw_frame::empty()), frame_processor_(frame_processor), filename_(filename),\r
+                       format_desc_(frame_processor->get_video_format_desc()), bmp_frame_(std::make_shared<bitmap>(format_desc_.width, format_desc_.height))\r
 \r
-       ~implementation() \r
        {\r
-               stop();\r
-       }\r
+               CASPAR_LOG(info) << print() << L" Started";\r
 \r
-       void start()\r
-       {               \r
-               try\r
-               {\r
-                       safe_ptr<draw_frame> frame = draw_frame::eof();\r
-                       while(frame_buffer_.try_pop(frame)){}\r
+               ::OleInitialize(nullptr);\r
 \r
-                       is_empty_ = true;\r
-                       executor_.stop(); // Restart if running\r
-                       executor_.start();\r
-                       executor_.invoke([=]()\r
-                       {\r
-                               if(FAILED(CComObject<FlashAxContainer>::CreateInstance(&flashax_container_)) || \r
-                                                       flashax_container_ == nullptr)\r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to create FlashAxContainer"));\r
+               CComObject<FlashAxContainer>* object;           \r
+               if(FAILED(CComObject<FlashAxContainer>::CreateInstance(&object)))\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to create FlashAxContainer"));\r
                \r
-                               flashax_container_->pflash_producer_ = self_;\r
-                               CComPtr<IShockwaveFlash> spFlash;\r
-\r
-                               if(FAILED(flashax_container_->CreateAxControl()))\r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Create FlashAxControl"));\r
-\r
-                               if(FAILED(flashax_container_->QueryControl(&spFlash)))\r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Query FlashAxControl"));\r
-                                                                                               \r
-                               if(FAILED(spFlash->put_Playing(true)) )\r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to start playing Flash"));\r
-\r
-                               if(FAILED(spFlash->put_Movie(CComBSTR(filename_.c_str()))))\r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Load Template Host"));\r
-                                               \r
-                               //Exact fit. Scale without respect to the aspect ratio.\r
-                               if(FAILED(spFlash->put_ScaleMode(2))) \r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Set Scale Mode"));\r
+               object->AddRef();\r
+               ax_.Attach(object);\r
+               \r
+               if(FAILED(ax_->CreateAxControl()))\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to Create FlashAxControl"));\r
+               \r
+               CComPtr<IShockwaveFlash> spFlash;\r
+               if(FAILED(ax_->QueryControl(&spFlash)))\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to Query FlashAxControl"));\r
                                                                                                \r
-                               // stop if failed\r
-                               if(FAILED(flashax_container_->SetFormat(frame_processor_->get_video_format_desc()))) \r
-                                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Set Format"));\r
-\r
-                               current_frame_ = nullptr; // Force re-render of current frame   \r
-                               last_frame_ = draw_frame::empty();\r
-                       });\r
-               }\r
-               catch(...)\r
-               {\r
-                       stop();\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                       throw;\r
-               }\r
+               if(FAILED(spFlash->put_Playing(true)) )\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to start playing Flash"));\r
+\r
+               if(FAILED(spFlash->put_Movie(CComBSTR(filename.c_str()))))\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to Load Template Host"));\r
+                                                               \r
+               if(FAILED(spFlash->put_ScaleMode(2)))  //Exact fit. Scale without respect to the aspect ratio.\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to Set Scale Mode"));\r
+                                                                                                               \r
+               if(FAILED(ax_->SetFormat(frame_processor_->get_video_format_desc())))  // stop if failed\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(bprint() + "Failed to Set Format"));\r
        }\r
 \r
-       void stop()\r
+       ~flash_renderer()\r
        {\r
-               is_empty_ = true;\r
-               if(executor_.is_running())\r
-               {\r
-                       safe_ptr<draw_frame> frame = draw_frame::eof();\r
-                       while(frame_buffer_.try_pop(frame)){}\r
-                       executor_.stop();\r
-               }\r
+               ax_->DestroyAxControl();\r
+               ax_.Release();\r
+               ::OleUninitialize();\r
+               CASPAR_LOG(info) << print() << L" Ended";\r
        }\r
 \r
        void param(const std::wstring& param) \r
-       {       \r
-               if(!executor_.is_running())\r
-                       start();\r
-\r
-               executor_.invoke([&]()\r
-               {                       \r
-                       for(size_t retries = 0; !flashax_container_->CallFunction(param); ++retries)\r
-                       {\r
-                               CASPAR_LOG(debug) << "Retrying. Count: " << retries;\r
-                               if(retries > 3)\r
-                                       BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(narrow(param)));\r
-                       }\r
-                       is_empty_ = false;      \r
-               });\r
-       }\r
-       \r
-       void run()\r
-       {\r
-               win32_exception::install_handler();\r
-               CASPAR_LOG(info) << L"started flash_producer Thread";\r
-\r
-               try\r
-               {\r
-                       ::OleInitialize(nullptr);\r
-                       CASPAR_SCOPE_EXIT(::OleUninitialize);\r
-\r
-                       CASPAR_SCOPE_EXIT([=]\r
-                       {\r
-                               if(flashax_container_)\r
-                               {\r
-                                       flashax_container_->DestroyAxControl();\r
-                                       flashax_container_->Release();\r
-                                       flashax_container_ = nullptr;\r
-                               }\r
-                       });\r
-                       \r
-                       while(executor_.is_running())\r
-                       {       \r
-                               if(!is_empty_)\r
-                               {\r
-                                       render();       \r
-                                       while(executor_.try_execute()){}\r
-                               }\r
-                               else                            \r
-                                       executor_.execute();                            \r
-                       }\r
-               }\r
-               catch(...)\r
+       {                       \r
+               for(size_t retries = 0; !ax_->CallFunction(param); ++retries)\r
                {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(debug) << print() << L" Retrying. Count: " << retries;\r
+                       if(retries > 3)\r
+                               BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(narrow(param)) << msg_info(narrow(print())));\r
                }\r
-               \r
-               frame_buffer_.try_push(draw_frame::eof()); // EOF\r
-               CASPAR_LOG(info) << L"Ended flash_producer Thread";\r
        }\r
-\r
+               \r
        void render()\r
-       {               \r
-               if(!is_empty_ || current_frame_ == nullptr)\r
+       {                \r
+               while(frame_buffer_.size() < 3)\r
                {\r
-                       bool is_progressive = format_desc_.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc_.fps/2 == 0);\r
+                       bool is_progressive = format_desc_.mode == video_mode::progressive || (ax_->GetFPS() - format_desc_.fps/2 == 0);\r
 \r
                        safe_ptr<draw_frame> frame = render_frame();\r
                        if(!is_progressive)\r
                                frame = composite_frame::interlace(frame, render_frame(), format_desc_.mode);\r
                        \r
-                       frame_buffer_.push(std::move(frame));\r
-                       is_empty_ = flashax_container_->IsEmpty();\r
+                       frame_buffer_.try_push(std::move(frame));\r
                }\r
        }\r
 \r
        safe_ptr<draw_frame> render_frame()\r
        {\r
-               if(!flashax_container_->IsReadyToRender())\r
-                       return draw_frame::empty();\r
-\r
-               flashax_container_->Tick();\r
-               invalid_count_ = !flashax_container_->InvalidRectangle() ? std::min(2, invalid_count_+1) : 0;\r
-               if(current_frame_ == nullptr || invalid_count_ < 2)\r
+               ax_->Tick();\r
+               \r
+               if(ax_->IsReadyToRender() && ax_->InvalidRectangle())\r
                {\r
                        std::fill_n(bmp_frame_->data(), bmp_frame_->size(), 0);                 \r
-                       flashax_container_->DrawControl(bmp_frame_->hdc());\r
-                       current_frame_ = bmp_frame_;\r
+                       ax_->DrawControl(bmp_frame_->hdc());\r
+               \r
+                       auto frame = frame_processor_->create_frame();\r
+                       std::copy(bmp_frame_->data(), bmp_frame_->data() + bmp_frame_->size(), frame->pixel_data().begin());\r
+                       current_frame_ = frame;\r
                }\r
-\r
-               auto frame = frame_processor_->create_frame(format_desc_.width, format_desc_.height);\r
-               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame->pixel_data().begin());\r
-               return frame;\r
+               return current_frame_;\r
        }\r
-\r
+       \r
        safe_ptr<draw_frame> receive()\r
        {\r
-               return frame_buffer_.try_pop(last_frame_) || !is_empty_ ? last_frame_ : draw_frame::empty();\r
+               frame_buffer_.try_pop(last_frame_);\r
+               return last_frame_;\r
        }\r
 \r
-       void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
-       {\r
-               frame_processor_ = frame_processor;\r
-               format_desc_ = frame_processor_->get_video_format_desc();\r
-               bmp_frame_ = std::make_shared<bitmap>(format_desc_.width, format_desc_.height);\r
-               start();\r
+       std::wstring print() const{ return L"flash[" + filename_ + L"]"; }\r
+       std::string bprint() const{ return narrow(L"flash[" + filename_ + L"]"); }\r
+\r
+private:\r
+       const std::wstring filename_;\r
+       const safe_ptr<frame_processor_device> frame_processor_;\r
+       const video_format_desc format_desc_;\r
+       const safe_ptr<bitmap> bmp_frame_;       \r
+\r
+       CComPtr<FlashAxContainer> ax_;\r
+       concurrent_bounded_queue_r<safe_ptr<draw_frame>> frame_buffer_; \r
+       safe_ptr<draw_frame> last_frame_;\r
+       safe_ptr<draw_frame> current_frame_;\r
+};\r
+\r
+struct flash_producer::implementation\r
+{      \r
+       implementation(const std::wstring& filename) : filename_(filename)\r
+       {       \r
+               if(!boost::filesystem::exists(filename))\r
+                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));\r
+\r
+               executor_.start();\r
        }\r
 \r
-       std::wstring print() const\r
+       ~implementation() \r
        {\r
-               return L"flash_producer. filename: " + filename_;\r
+               executor_.invoke([this]{renderer_.reset();});\r
        }\r
        \r
-       CComObject<flash::FlashAxContainer>* flashax_container_;\r
-\r
-       concurrent_bounded_queue_r<safe_ptr<draw_frame>> frame_buffer_;\r
+       void param(const std::wstring& param) \r
+       {       \r
+               if(!factory_)\r
+                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info(narrow(print()) + "Uninitialized."));\r
 \r
-       safe_ptr<draw_frame> last_frame_;\r
+               executor_.invoke([&]\r
+               {\r
+                       if(!renderer_)\r
+                               renderer_.reset(factory_());\r
+                       renderer_->param(param);\r
+               }, executor::high_priority);\r
+       }\r
+       \r
+       safe_ptr<draw_frame> receive()\r
+       {\r
+               auto frame = renderer_ ? renderer_->receive() : draw_frame::empty();\r
+               executor_.begin_invoke([this]\r
+               {\r
+                       try\r
+                       {\r
+                               renderer_->render();\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                               renderer_.reset();\r
+                       }\r
+               });\r
+               return frame;\r
+       }\r
 \r
-       bitmap_ptr current_frame_;\r
-       bitmap_ptr bmp_frame_;\r
+       void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
+       {\r
+               factory_ = [=]{return new flash_renderer(frame_processor, filename_);};\r
+               executor_.invoke([&]\r
+               {\r
+                       if(!renderer_)\r
+                               renderer_.reset(factory_());\r
+               });\r
+       }\r
 \r
+       std::wstring print() const{ return L"flash[" + filename_ + L"]"; }\r
+       \r
        std::wstring filename_;\r
-       flash_producer* self_;\r
+       std::function<flash_renderer*()> factory_;\r
 \r
-       tbb::atomic<bool> is_empty_;\r
+       std::unique_ptr<flash_renderer> renderer_;\r
        executor executor_;\r
-       int invalid_count_;\r
-\r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-\r
-       video_format_desc format_desc_;\r
 };\r
 \r
 flash_producer::flash_producer(flash_producer&& other) : impl_(std::move(other.impl_)){}\r
-flash_producer::flash_producer(const std::wstring& filename) : impl_(new implementation(this, filename)){}\r
+flash_producer::flash_producer(const std::wstring& filename) : impl_(new implementation(filename)){}\r
 safe_ptr<draw_frame> flash_producer::receive(){return impl_->receive();}\r
 void flash_producer::param(const std::wstring& param){impl_->param(param);}\r
 void flash_producer::initialize(const safe_ptr<frame_processor_device>& frame_processor) { impl_->initialize(frame_processor);}\r
@@ -280,20 +243,4 @@ std::wstring flash_producer::find_template(const std::wstring& template_name)
        return L"";\r
 }\r
 \r
-safe_ptr<flash_producer> create_flash_producer(const std::vector<std::wstring>& params)\r
-{\r
-       static const std::vector<std::wstring> extensions = list_of(L"swf");\r
-       std::wstring filename = server::media_folder() + L"\\" + params[0];\r
-       \r
-       auto ext = std::find_if(extensions.begin(), extensions.end(), [&](const std::wstring& ex) -> bool\r
-               {\r
-                       return boost::filesystem::is_regular_file(boost::filesystem::wpath(filename).replace_extension(ex));\r
-               });\r
-\r
-       if(ext == extensions.end())\r
-               BOOST_THROW_EXCEPTION(file_not_found() << msg_info(narrow(filename)));\r
-\r
-       return make_safe<flash_producer>(filename + L"." + *ext);\r
-}\r
-\r
 }}}
\ No newline at end of file
index 2fd6ecd84d7da36189804938f147376bd1d289aa..53ebe9fa46aa846cf0cfb37c5790dc21f975dadf 100644 (file)
@@ -55,6 +55,4 @@ private:
 \r
 };\r
 \r
-safe_ptr<flash_producer> create_flash_producer(const std::vector<std::wstring>& params);\r
-\r
 }}}
\ No newline at end of file
index 0f975bc9c4a9e94e96adf7d224f85272f623daca..85f95e05d6cd6df08d9d861aec7d15affc109f39 100644 (file)
@@ -57,7 +57,8 @@ struct frame_producer_device::implementation : boost::noncopyable
                producer->initialize(frame_processor_);\r
                executor_.begin_invoke([=]\r
                {\r
-                       layers_[render_layer].load(producer, option);\r
+                       auto it = layers_.insert(std::make_pair(render_layer, layer(render_layer))).first;\r
+                       it->second.load(producer, option);\r
                });\r
        }\r
                        \r
index 72952d7232a9f84bf61eadb1f3ac7840e228575e..b145b9b88096ad1bb363bc4ea2d878f03241c59a 100644 (file)
@@ -11,7 +11,7 @@ namespace caspar { namespace core {
 \r
 struct layer::implementation\r
 {              \r
-       implementation() : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()) {}\r
+       implementation(size_t index) : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()), index_(index) {}\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, load_option::type option)\r
        {                       \r
@@ -31,7 +31,7 @@ struct layer::implementation
                foreground_ = background_;\r
                background_ = frame_producer::empty();\r
                is_paused_ = false;\r
-               CASPAR_LOG(info) << L"Started: " << foreground_->print();\r
+               CASPAR_LOG(info) << L"layer[" << index_ << L"] Started: " << foreground_->print();\r
        }\r
 \r
        void pause()\r
@@ -63,10 +63,12 @@ struct layer::implementation
 \r
                        if(last_frame_ == draw_frame::eof())\r
                        {\r
-                               CASPAR_LOG(info) << L"Ended: " << foreground_->print();\r
+                               CASPAR_LOG(info) << L"layer[" << index_ << L"] Ended:" << foreground_->print();\r
                                auto following = foreground_->get_following_producer();\r
                                following->set_leading_producer(foreground_);\r
                                foreground_ = following;\r
+                               if(foreground_ != frame_producer::empty())\r
+                                       CASPAR_LOG(info) << L"layer[" << index_ << L"] Started:" << foreground_->print();\r
                                last_frame_ = receive();\r
                        }\r
                }\r
@@ -75,7 +77,7 @@ struct layer::implementation
                        try\r
                        {\r
                                CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               CASPAR_LOG(warning) << L"Removed " << foreground_->print() << L" from layer.";\r
+                               CASPAR_LOG(warning) << L"layer[" << index_ << L"] Error. Removed " << foreground_->print() << L" from layer.";\r
                                foreground_ = frame_producer::empty();\r
                                last_frame_ = draw_frame::empty();\r
                        }\r
@@ -89,9 +91,10 @@ struct layer::implementation
        safe_ptr<draw_frame>            last_frame_;\r
        safe_ptr<frame_producer>        foreground_;\r
        safe_ptr<frame_producer>        background_;\r
+       size_t                                          index_;\r
 };\r
 \r
-layer::layer() : impl_(new implementation()){}\r
+layer::layer(size_t index) : impl_(new implementation(index)){}\r
 layer::layer(layer&& other) : impl_(std::move(other.impl_)){other.impl_ = nullptr;}\r
 layer& layer::operator=(layer&& other)\r
 {\r
index 16e20822ce8d5d8911a5566c72a908bafc6537f6..6a021a97440a61612da64cd4d6b1ef5663415e5d 100644 (file)
@@ -19,7 +19,7 @@ struct load_option
 class layer : boost::noncopyable\r
 {\r
 public:\r
-       layer();\r
+       layer(size_t index = -1);\r
        layer(layer&& other);\r
        layer& operator=(layer&& other);\r
 \r
index 8951293399a93e87561e8b381e3746223b874c62..70385179cd8736c0a826fe03e21f276aad429cea 100644 (file)
@@ -146,7 +146,7 @@ struct transition_producer::implementation : boost::noncopyable
 \r
        std::wstring print() const\r
        {\r
-               return L"transition_producer. dest: " + (dest_producer_->print()) + L" src: " + (source_producer_->print());\r
+               return L"transition[" + (source_producer_->print()) + L" -> " + (dest_producer_->print()) + L"]";\r
        }\r
        \r
        safe_ptr<frame_producer>        source_producer_;\r
index 6d59984c438250f8f6639e05ed9bc04e9da8a5ca..9cd364b0634dd957d4250f34ff492221ac44feb1 100644 (file)
@@ -180,17 +180,15 @@ void CIIProtocolStrategy::WriteTemplateData(const std::wstring& templateName, co
                return;\r
        }\r
        \r
-       std::vector<std::wstring> params;\r
-       params.push_back(server::template_folder()+TEXT("CG.fth"));\r
-       auto pFP = flash::create_flash_producer(params);\r
+       auto producer = flash::flash_producer(server::template_folder()+TEXT("CG.fth"));\r
 \r
        std::wstringstream flashParam;\r
        flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
-       pFP->param(flashParam.str());\r
+       producer.param(flashParam.str());\r
 \r
        CASPAR_LOG(info) << "Saved an instance of " << templateName << TEXT(" as ") << titleName ;\r
 \r
-       PutPreparedTemplate(titleName, safe_ptr<frame_producer>(std::move(*pFP)));\r
+       PutPreparedTemplate(titleName, safe_ptr<frame_producer>(std::move(producer)));\r
        \r
 }\r
 \r
index 1e2a21d60d079699ed00d810626677c1a67cdc35..cb3c24ec9e3793ca852aac162f9cbdaa141d6d4b 100644 (file)
@@ -4,7 +4,6 @@
 \r
 #include "../producer/color/color_producer.h"\r
 #include "../producer/ffmpeg/ffmpeg_producer.h"\r
-#include "../producer/flash/flash_producer.h"\r
 #include "../producer/flash/ct_producer.h"\r
 #include "../producer/image/image_producer.h"\r
 //#include "../producer/image/image_scroll_producer.h"\r