]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 31 Oct 2011 18:49:32 +0000 (18:49 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 31 Oct 2011 18:49:32 +0000 (18:49 +0000)
core/consumer/output.cpp
modules/flash/producer/flash_producer.cpp
modules/oal/consumer/oal_consumer.cpp
protocol/amcp/AMCPProtocolStrategy.cpp
shell/casparcg.config

index db146f9cee84db0d1a03c866722939aa1d1a510e..d59d2abb291ae686e26518eb619825027c990ed3 100644 (file)
@@ -52,6 +52,8 @@ struct output::implementation
 \r
        critical_section                                mutex_;\r
        call<output::source_element_t>  output_;\r
+\r
+       boost::circular_buffer<safe_ptr<read_frame>> frames_;\r
                \r
 public:\r
        implementation(output::source_t& source, const video_format_desc& format_desc) \r
@@ -90,6 +92,21 @@ public:
                        }\r
                }\r
        }\r
+\r
+       std::pair<size_t, size_t> minmax_buffer_depth() const\r
+       {               \r
+               if(consumers_.empty())\r
+                       return std::make_pair(0, 0);\r
+               std::vector<size_t> buffer_depths;\r
+               std::transform(consumers_.begin(), consumers_.end(), std::back_inserter(buffer_depths), [](const decltype(*consumers_.begin())& pair)\r
+               {\r
+                       return pair.second->buffer_depth();\r
+               });\r
+               std::sort(buffer_depths.begin(), buffer_depths.end());\r
+               auto min = buffer_depths.front();\r
+               auto max = buffer_depths.back();\r
+               return std::make_pair(min, max);\r
+       }\r
                                                \r
        void execute(const output::source_element_t& element)\r
        {       \r
@@ -97,19 +114,29 @@ public:
 \r
                {\r
                        critical_section::scoped_lock lock(mutex_);             \r
-\r
+                       \r
                        if(!has_synchronization_clock() || frame->image_size() != format_desc_.size)\r
                        {               \r
                                scoped_oversubcription_token oversubscribe;\r
                                timer_.tick(1.0/format_desc_.fps);\r
                        }\r
-       \r
+                               \r
+                       auto minmax = minmax_buffer_depth();\r
+\r
+                       frames_.set_capacity(minmax.second - minmax.first + 1);\r
+                       frames_.push_back(frame);\r
+\r
+                       if(!frames_.full())\r
+                               return;\r
+\r
                        std::vector<int> removables;            \r
                        Concurrency::parallel_for_each(consumers_.begin(), consumers_.end(), [&](const decltype(*consumers_.begin())& pair)\r
                        {               \r
                                try\r
                                {\r
-                                       if(!pair.second->send(frame))\r
+                                       auto consumer = pair.second;\r
+\r
+                                       if(!consumer->send(frames_.at(consumer->buffer_depth()-minmax.first)))\r
                                                removables.push_back(pair.first);\r
                                }\r
                                catch(...)\r
index 9bfb82af182884e38d502b6f4a12ab2e5227ea1d..d9b6c56f341512d2ed327c55698e2bbdaaa56db7 100644 (file)
@@ -128,42 +128,18 @@ template_host get_template_host(const core::video_format_desc& desc)
        return template_host;\r
 }\r
 \r
-class flash_renderer\r
-{      \r
-       const std::wstring                                                              filename_;\r
-\r
-       const safe_ptr<core::frame_factory>                             frame_factory_;\r
-       safe_ptr<diagnostics::graph>                                    graph_;\r
-\r
-       high_prec_timer                                                                 timer_;\r
-       safe_ptr<core::basic_frame>                                             head_;\r
-       bitmap                                                                                  bmp_;\r
-\r
-       const size_t                                                                    width_;\r
-       const size_t                                                                    height_;\r
-                       \r
-       boost::timer                                                                    frame_timer_;\r
-       boost::timer                                                                    tick_timer_;\r
-\r
+class flash_player\r
+{\r
+       const std::wstring      filename_;\r
+       const size_t            width_;\r
+       const size_t            height_;\r
        CComObject<caspar::flash::FlashAxContainer>*    ax_;\r
-       \r
 public:\r
-       flash_renderer(const safe_ptr<diagnostics::graph>& graph, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int width, int height) \r
+       flash_player(const std::wstring& filename, size_t width, size_t height)\r
                : filename_(filename)\r
-               , frame_factory_(frame_factory)\r
-               , graph_(graph)\r
-               , ax_(nullptr)\r
-               , head_(core::basic_frame::empty())\r
-               , bmp_(width, height)\r
                , width_(width)\r
                , height_(height)\r
        {               \r
-               graph_->add_guide("frame-time", 0.5f);\r
-               graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
-               graph_->add_guide("tick-time", 0.5);\r
-               graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));\r
-               graph_->set_color("param", diagnostics::color(1.0f, 0.5f, 0.0f));               \r
-               \r
                if(FAILED(CComObject<caspar::flash::FlashAxContainer>::CreateInstance(&ax_)))\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to create FlashAxContainer"));\r
                \r
@@ -185,25 +161,99 @@ public:
                if(FAILED(spFlash->put_ScaleMode(2)))  //Exact fit. Scale without respect to the aspect ratio.\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to Set Scale Mode"));\r
                                                \r
-               ax_->SetSize(width_, height_);          \r
-       \r
-               CASPAR_LOG(info) << print() << L" Thread started.";\r
-               CASPAR_LOG(info) << print() << L" Successfully initialized with template-host: " << filename << L" width: " << width_ << L" height: " << height_ << L".";\r
+               ax_->SetSize(width, height);    \r
+\r
+               CASPAR_LOG(info) << "Initialized" << print();\r
        }\r
 \r
-       ~flash_renderer()\r
-       {               \r
+       ~flash_player()\r
+       {\r
                if(ax_)\r
                {\r
                        ax_->DestroyAxControl();\r
                        ax_->Release();\r
                }\r
-               CASPAR_LOG(info) << print() << L" Thread ended.";\r
+               CASPAR_LOG(info) << "Uninitialized " << print();\r
+       }\r
+\r
+       bool is_empty() const\r
+       {\r
+               return ax_->IsEmpty();\r
        }\r
+\r
+       void tick()\r
+       {\r
+               ax_->Tick();\r
+       }\r
+\r
+       bool invalid_rect() const\r
+       {\r
+               return ax_->InvalidRect();\r
+       }\r
+\r
+       bool draw_control(HDC targetDC)\r
+       {\r
+               return ax_->DrawControl(targetDC);\r
+       }\r
+\r
+       bool flash_call(const std::wstring& param)\r
+       {\r
+               return ax_->FlashCall(param);\r
+       }\r
+\r
+       double fps() const\r
+       {\r
+               return ax_->GetFPS();\r
+       }\r
+\r
+       std::wstring print()\r
+       {\r
+               return L"flash-player[" + boost::filesystem::wpath(filename_).filename() + L"|" + boost::lexical_cast<std::wstring>(width_) + L"|" + boost::lexical_cast<std::wstring>(height_) + L"]";         \r
+       }\r
+};\r
+\r
+class flash_renderer\r
+{      \r
+       const std::wstring                                                              filename_;\r
+\r
+       const safe_ptr<core::frame_factory>                             frame_factory_;\r
+       safe_ptr<diagnostics::graph>                                    graph_;\r
+\r
+       high_prec_timer                                                                 timer_;\r
+       safe_ptr<core::basic_frame>                                             head_;\r
+       bitmap                                                                                  bmp_;\r
+\r
+       const size_t                                                                    width_;\r
+       const size_t                                                                    height_;\r
+                       \r
+       boost::timer                                                                    frame_timer_;\r
+       boost::timer                                                                    tick_timer_;\r
+\r
+       std::unique_ptr<flash_player>                                   player_;\r
        \r
+public:\r
+       flash_renderer(const safe_ptr<diagnostics::graph>& graph, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int width, int height) \r
+               : filename_(filename)\r
+               , frame_factory_(frame_factory)\r
+               , graph_(graph)\r
+               , head_(core::basic_frame::empty())\r
+               , bmp_(width, height)\r
+               , width_(width)\r
+               , height_(height)\r
+       {               \r
+               graph_->add_guide("frame-time", 0.5f);\r
+               graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
+               graph_->add_guide("tick-time", 0.5);\r
+               graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));\r
+               graph_->set_color("param", diagnostics::color(1.0f, 0.5f, 0.0f));               \r
+       }\r
+               \r
        bool param(const std::wstring& param)\r
        {               \r
-               bool success = ax_->FlashCall(param); \r
+               if(!player_)\r
+                       player_.reset(new flash_player(filename_, width_, height_));\r
+\r
+               bool success = player_->flash_call(param); \r
                if(!success)\r
                        CASPAR_LOG(warning) << print() << L" Flash call failed:" << param;//BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Flash function call failed.") << arg_name_info("param") << arg_value_info(narrow(param)));\r
                else\r
@@ -213,13 +263,19 @@ public:
        \r
        safe_ptr<core::basic_frame> operator()()\r
        {\r
-               const float frame_time = 1.0f/ax_->GetFPS();\r
+               if(player_ && player_->is_empty())\r
+                       player_.reset();\r
+\r
+               if(!player_)\r
+               {\r
+                       graph_->update_value("tick-time", 0.0);\r
+                       return core::basic_frame::empty();      \r
+               }\r
+\r
+               const float frame_time = 1.0f/player_->fps();\r
 \r
                graph_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()/frame_time)*0.5f);\r
                tick_timer_.restart();\r
-\r
-               if(ax_->IsEmpty())\r
-                       return core::basic_frame::empty();              \r
                \r
                Concurrency::scoped_oversubcription_token oversubscribe;\r
                timer_.tick(frame_time); // This will block the thread.\r
@@ -227,11 +283,11 @@ public:
                        \r
                frame_timer_.restart();\r
 \r
-               ax_->Tick();\r
-               if(ax_->InvalidRect())\r
+               player_->tick();\r
+               if(player_->invalid_rect())\r
                {                       \r
                        fast_memclr(bmp_.data(), width_*height_*4);\r
-                       ax_->DrawControl(bmp_);\r
+                       player_->draw_control(bmp_);\r
                \r
                        auto frame = frame_factory_->create_frame(this, width_, height_);\r
                        fast_memcpy(frame->image_data().begin(), bmp_.data(), width_*height_*4);\r
@@ -245,7 +301,7 @@ public:
 \r
        double fps() const\r
        {\r
-               return ax_->GetFPS();   \r
+               return player_ ? player_->fps() : 0.0;  \r
        }\r
        \r
        std::wstring print()\r
index 72b065f477963a7512b2fea12e806327db67c526..afffc26e108ddda9cdcbdbc615621ae10500d173 100644 (file)
@@ -113,7 +113,7 @@ public:
        \r
        virtual size_t buffer_depth() const\r
        {\r
-               return 2;\r
+               return 3;\r
        }\r
 \r
        virtual std::wstring print() const\r
index fdd685875b85f6ac0df9eb63a105ad0220c5a8de..03b32196f6fea8bf36ff887e37d9f0d6c16c9146 100644 (file)
@@ -168,7 +168,7 @@ AMCPCommandPtr AMCPProtocolStrategy::InterpretCommandString(const std::wstring&
        AMCPCommandPtr pCommand;\r
        MessageParserState state = New;\r
 \r
-       CASPAR_LOG(trace) << message;\r
+       CASPAR_LOG(info) << message;\r
 \r
        std::size_t tokensInMessage = TokenizeMessage(message, &tokens);\r
 \r
index 0a758b24c34c3aad542efa875234e6818f7be9e9..bd9c1a3298ede3447dd102a182151e91a152ec05 100644 (file)
     </template-hosts>\r
   </producers>\r
   <channels>\r
-    <channel>\r
-      <video-mode>PAL</video-mode>\r
-      <consumers>\r
-        <bluefish>\r
-          <device>1</device>\r
-          <embedded-audio>true</embedded-audio>\r
-        </bluefish>\r
-      </consumers>\r
-    </channel>\r
     <channel>\r
       <video-mode>PAL</video-mode>\r
       <consumers>\r
           <device>1</device>\r
         </screen>\r
         <system-audio></system-audio>\r
+        <bluefish>\r
+          <device>1</device>\r
+          <embedded-audio>true</embedded-audio>\r
+        </bluefish>\r
       </consumers>\r
     </channel>\r
   </channels>\r