]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/consumer/decklink_consumer.cpp
[decklink_consumer] #539 #285 #521 Fixed serious deadlock in decklink_consumer where...
[casparcg] / modules / decklink / consumer / decklink_consumer.cpp
index 3378068762d8e1fb74c73bb717816fb921bf9c80..2e494577ed02c9ce019203cbdbfe532feedb714e 100644 (file)
@@ -81,7 +81,7 @@ struct configuration
 
        int                                                     device_index            = 1;
        int                                                     key_device_idx          = 0;
-       bool                                            embedded_audio          = true;
+       bool                                            embedded_audio          = false;
        keyer_t                                         keyer                           = keyer_t::default_keyer;
        latency_t                                       latency                         = latency_t::default_latency;
        bool                                            key_only                        = false;
@@ -219,7 +219,12 @@ public:
        virtual ULONG STDMETHODCALLTYPE Release()
        {
                if(--ref_count_ == 0)
+               {
                        delete this;
+
+                       return 0;
+               }
+
                return ref_count_;
        }
 
@@ -390,11 +395,10 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, boost::noncopyab
        boost::circular_buffer<std::vector<int32_t>>            audio_container_                { buffer_size_ + 1 };
 
        tbb::concurrent_bounded_queue<core::const_frame>        frame_buffer_;
+       caspar::semaphore                                                                       ready_for_new_frames_   { 0 };
 
        spl::shared_ptr<diagnostics::graph>                                     graph_;
        caspar::timer                                                                           tick_timer_;
-       boost::mutex                                                                            send_completion_mutex_;
-       std::packaged_task<bool ()>                                                     send_completion_;
        reference_signal_detector                                                       reference_signal_detector_      { output_ };
        tbb::atomic<int64_t>                                                            current_presentation_delay_;
        tbb::atomic<int64_t>                                                            scheduled_frames_completed_;
@@ -569,16 +573,10 @@ public:
                        auto frame = core::const_frame::empty();
 
                        frame_buffer_.pop(frame);
+                       ready_for_new_frames_.release();
 
-                       {
-                               boost::lock_guard<boost::mutex> lock(send_completion_mutex_);
-
-                               if (send_completion_.valid())
-                               {
-                                       send_completion_();
-                                       send_completion_ = std::packaged_task<bool()>();
-                               }
-                       }
+                       if (!is_running_)
+                               return E_FAIL;
 
                        if (config_.embedded_audio)
                                schedule_next_audio(channel_remapper_.mix_and_rearrange(frame.audio_data()));
@@ -639,19 +637,16 @@ public:
                if(!is_running_)
                        CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info(print() + L" Is not running."));
 
-               if (frame_buffer_.try_push(frame))
-                       return make_ready_future(true);
+               frame_buffer_.push(frame);
 
-               boost::lock_guard<boost::mutex> lock(send_completion_mutex_);
+               auto send_completion = spl::make_shared<std::promise<bool>>();
 
-               send_completion_ = std::packaged_task<bool ()>([frame, this] () mutable -> bool
+               ready_for_new_frames_.acquire(1, [send_completion]
                {
-                       frame_buffer_.push(frame);
-
-                       return true;
+                       send_completion->set_value(true);
                });
 
-               return send_completion_.get_future();
+               return send_completion->get_future();
        }
 
        std::wstring print() const
@@ -817,7 +812,7 @@ void describe_consumer(core::help_sink& sink, const core::help_repository& repo)
 }
 
 spl::shared_ptr<core::frame_consumer> create_consumer(
-               const std::vector<std::wstring>& params, core::interaction_sink*)
+               const std::vector<std::wstring>& params, core::interaction_sink*, std::vector<spl::shared_ptr<core::video_channel>> channels)
 {
        if (params.size() < 1 || !boost::iequals(params.at(0), L"DECKLINK"))
                return core::frame_consumer::empty();
@@ -863,7 +858,7 @@ spl::shared_ptr<core::frame_consumer> create_consumer(
 }
 
 spl::shared_ptr<core::frame_consumer> create_preconfigured_consumer(
-               const boost::property_tree::wptree& ptree, core::interaction_sink*)
+               const boost::property_tree::wptree& ptree, core::interaction_sink*, std::vector<spl::shared_ptr<core::video_channel>> channels)
 {
        configuration config;