]> git.sesse.net Git - casparcg/blobdiff - core/producer/flash/flash_producer.cpp
2.0.0.2:
[casparcg] / core / producer / flash / flash_producer.cpp
index e6c3f5577975eeee212d25f062bcca3a57d15b03..ca777dff21ca1ee730c12f592a71903ab672f3db 100644 (file)
@@ -34,7 +34,7 @@
 #include "../../../common/concurrency/executor.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/draw_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 \r
 #include <boost/assign.hpp>\r
@@ -60,7 +60,7 @@ struct flash_producer::implementation
                : flashax_container_(nullptr), filename_(filename), self_(self), executor_([=]{run();}), invalid_count_(0)\r
        {       \r
                if(!boost::filesystem::exists(filename))\r
-                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(common::narrow(filename)));\r
+                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));\r
 \r
                frame_buffer_.set_capacity(3);          \r
        }\r
@@ -151,7 +151,7 @@ struct flash_producer::implementation
                        {\r
                                CASPAR_LOG(debug) << "Retrying. Count: " << retries;\r
                                if(retries > 3)\r
-                                       BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(common::narrow(param)));\r
+                                       BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(narrow(param)));\r
                        }\r
                        is_empty_ = false;      \r
                });\r
@@ -182,7 +182,7 @@ struct flash_producer::implementation
                                stop();\r
 \r
                                frame_buffer_.clear();\r
-                               frame_buffer_.try_push(nullptr); // EOF\r
+                               frame_buffer_.try_push(draw_frame::eof()); // EOF\r
                \r
                                current_frame_ = nullptr;\r
                        });\r
@@ -225,23 +225,18 @@ struct flash_producer::implementation
                        auto format_desc = frame_processor_->get_video_format_desc();\r
                        bool is_progressive = format_desc.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc.fps/2 == 0);\r
 \r
-                       frame_ptr result;\r
-\r
-                       if(is_progressive)                                                      \r
-                               result = do_render_frame();             \r
+                       std::shared_ptr<draw_frame> frame;\r
+                       if(is_progressive)\r
+                               frame = do_receive();\r
                        else\r
-                       {\r
-                               frame_ptr frame1 = do_render_frame();\r
-                               frame_ptr frame2 = do_render_frame();\r
-                               result = composite_frame::interlace(frame1, frame2, format_desc.mode);\r
-                       }\r
-\r
-                       frame_buffer_.push(result);\r
+                               frame = std::shared_ptr<composite_frame>(composite_frame::interlace(do_receive(), do_receive(), format_desc.mode));\r
+                       \r
+                       frame_buffer_.push(frame);\r
                        is_empty_ = flashax_container_->IsEmpty();\r
                }\r
        }\r
                \r
-       frame_ptr do_render_frame()\r
+       safe_ptr<draw_frame> do_receive()\r
        {\r
                auto format_desc = frame_processor_->get_video_format_desc();\r
 \r
@@ -249,39 +244,39 @@ struct flash_producer::implementation
                invalid_count_ = !flashax_container_->InvalidRectangle() ? std::min(2, invalid_count_+1) : 0;\r
                if(current_frame_ == nullptr || invalid_count_ < 2)\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
-                       memset(current_frame_->data(), 0, current_frame_->size());\r
-                       \r
-                       flashax_container_->DrawControl(current_frame_->hdc());\r
                }       \r
 \r
                auto frame = frame_processor_->create_frame(format_desc.width, format_desc.height);\r
-               memcpy(frame->data(), current_frame_->data(), current_frame_->size());  \r
-\r
+               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame->pixel_data().begin());\r
                return frame;\r
        }\r
                \r
-       frame_ptr render_frame()\r
-       {\r
-               if(!frame_buffer_.try_pop(last_frame_) && is_empty_)\r
-                       last_frame_ = frame::empty();\r
-               \r
-               return last_frame_;\r
+       safe_ptr<draw_frame> receive()\r
+       {               \r
+               return ((frame_buffer_.try_pop(last_frame_) || !is_empty_) && last_frame_) ? safe_ptr<draw_frame>(last_frame_) : draw_frame::empty();\r
        }\r
 \r
-       void initialize(const frame_processor_device_ptr& frame_processor)\r
+       void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
                auto format_desc = frame_processor_->get_video_format_desc();\r
                bmp_frame_ = std::make_shared<bitmap>(format_desc.width, format_desc.height);\r
                start(false);\r
        }\r
+\r
+       std::wstring print() const\r
+       {\r
+               return L"flash_producer. filename: " + filename_;\r
+       }\r
        \r
        CComObject<flash::FlashAxContainer>* flashax_container_;\r
                \r
-       tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<draw_frame>> frame_buffer_;\r
 \r
-       frame_ptr last_frame_;\r
+       std::shared_ptr<draw_frame> last_frame_;\r
 \r
        bitmap_ptr current_frame_;\r
        bitmap_ptr bmp_frame_;\r
@@ -290,16 +285,18 @@ struct flash_producer::implementation
        flash_producer* self_;\r
 \r
        tbb::atomic<bool> is_empty_;\r
-       common::executor executor_;\r
+       executor executor_;\r
        int invalid_count_;\r
 \r
-       frame_processor_device_ptr frame_processor_;\r
+       std::shared_ptr<frame_processor_device> frame_processor_;\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
-frame_ptr flash_producer::render_frame(){return impl_->render_frame();}\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 frame_processor_device_ptr& frame_processor) { impl_->initialize(frame_processor);}\r
+void flash_producer::initialize(const safe_ptr<frame_processor_device>& frame_processor) { impl_->initialize(frame_processor);}\r
+std::wstring flash_producer::print() const {return impl_->print();}\r
 \r
 std::wstring flash_producer::find_template(const std::wstring& template_name)\r
 {\r
@@ -312,7 +309,7 @@ std::wstring flash_producer::find_template(const std::wstring& template_name)
        return L"";\r
 }\r
 \r
-flash_producer_ptr create_flash_producer(const std::vector<std::wstring>& params)\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
@@ -323,9 +320,9 @@ flash_producer_ptr create_flash_producer(const std::vector<std::wstring>& params
                });\r
 \r
        if(ext == extensions.end())\r
-               return nullptr;\r
+               BOOST_THROW_EXCEPTION(file_not_found() << msg_info(narrow(filename)));\r
 \r
-       return std::make_shared<flash_producer>(filename + L"." + *ext);\r
+       return make_safe<flash_producer>(filename + L"." + *ext);\r
 }\r
 \r
 }}}
\ No newline at end of file