]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/producer/decklink_producer.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / modules / decklink / producer / decklink_producer.cpp
index 1db16f3fde52fd2a4cd0ced8f90abcd5405b7d1b..89aed0f030f37274b4a6912221c1a1f284fc2f8a 100644 (file)
@@ -35,9 +35,9 @@
 #include <common/diagnostics/graph.h>\r
 #include <common/except.h>\r
 #include <common/log.h>\r
-#include <common/utility/param.h>\r
+#include <common/param.h>\r
 \r
-#include <core/mixer/gpu/write_frame.h>\r
+#include <core/frame/write_frame.h>\r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/frame_factory.h>\r
 \r
@@ -78,41 +78,45 @@ namespace caspar { namespace decklink {
                \r
 class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback\r
 {      \r
-       CComPtr<IDeckLink>                                                                                      decklink_;\r
-       CComQIPtr<IDeckLinkInput>                                                                       input_;\r
-       \r
-       const std::wstring                                                                                      model_name_;\r
-       const core::video_format_desc                                                           format_desc_;\r
-       const size_t                                                                                            device_index_;\r
-\r
-       safe_ptr<diagnostics::graph>                                                            graph_;\r
-       boost::timer                                                                                            tick_timer_;\r
-       boost::timer                                                                                            frame_timer_;\r
-               \r
-       tbb::atomic<int>                                                                                        flags_;\r
-       safe_ptr<core::frame_factory>                                                           frame_factory_;\r
-       std::vector<int>                                                                                        audio_cadence_;\r
+       spl::shared_ptr<diagnostics::graph>             graph_;\r
+       boost::timer                                                    tick_timer_;\r
+       boost::timer                                                    frame_timer_;\r
 \r
-       tbb::concurrent_bounded_queue<safe_ptr<core::draw_frame>>       frame_buffer_;\r
+       CComPtr<IDeckLink>                                              decklink_;\r
+       CComQIPtr<IDeckLinkInput>                               input_;\r
+       CComQIPtr<IDeckLinkAttributes >                 attributes_;\r
+       \r
+       const std::wstring                                              model_name_;\r
+       const size_t                                                    device_index_;\r
+       const std::wstring                                              filter_;\r
+       \r
+       core::video_format_desc                                 format_desc_;\r
+       std::vector<int>                                                audio_cadence_;\r
+       boost::circular_buffer<size_t>                  sync_buffer_;\r
+       ffmpeg::frame_muxer                                             muxer_;\r
+                       \r
+       tbb::atomic<int>                                                flags_;\r
+       spl::shared_ptr<core::frame_factory>    frame_factory_;\r
 \r
-       std::exception_ptr                                                                                      exception_;\r
-               \r
-       ffmpeg::frame_muxer                                                                                     muxer_;\r
+       tbb::concurrent_bounded_queue<\r
+               spl::shared_ptr<core::draw_frame>>      frame_buffer_;\r
 \r
-       boost::circular_buffer<size_t>                                                          sync_buffer_;\r
+       std::exception_ptr                                              exception_;             \r
 \r
 public:\r
-       decklink_producer(const core::video_format_desc& format_desc, size_t device_index, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
+       decklink_producer(const core::video_format_desc& format_desc, size_t device_index, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
                : decklink_(get_device(device_index))\r
                , input_(decklink_)\r
+               , attributes_(decklink_)\r
                , model_name_(get_model_name(decklink_))\r
-               , format_desc_(format_desc)\r
                , device_index_(device_index)\r
-               , frame_factory_(frame_factory)\r
-               , audio_cadence_(frame_factory->get_video_format_desc().audio_cadence)\r
+               , filter_(filter)\r
+               , format_desc_(format_desc)\r
+               , audio_cadence_(format_desc.audio_cadence)\r
                , muxer_(format_desc.fps, frame_factory, filter)\r
                , sync_buffer_(format_desc.audio_cadence.size())\r
-       {               \r
+               , frame_factory_(frame_factory)\r
+       {       \r
                flags_ = 0;\r
                frame_buffer_.set_capacity(2);\r
                \r
@@ -184,7 +188,7 @@ public:
                        if(FAILED(video->GetBytes(&bytes)) || !bytes)\r
                                return S_OK;\r
                        \r
-                       safe_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free);     \r
+                       spl::shared_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free);      \r
                        avcodec_get_frame_defaults(av_frame.get());\r
                                                \r
                        av_frame->data[0]                       = reinterpret_cast<uint8_t*>(bytes);\r
@@ -226,7 +230,7 @@ public:
                        \r
                        for(auto frame = muxer_.poll(); frame; frame = muxer_.poll())\r
                        {\r
-                               if(!frame_buffer_.try_push(make_safe_ptr(frame)))\r
+                               if(!frame_buffer_.try_push(spl::make_shared_ptr(frame)))\r
                                        graph_->set_tag("dropped-frame");\r
                        }\r
 \r
@@ -243,14 +247,14 @@ public:
                return S_OK;\r
        }\r
        \r
-       safe_ptr<core::draw_frame> get_frame(int flags)\r
+       spl::shared_ptr<core::draw_frame> get_frame(int flags)\r
        {\r
                if(exception_ != nullptr)\r
                        std::rethrow_exception(exception_);\r
 \r
                flags_ = flags;\r
 \r
-               safe_ptr<core::draw_frame> frame = core::draw_frame::late();\r
+               spl::shared_ptr<core::draw_frame> frame = core::draw_frame::late();\r
                if(!frame_buffer_.try_pop(frame))\r
                        graph_->set_tag("late-frame");\r
                graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity()));      \r
@@ -259,21 +263,21 @@ public:
        \r
        std::wstring print() const\r
        {\r
-               return model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
+               return model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"|" + format_desc_.name + L"]";\r
        }\r
 };\r
        \r
 class decklink_producer_proxy : public core::frame_producer\r
 {              \r
-       safe_ptr<core::draw_frame>                      last_frame_;\r
        std::unique_ptr<decklink_producer>      producer_;\r
        const uint32_t                                          length_;\r
+       spl::shared_ptr<core::draw_frame>       last_frame_;\r
        executor                                                        executor_;\r
 public:\r
-       explicit decklink_producer_proxy(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str, uint32_t length)\r
+       explicit decklink_producer_proxy(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str, uint32_t length)\r
                : executor_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
-               , last_frame_(core::draw_frame::empty())\r
                , length_(length)\r
+               , last_frame_(core::draw_frame::empty())\r
        {\r
                executor_.invoke([=]\r
                {\r
@@ -293,43 +297,53 @@ public:
        \r
        // frame_producer\r
                                \r
-       virtual safe_ptr<core::draw_frame> receive(int flags) override\r
+       virtual spl::shared_ptr<core::draw_frame> receive(int flags) override\r
        {\r
                auto frame = producer_->get_frame(flags);\r
+\r
                if(frame != core::draw_frame::late())\r
                        last_frame_ = frame;\r
+\r
                return frame;\r
        }\r
 \r
-       virtual safe_ptr<core::draw_frame> last_frame() const override\r
+       virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
        {\r
-               return last_frame_;\r
+               return core::draw_frame::still(last_frame_);\r
        }\r
-       \r
+               \r
        virtual uint32_t nb_frames() const override\r
        {\r
                return length_;\r
        }\r
        \r
-       std::wstring print() const override\r
+       virtual std::wstring print() const override\r
        {\r
                return producer_->print();\r
        }\r
+       \r
+       virtual std::wstring name() const override\r
+       {\r
+               return L"decklink";\r
+       }\r
 \r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
-               info.add(L"type", L"decklink-producer");\r
+               info.add(L"type", L"decklink");\r
                return info;\r
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty() || !boost::iequals(params[0], "decklink"))\r
                return core::frame_producer::empty();\r
 \r
-       auto device_index       = get_param(L"DEVICE", params, 1);\r
+       auto device_index       = get_param(L"DEVICE", params, -1);\r
+       if(device_index == -1)\r
+               device_index = boost::lexical_cast<int>(params.at(1));\r
+\r
        auto filter_str         = get_param(L"FILTER", params);         \r
        auto length                     = get_param(L"LENGTH", params, std::numeric_limits<uint32_t>::max());   \r
        auto format_desc        = core::video_format_desc(get_param(L"FORMAT", params, L"INVALID"));\r
@@ -338,11 +352,9 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factor
        boost::replace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1");\r
        \r
        if(format_desc.format == core::video_format::invalid)\r
-               format_desc = frame_factory->get_video_format_desc();\r
+               format_desc = frame_factory->video_format_desc();\r
                        \r
-       return create_producer_print_proxy(\r
-                  create_producer_destroy_proxy(\r
-                       make_safe<decklink_producer_proxy>(frame_factory, format_desc, device_index, filter_str, length)));\r
+       return core::wrap_producer(spl::make_shared<decklink_producer_proxy>(frame_factory, format_desc, device_index, filter_str, length));\r
 }\r
 \r
 }}
\ No newline at end of file