]> 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, 9 May 2011 19:22:55 +0000 (19:22 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 9 May 2011 19:22:55 +0000 (19:22 +0000)
modules/decklink/consumer/decklink_consumer.cpp

index a1f9b80f2f5ba26d5d77a36418575d90eb982315..1d0b1d1a653bbb902861613fb22a81096377a9d3 100644 (file)
@@ -86,8 +86,6 @@ struct configuration
 \r
 struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback, boost::noncopyable\r
 {              \r
-       static const size_t BUFFER_SIZE = 4;\r
-               \r
        const configuration config_;\r
 \r
        CComPtr<IDeckLink>                                      decklink_;\r
@@ -107,7 +105,7 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLink
        unsigned long frames_scheduled_;\r
        unsigned long audio_scheduled_;\r
                \r
-       std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, BUFFER_SIZE+1> reserved_frames_;\r
+       std::vector<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>> reserved_frames_;\r
        boost::circular_buffer<std::vector<short>> audio_container_;\r
 \r
        tbb::concurrent_bounded_queue<std::shared_ptr<const core::read_frame>> video_frame_buffer_;\r
@@ -116,6 +114,8 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLink
        std::shared_ptr<diagnostics::graph> graph_;\r
        boost::timer tick_timer_;\r
 \r
+       size_t buffer_size_;\r
+\r
 public:\r
        decklink_consumer(const configuration& config, const core::video_format_desc& format_desc) \r
                : config_(config)\r
@@ -128,6 +128,7 @@ public:
                , audio_container_(5)\r
                , frames_scheduled_(0)\r
                , audio_scheduled_(0)\r
+               , buffer_size_(5) // Minimum buffer-size (4 + 1 tolerance).\r
        {\r
                is_running_ = true;\r
                                                \r
@@ -159,6 +160,8 @@ public:
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not set audio callback."));\r
 \r
                        CASPAR_LOG(info) << print() << L" Enabled embedded-audio.";\r
+\r
+                       buffer_size_ = 6; //  Minimum buffer-size with embedded-audio (5 + 1 tolerance).\r
                }\r
 \r
                if(config.latency == normal_latency)\r
@@ -173,7 +176,7 @@ public:
                }\r
                else\r
                        CASPAR_LOG(info) << print() << L" Uses driver latency settings.";       \r
-               \r
+                               \r
                if(config.keyer == internal_key) \r
                {\r
                        if(FAILED(keyer_->Enable(FALSE)))                       \r
@@ -201,18 +204,24 @@ public:
                if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
                                        \r
-               BOOST_FOREACH(auto& frame, reserved_frames_)\r
+               for(size_t n = 0; n < buffer_size_+1; ++n)\r
                {\r
-                       if(FAILED(output_->CreateVideoFrame(format_desc_.width, format_desc_.height, format_desc_.size/format_desc_.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &frame.second)))\r
+                       CComPtr<IDeckLinkMutableVideoFrame> frame;\r
+\r
+                       if(FAILED(output_->CreateVideoFrame(format_desc_.width, format_desc_.height, format_desc_.size/format_desc_.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &frame)))\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to create frame."));\r
 \r
-                       if(FAILED(frame.second->GetBytes(&frame.first)))\r
+                       void* bytes = nullptr;\r
+\r
+                       if(FAILED(frame->GetBytes(&bytes)) || bytes == nullptr)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to get frame bytes."));\r
-               }\r
 \r
-               CASPAR_LOG(info) << print() << L" Buffer-depth: " << BUFFER_SIZE;\r
+                       reserved_frames_.push_back(std::make_pair(bytes, frame));\r
+               }\r
                \r
-               for(size_t n = 0; n < BUFFER_SIZE; ++n)\r
+               CASPAR_LOG(info) << print() << L" Buffer-depth: " << buffer_size_;\r
+               \r
+               for(size_t n = 0; n < buffer_size_; ++n)\r
                        schedule_next_video(core::read_frame::empty());\r
 \r
                video_frame_buffer_.set_capacity(2);\r
@@ -342,8 +351,11 @@ public:
                video_frame_buffer_.push(frame);\r
                if(config_.embedded_audio)\r
                        audio_frame_buffer_.push(frame);\r
+               \r
        }\r
 \r
+       size_t buffer_depth() const {return 1;}\r
+\r
        std::wstring print() const\r
        {\r
                return model_name_ + L" [" + boost::lexical_cast<std::wstring>(config_.device_index) + L"]";\r
@@ -361,20 +373,25 @@ public:
                : config_(config)\r
                , context_(L"decklink_consumer[" + boost::lexical_cast<std::wstring>(config.device_index) + L"]"){}\r
        \r
-       void initialize(const core::video_format_desc& format_desc)\r
+       virtual void initialize(const core::video_format_desc& format_desc)\r
        {\r
                context_.reset([&]{return new decklink_consumer(config_, format_desc);});\r
        }\r
        \r
-       void send(const safe_ptr<const core::read_frame>& frame)\r
+       virtual void send(const safe_ptr<const core::read_frame>& frame)\r
        {\r
                context_->send(frame);\r
        }\r
        \r
-       std::wstring print() const\r
+       virtual std::wstring print() const\r
        {\r
                return context_->print();\r
        }\r
+\r
+       virtual size_t buffer_depth() const \r
+       {\r
+               return context_->buffer_depth();\r
+       }\r
 };     \r
 \r
 safe_ptr<core::frame_consumer> create_decklink_consumer(const std::vector<std::wstring>& params) \r