]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2:
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 8 May 2011 16:10:18 +0000 (16:10 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 8 May 2011 16:10:18 +0000 (16:10 +0000)
 bluefish_consumer: Refactored.
 decklink_producer: Full support for different sample counts.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@698 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/bluefish/bluefish.cpp
modules/bluefish/consumer/bluefish_consumer.cpp
modules/bluefish/consumer/bluefish_consumer.h
modules/decklink/producer/decklink_producer.cpp
shell/caspar.config
shell/server.cpp

index 06c3b4ad87f8c813c7b477b73bc0cb7613014cc6..eeea99eb542e7c5fc90c337da3f09b445da4660e 100644 (file)
@@ -30,7 +30,7 @@ void init_bluefish()
                blue_initialize();\r
        }\r
        catch(...){}\r
-       core::register_consumer_factory(create_bluefish_consumer);\r
+       core::register_consumer_factory([](const std::vector<std::wstring>& params){return create_bluefish_consumer(params);});\r
 }\r
 \r
 }
\ No newline at end of file
index 65a5edba712de4cb2838df1a4e9689ef85bf268e..676540e925242db5fc765d6e01338d309b4bc555 100644 (file)
@@ -82,7 +82,7 @@ void blue_initialize()
        blue_hanc_initialize();\r
 }\r
                \r
-struct bluefish_consumer::implementation : boost::noncopyable\r
+struct bluefish_consumer : boost::noncopyable\r
 {\r
        std::wstring            model_name_;\r
        const unsigned int      device_index_;\r
@@ -90,59 +90,43 @@ struct bluefish_consumer::implementation : boost::noncopyable
        std::shared_ptr<diagnostics::graph> graph_;\r
        boost::timer perf_timer_;\r
 \r
-       boost::unique_future<void> active_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<const core::read_frame>> frame_buffer_;\r
                        \r
        std::shared_ptr<CBlueVelvet4> blue_;\r
        \r
-       core::video_format_desc format_desc_;\r
+       const core::video_format_desc   format_desc_;\r
                \r
-       unsigned long   mem_fmt_;\r
-       unsigned long   upd_fmt_;\r
-       EVideoMode              vid_fmt_; \r
-       unsigned long   res_fmt_; \r
-       unsigned long   engine_mode_;\r
+       const unsigned long     mem_fmt_;\r
+       const unsigned long     upd_fmt_;\r
+       const unsigned long     res_fmt_; \r
+       unsigned long engine_mode_;\r
+       EVideoMode      vid_fmt_; \r
        \r
        std::array<blue_dma_buffer_ptr, 3> reserved_frames_;    \r
 \r
        const bool embedded_audio_;\r
 \r
+       tbb::atomic<bool> is_running_;\r
        executor executor_;\r
 public:\r
-       implementation::implementation(unsigned int device_index, bool embedded_audio) \r
+       bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio) \r
                : model_name_(L"BLUEFISH")\r
                , device_index_(device_index) \r
+               , format_desc_(format_desc)\r
                , mem_fmt_(MEM_FMT_ARGB_PC)\r
                , upd_fmt_(UPD_FMT_FRAME)\r
-               , vid_fmt_(VID_FMT_INVALID) \r
                , res_fmt_(RES_FMT_NORMAL) \r
                , engine_mode_(VIDEO_ENGINE_FRAMESTORE)         \r
+               , vid_fmt_(VID_FMT_INVALID) \r
                , embedded_audio_(embedded_audio)\r
-               , executor_(print())\r
+               , executor_(print(), true)\r
        {\r
-               if(!BlueVelvetFactory4 || (embedded_audio_ && (!encode_hanc_frame || !encode_hanc_frame)))\r
-                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Bluefish drivers not found."));\r
-       }\r
+               is_running_ = true;\r
+               frame_buffer_.set_capacity(1);\r
 \r
-       ~implementation()\r
-       {\r
-               if(executor_.is_running())\r
-               {\r
-                       executor_.invoke([&]\r
-                       {\r
-                               disable_video_output();\r
-\r
-                               if(blue_)\r
-                                       blue_->device_detach();         \r
-                       });\r
-               }\r
+               if(!BlueVelvetFactory4 || (embedded_audio_ && (!encode_hanc_frame || !encode_hanc_frame)))\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Bluefish drivers not found."));\r
                \r
-               CASPAR_LOG(info) << print() << L" Shutting down.";      \r
-       }\r
-\r
-       void initialize(const core::video_format_desc& format_desc)\r
-       {               \r
-               format_desc_ = format_desc;\r
-\r
                blue_.reset(BlueVelvetFactory4());\r
 \r
                if(BLUE_FAIL(blue_->device_attach(device_index_, FALSE))) \r
@@ -241,12 +225,25 @@ public:
                for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
                        reserved_frames_[n] = std::make_shared<blue_dma_buffer>(format_desc_.size, n);          \r
                                \r
-               executor_.start();\r
-               active_ = executor_.begin_invoke([]{});\r
-\r
                CASPAR_LOG(info) << print() << TEXT(" Successfully initialized for ") << format_desc_ << TEXT(".");\r
        }\r
+\r
+       ~bluefish_consumer()\r
+       {\r
+               is_running_ = false;\r
+               frame_buffer_.clear();\r
+               executor_.clear();\r
+               executor_.invoke([&]\r
+               {\r
+                       disable_video_output();\r
+\r
+                       if(blue_)\r
+                               blue_->device_detach();         \r
+               });\r
                \r
+               CASPAR_LOG(info) << print() << L" Shutting down.";      \r
+       }\r
+\r
        void enable_video_output()\r
        {\r
                if(!BLUE_PASS(set_card_property(blue_, VIDEO_BLACKGENERATOR, 0)))\r
@@ -262,15 +259,21 @@ public:
        virtual void send(const safe_ptr<const core::read_frame>& frame)\r
        {                       \r
                static std::vector<short> silence(MAX_HANC_BUFFER_SIZE, 0);\r
-               \r
-               size_t audio_samples = static_cast<size_t>(48000.0 / format_desc_.fps);\r
-               size_t audio_nchannels = 2;\r
-               \r
-               active_.get();\r
-               active_ = executor_.begin_invoke([=]\r
+                               \r
+               if(!is_running_)\r
+                       return;\r
+\r
+               frame_buffer_.push(frame);\r
+               executor_.begin_invoke([this]\r
                {\r
                        try\r
                        {\r
+                               const size_t audio_samples = static_cast<size_t>(48000.0 / format_desc_.fps);\r
+                               const size_t audio_nchannels = 2;\r
+\r
+                               std::shared_ptr<const core::read_frame> frame;\r
+                               frame_buffer_.pop(frame);\r
+\r
                                fast_memcpy(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size());\r
                                \r
                                if(embedded_audio_)\r
@@ -348,17 +351,32 @@ public:
        }\r
 };\r
 \r
-bluefish_consumer::bluefish_consumer(unsigned int device_index, bool embedded_audio) : impl_(new implementation(device_index, embedded_audio)){}       \r
-bluefish_consumer::bluefish_consumer(bluefish_consumer&& other) : impl_(std::move(other.impl_)){}\r
-void bluefish_consumer::initialize(const core::video_format_desc& format_desc)\r
+struct bluefish_consumer_proxy : public core::frame_consumer\r
 {\r
-       // TODO: Ugly\r
-       impl_.reset(new implementation(impl_->device_index_, impl_->embedded_audio_));\r
-       impl_->initialize(format_desc);\r
-}\r
-void bluefish_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
-size_t bluefish_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
-std::wstring bluefish_consumer::print() const {return impl_->print();} \r
+       std::unique_ptr<bluefish_consumer> consumer_;\r
+       const size_t device_index_;\r
+       const bool embedded_audio_;\r
+public:\r
+\r
+       bluefish_consumer_proxy(size_t device_index, bool embedded_audio)\r
+               : device_index_(device_index)\r
+               , embedded_audio_(embedded_audio){}\r
+       \r
+       void initialize(const core::video_format_desc& format_desc)\r
+       {\r
+               consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_));\r
+       }\r
+       \r
+       void send(const safe_ptr<const core::read_frame>& frame)\r
+       {\r
+               consumer_->send(frame);\r
+       }\r
+       \r
+       std::wstring print() const\r
+       {\r
+               return consumer_->print();\r
+       }\r
+};     \r
 \r
 std::wstring get_bluefish_version()\r
 {\r
@@ -409,7 +427,15 @@ safe_ptr<core::frame_consumer> create_bluefish_consumer(const std::vector<std::w
 \r
        bool embedded_audio = std::find(params.begin(), params.end(), L"EMBEDDED_AUDIO") != params.end();\r
 \r
-       return make_safe<bluefish_consumer>(device_index, embedded_audio);\r
+       return make_safe<bluefish_consumer_proxy>(device_index, embedded_audio);\r
+}\r
+\r
+safe_ptr<core::frame_consumer> create_bluefish_consumer(const boost::property_tree::ptree& ptree) \r
+{      \r
+       auto device_index = ptree.get("device", 0);\r
+       auto embedded_audio  = ptree.get("embedded-audio", false);\r
+\r
+       return make_safe<bluefish_consumer_proxy>(device_index, embedded_audio);\r
 }\r
 \r
 }
\ No newline at end of file
index b7d0c6d6246c797a45aa26a5175e37ea3f4afc2c..4e062b31e2d1ea51977e49d87fb09bb7d502e4c8 100644 (file)
 #include <core/video_format.h>\r
 #include <core/consumer/frame_consumer.h>\r
 \r
+#include <boost/property_tree/ptree.hpp>\r
+\r
 #include <string>\r
 \r
 namespace caspar { \r
-       \r
-struct bluefish_exception : public caspar_exception{};\r
-\r
-class bluefish_consumer : public core::frame_consumer\r
-{\r
-public:\r
-       explicit bluefish_consumer(unsigned int device_index, bool embed_audio = false);\r
-       bluefish_consumer(bluefish_consumer&& other);\r
-       \r
-       virtual void initialize(const core::video_format_desc& format_desc);\r
-       virtual void send(const safe_ptr<const core::read_frame>&);\r
-       virtual size_t buffer_depth() const;\r
-       virtual std::wstring print() const;\r
-private:\r
-       struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
-};\r
-       \r
+\r
+struct bluefish_exception : virtual caspar_exception{};\r
+               \r
 void blue_initialize();\r
 std::wstring get_bluefish_version();\r
 std::vector<std::wstring> get_bluefish_device_list();\r
+\r
 safe_ptr<core::frame_consumer> create_bluefish_consumer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_consumer> create_bluefish_consumer(const boost::property_tree::ptree& ptree);\r
 \r
 }
\ No newline at end of file
index 29f8227dfcecb08e173e7bb329fa720ed68509ca..268cb14cb57ef01f5dcb3f58fc58b1c805fcaaaa 100644 (file)
@@ -56,8 +56,6 @@ namespace caspar {
 \r
 class decklink_producer : public IDeckLinkInputCallback\r
 {      \r
-       static const size_t SAMPLES_PER_FRAME = 3840;\r
-\r
        CComPtr<IDeckLink>                              decklink_;\r
        CComQIPtr<IDeckLinkInput>               input_;\r
        \r
@@ -179,14 +177,17 @@ public:
                        // It is assumed that audio is always equal or ahead of video.\r
                        if(audio && SUCCEEDED(audio->GetBytes(&bytes)))\r
                        {\r
+                               const size_t audio_samples = static_cast<size_t>(48000.0 / format_desc_.fps);\r
+                               const size_t audio_nchannels = 2;\r
+\r
                                auto sample_frame_count = audio->GetSampleFrameCount();\r
                                auto audio_data = reinterpret_cast<short*>(bytes);\r
                                audio_data_.insert(audio_data_.end(), audio_data, audio_data + sample_frame_count*2);\r
 \r
-                               if(audio_data_.size() > SAMPLES_PER_FRAME)\r
+                               if(audio_data_.size() > audio_samples*audio_nchannels)\r
                                {\r
-                                       frame->audio_data() = std::vector<short>(audio_data_.begin(), audio_data_.begin() + SAMPLES_PER_FRAME);\r
-                                       audio_data_.erase(audio_data_.begin(), audio_data_.begin() + SAMPLES_PER_FRAME);\r
+                                       frame->audio_data() = std::vector<short>(audio_data_.begin(), audio_data_.begin() +  audio_samples*audio_nchannels);\r
+                                       audio_data_.erase(audio_data_.begin(), audio_data_.begin() +  audio_samples*audio_nchannels);\r
                                }\r
                        }\r
 \r
index 65e587a6d619bfcd4efa94a14dcb96fe589c457c..52fa351574ce3336fe34372a86393c07a3dbca32 100644 (file)
@@ -14,7 +14,7 @@
     <channel>\r
       <videomode>PAL</videomode>\r
       <consumers>\r
-        <decklink>\r
+        <!--<decklink>\r
           <device>1</device>\r
           <embedded-audio>true</embedded-audio>\r
           <latency>low</latency>\r
           <device>0</device>\r
           <stretch>uniform</stretch>\r
           <windowed>true</windowed>\r
-        </ogl>\r
+        </ogl>-->\r
         <!--<audio/>-->\r
-        <!--<bluefish>\r
+        <bluefish>\r
           <device>1</device>\r
-          <embedded-audio>false</embedded-audio>\r
-        </bluefish>-->\r
+          <embedded-audio>true</embedded-audio>\r
+        </bluefish>\r
+      </consumers>\r
+    </channel>\r
+    <channel>\r
+      <videomode>PAL</videomode>\r
+      <consumers>\r
+        <ogl>\r
+          <device>0</device>\r
+          <stretch>uniform</stretch>\r
+          <windowed>true</windowed>\r
+        </ogl>\r
+        <audio/>\r
       </consumers>\r
     </channel>\r
 </channels>\r
index 5ed616e69414ca0b36989d6455815d9c6a874be2..5e3528bfdc137427da000acce2cdcabf49ae4149 100644 (file)
@@ -118,8 +118,7 @@ struct server::implementation : boost::noncopyable
                                                channels_.back()->consumer()->add(index++, ogl_consumer(device, stretch, windowed));\r
                                        }\r
                                        else if(name == "bluefish")                                     \r
-                                               channels_.back()->consumer()->add(index++, bluefish_consumer(xml_consumer.second.get("device", 0), \r
-                                                                                                                                                                       xml_consumer.second.get("embedded-audio", true)));                                      \r
+                                               channels_.back()->consumer()->add(index++, create_bluefish_consumer(xml_consumer.second));                                      \r
                                        else if(name == "decklink")                                     \r
                                                channels_.back()->consumer()->add(index++, create_decklink_consumer(xml_consumer.second));                                      \r
                                        else if(name == "audio")\r