]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: decklink_consumer: Possible to choose internal_key, external_key or default_key.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 2 May 2011 20:48:13 +0000 (20:48 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 2 May 2011 20:48:13 +0000 (20:48 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@683 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/consumer/frame/read_frame.h
core/producer/frame_producer.h
core/producer/frame_producer_device.h
core/producer/layer.h
modules/decklink/consumer/decklink_consumer.cpp
modules/decklink/consumer/decklink_consumer.h
shell/caspar.config
shell/main.cpp
shell/server.cpp

index 07c2296b797fbad381972cc235d7138cb177b51c..02369f8a75b310ccb2494c7ef7f507f4762f718e 100644 (file)
 */\r
 #pragma once\r
 \r
+#include <common/memory/safe_ptr.h>\r
+\r
 #include <boost/noncopyable.hpp>\r
 #include <boost/range/iterator_range.hpp>\r
 \r
-#include <memory>\r
-#include <vector>\r
-\r
-#include <common/memory/safe_ptr.h>\r
-\r
 namespace caspar { namespace core {\r
        \r
-class read_frame\r
+class read_frame : boost::noncopyable\r
 {\r
 public:\r
        virtual const boost::iterator_range<const unsigned char*> image_data() const = 0;\r
index c32c1838ce3da83cea5da399f6618ff834c22aed..705ce64110f7fbfbba32761f53b4b23676028bf0 100644 (file)
@@ -42,7 +42,7 @@ public:
        virtual void param(const std::wstring&){}\r
 \r
        virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();}  // nothrow\r
-       virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {}  // nothrow\r
+       virtual void set_leading_producer(const safe_ptr<frame_producer>&) {}  // nothrow\r
                \r
        static const safe_ptr<frame_producer>& empty() // nothrow\r
        {\r
index 5549662612b22281ae41e4e1276a70cb212a09a5..fe407dd9693ad57540fb94e80fa19f7bab9cdc34 100644 (file)
 #include <common/memory/safe_ptr.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
+#include <boost/signals2.hpp>\r
 #include <boost/thread/future.hpp>\r
 \r
 #include <functional>\r
 \r
-#include <boost/signals2.hpp>\r
-\r
 namespace caspar { namespace core {\r
 \r
 ////////////////////////////////////////////////////////////////////////////////////////////////////\r
index 892f14ae773db86afb531c694143c57e6e74eb55..b5281ff018f33a4e52d11c08589f84f72206636e 100644 (file)
 \r
 #include <boost/noncopyable.hpp>\r
 \r
-#include <memory>\r
-#include <numeric>\r
-\r
 namespace caspar { namespace core {\r
 \r
 class frame_producer;\r
 class basic_frame;\r
 \r
-class layer //: boost::noncopyable\r
+class layer : boost::noncopyable\r
 {\r
 public:\r
        layer(); // nothrow\r
@@ -54,7 +51,7 @@ public:
        safe_ptr<basic_frame> receive(); // nothrow\r
 private:\r
        struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
+       safe_ptr<implementation> impl_;\r
 };\r
 \r
 }}
\ No newline at end of file
index 2e0d24e55a503734c0e510111e73dd9b04f12d47..86019eb4c37dd82f3da5922bfa73b117d7da4f45 100644 (file)
@@ -62,8 +62,11 @@ struct decklink_output : public IDeckLinkVideoOutputCallback, public IDeckLinkAu
                ~co_init(){CoUninitialize();}\r
        } co_;\r
        \r
-       std::wstring    model_name_;\r
        const size_t    device_index_;\r
+       const bool              embed_audio_;\r
+       const decklink_consumer::key            key_;\r
+\r
+       std::wstring    model_name_;\r
        tbb::atomic<bool> is_running_;\r
 \r
        std::shared_ptr<diagnostics::graph> graph_;\r
@@ -72,12 +75,8 @@ struct decklink_output : public IDeckLinkVideoOutputCallback, public IDeckLinkAu
        std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, 3> reserved_frames_;\r
        boost::circular_buffer<std::vector<short>> audio_container_;\r
        \r
-       const bool              embed_audio_;\r
-       const bool              internal_key;\r
-\r
        CComPtr<IDeckLink>                      decklink_;\r
        CComQIPtr<IDeckLinkOutput>      output_;\r
-       CComQIPtr<IDeckLinkKeyer>       keyer_;\r
        \r
        core::video_format_desc format_desc_;\r
 \r
@@ -90,12 +89,12 @@ struct decklink_output : public IDeckLinkVideoOutputCallback, public IDeckLinkAu
        tbb::concurrent_bounded_queue<std::shared_ptr<const core::read_frame>> audio_frame_buffer_;\r
 \r
 public:\r
-       decklink_output(const core::video_format_desc& format_desc,size_t device_index, bool embed_audio, bool internalKey) \r
+       decklink_output(const core::video_format_desc& format_desc,size_t device_index, bool embed_audio, decklink_consumer::key key) \r
                :  model_name_(L"DECKLINK")\r
                , device_index_(device_index)\r
                , audio_container_(5)\r
                , embed_audio_(embed_audio)\r
-               , internal_key(internalKey)\r
+               , key_(key)\r
                , frames_scheduled_(0)\r
                , audio_scheduled_(0)\r
                , format_desc_(format_desc)\r
@@ -111,10 +110,7 @@ public:
 \r
                if(n != device_index_ || !decklink_)\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Decklink card not found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index_)));\r
-\r
-               output_ = decklink_;\r
-               keyer_ = decklink_;\r
-\r
+               \r
                BSTR pModelName;\r
                decklink_->GetModelName(&pModelName);\r
                model_name_ = std::wstring(pModelName);\r
@@ -123,6 +119,8 @@ public:
                graph_->add_guide("tick-time", 0.5);\r
                graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
                \r
+               output_ = decklink_;\r
+\r
                auto display_mode = get_display_mode(output_.p, format_desc_.format);\r
                if(display_mode == nullptr) \r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Card does not support requested videoformat."));\r
@@ -150,24 +148,28 @@ public:
                if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
                        \r
-               if(internal_key) \r
+               CComQIPtr<IDeckLinkKeyer> keyer = decklink_;\r
+               if(key_ == decklink_consumer::internal_key) \r
                {\r
-                       if(FAILED(keyer_->Enable(FALSE)))                       \r
+                       if(FAILED(keyer->Enable(FALSE)))                        \r
                                CASPAR_LOG(error) << print() << L" Failed to enable internal keyer.";                   \r
-                       else if(FAILED(keyer_->SetLevel(255)))                  \r
+                       else if(FAILED(keyer->SetLevel(255)))                   \r
                                CASPAR_LOG(error) << print() << L" Failed to set key-level to max.";\r
                        else\r
                                CASPAR_LOG(info) << print() << L" Successfully configured internal keyer.";             \r
                }\r
-               else\r
+               else if(key_ == decklink_consumer::external_key)\r
                {\r
-                       if(FAILED(keyer_->Enable(TRUE)))                        \r
+                       if(FAILED(keyer->Enable(TRUE)))                 \r
                                CASPAR_LOG(error) << print() << L" Failed to enable external keyer.";   \r
-                       else if(FAILED(keyer_->SetLevel(255)))                  \r
+                       else if(FAILED(keyer->SetLevel(255)))                   \r
                                CASPAR_LOG(error) << print() << L" Failed to set key-level to max.";\r
                        else\r
                                CASPAR_LOG(info) << print() << L" Successfully configured external keyer.";                     \r
                }\r
+               else\r
+                               CASPAR_LOG(info) << print() << L" Uses default keyer settings.";        \r
+\r
                \r
                for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
                {\r
@@ -293,15 +295,15 @@ struct decklink_consumer::implementation
        std::unique_ptr<decklink_output> input_;\r
        size_t device_index_;\r
        bool embed_audio_;\r
-       bool internal_key_;\r
+       decklink_consumer::key key_;\r
 \r
        executor executor_;\r
 public:\r
 \r
-       implementation(size_t device_index, bool embed_audio, bool internal_key)\r
+       implementation(size_t device_index, bool embed_audio, decklink_consumer::key key)\r
                : device_index_(device_index)\r
                , embed_audio_(embed_audio)\r
-               , internal_key_(internal_key)\r
+               , key_(key)\r
                , executor_(L"DECKLINK[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
        {\r
                executor_.start();\r
@@ -319,7 +321,7 @@ public:
        {\r
                executor_.invoke([&]\r
                {\r
-                       input_.reset(new decklink_output(format_desc, device_index_, embed_audio_, internal_key_));\r
+                       input_.reset(new decklink_output(format_desc, device_index_, embed_audio_, key_));\r
                });\r
        }\r
        \r
@@ -339,7 +341,7 @@ public:
        }\r
 };\r
 \r
-decklink_consumer::decklink_consumer(size_t device_index, bool embed_audio, bool internalKey) : impl_(new implementation(device_index, embed_audio, internalKey)){}\r
+decklink_consumer::decklink_consumer(size_t device_index, bool embed_audio, key key) : impl_(new implementation(device_index, embed_audio, key)){}\r
 decklink_consumer::decklink_consumer(decklink_consumer&& other) : impl_(std::move(other.impl_)){}\r
 void decklink_consumer::initialize(const core::video_format_desc& format_desc){impl_->initialize(format_desc);}\r
 void decklink_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
@@ -353,7 +355,7 @@ safe_ptr<core::frame_consumer> create_decklink_consumer(const std::vector<std::w
        \r
        int device_index = 1;\r
        bool embed_audio = false;\r
-       bool internal_key = false;\r
+       auto key = decklink_consumer::default_key;\r
 \r
        if(params.size() > 1) \r
                device_index = lexical_cast_or_default<int>(params[2], device_index);\r
@@ -361,10 +363,16 @@ safe_ptr<core::frame_consumer> create_decklink_consumer(const std::vector<std::w
        if(params.size() > 2)\r
                embed_audio = lexical_cast_or_default<bool>(params[3], embed_audio);\r
        \r
+\r
        if(params.size() > 3) \r
-               internal_key = lexical_cast_or_default<bool>(params[4], internal_key);\r
+       {\r
+               if(params[4] == L"INTERNAL_KEY")\r
+                       key = decklink_consumer::internal_key;\r
+               else if(params[4] == L"EXTERNAL_KEY")\r
+                       key = decklink_consumer::external_key;\r
+       }\r
 \r
-       return make_safe<decklink_consumer>(device_index, embed_audio, internal_key);\r
+       return make_safe<decklink_consumer>(device_index, embed_audio, key);\r
 }\r
 \r
 }
\ No newline at end of file
index ee70d59746e587ebbcb3f5da95cbf771a1d48ef4..8db428447237d533d84929adf273b707e788c770 100644 (file)
@@ -31,7 +31,15 @@ namespace caspar {
 class decklink_consumer : public core::frame_consumer\r
 {\r
 public:\r
-       explicit decklink_consumer(size_t device_index, bool embed_audio = false, bool internal_key = false);\r
+\r
+       enum key\r
+       {\r
+               external_key,\r
+               internal_key,\r
+               default_key\r
+       };\r
+\r
+       explicit decklink_consumer(size_t device_index, bool embed_audio = false, key key = default_key);\r
        decklink_consumer(decklink_consumer&& other);\r
        \r
        virtual void initialize(const core::video_format_desc& format_desc);\r
index 01e401f4b876403f8d11210907433cbdc9af590a..f374a208f06391f19fe932e64b9b44f3b57775c6 100644 (file)
   </diagnostics>\r
   <channels>\r
     <channel>\r
-      <videomode>1080p5000</videomode>\r
+      <videomode>PAL</videomode>\r
       <consumers>\r
-        <!--<decklink>\r
+        <decklink>\r
           <device>1</device>\r
-          <embedded-audio>false</embedded-audio>\r
-          <internal-key>false</internal-key>\r
-        </decklink>-->\r
+          <embedded-audio>true</embedded-audio>\r
+          <key>external</key>\r
+        </decklink>\r
         <ogl>\r
           <device>0</device>\r
           <stretch>uniform</stretch>\r
index f835e4191cd1b6bd17e2541d7c29edee18ea91bc..1dbcb21fd37bfdfd426f78a810badc8dc90a4172 100644 (file)
@@ -125,12 +125,9 @@ int main(int argc, wchar_t* argv[])
 {      \r
        static_assert(sizeof(void*) == 4, "64-bit code generation is not supported.");\r
        \r
-       // Install unstructured exception handler.\r
+       // Install structured exception handler.\r
        caspar::win32_exception::install_handler();\r
 \r
-       // Create atleast two threads to avoid async issues with legacy code running on unicore systems.\r
-       //tbb::task_scheduler_init init(std::max(tbb::task_scheduler_init::default_num_threads(), 2));\r
-\r
        // Set debug mode.\r
        #ifdef _DEBUG\r
                _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );\r
index 610487e328fc60749f895e5e64cb4b7f70828b4b..0ca01eb6408b01fb06922d2693a4d0acd82de2de 100644 (file)
@@ -121,9 +121,17 @@ struct server::implementation : boost::noncopyable
                                                channels_.back()->consumer()->add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
                                                                                                                                                                        xml_consumer.second.get("embedded-audio", true)));                                      \r
                                        else if(name == "decklink")\r
+                                       {\r
+                                               auto key_str = xml_consumer.second.get("key", "default");\r
+                                               auto key = decklink_consumer::default_key;\r
+                                               if(key_str == "internal")\r
+                                                       key = decklink_consumer::internal_key;\r
+                                               else if(key_str == "external")\r
+                                                       key = decklink_consumer::external_key;\r
                                                channels_.back()->consumer()->add(index++, decklink_consumer(xml_consumer.second.get("device", 0), \r
                                                                                                                                                                        xml_consumer.second.get("embedded-audio", true), \r
-                                                                                                                                                                       xml_consumer.second.get("internal-key", false)));\r
+                                                                                                                                                                       key));\r
+                                       }\r
                                        else if(name == "audio")\r
                                                channels_.back()->consumer()->add(index++, oal_consumer());                     \r
                                }\r