]> git.sesse.net Git - casparcg/commitdiff
Fixed bug where both layer_producer and channel_producer display:s and empty/late...
authorHelge Norberg <helge.norberg@svt.se>
Fri, 3 Oct 2014 12:49:18 +0000 (14:49 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 3 Oct 2014 12:49:18 +0000 (14:49 +0200)
core/producer/channel/channel_producer.cpp
core/producer/layer/layer_producer.cpp

index 3392cc741a1a8ba5c7a37324017caffec883aea9..e4658fd78d7301b7258bf0fb8c59f99b766fdf87 100644 (file)
@@ -51,10 +51,15 @@ class channel_consumer : public frame_consumer
        int                                                                                                                     consumer_index_;\r
        tbb::atomic<bool>                                                                                       is_running_;\r
        tbb::atomic<int64_t>                                                                            current_age_;\r
+       boost::promise<void>                                                                            first_frame_promise_;\r
+       boost::unique_future<void>                                                                      first_frame_available_;\r
+       bool                                                                                                            first_frame_reported_;\r
 \r
 public:\r
        channel_consumer()\r
                : consumer_index_(next_consumer_index())\r
+               , first_frame_available_(first_frame_promise_.get_future())\r
+               , first_frame_reported_(false)\r
        {\r
                is_running_ = true;\r
                current_age_ = 0;\r
@@ -83,7 +88,14 @@ public:
 \r
        virtual boost::unique_future<bool> send(const safe_ptr<read_frame>& frame) override\r
        {\r
-               frame_buffer_.try_push(frame);\r
+               bool pushed = frame_buffer_.try_push(frame);\r
+\r
+               if (pushed && !first_frame_reported_)\r
+               {\r
+                       first_frame_promise_.set_value();\r
+                       first_frame_reported_ = true;\r
+               }\r
+\r
                return caspar::wrap_as_future(is_running_.load());\r
        }\r
 \r
@@ -142,6 +154,13 @@ public:
                return format_desc_;\r
        }\r
 \r
+       void block_until_first_frame_available()\r
+       {\r
+               if (!first_frame_available_.timed_wait(boost::posix_time::seconds(2)))\r
+                       CASPAR_LOG(warning)\r
+                                       << print() << L" Timed out while waiting for first frame";\r
+       }\r
+\r
        std::shared_ptr<read_frame> receive()\r
        {\r
                if(!is_running_)\r
@@ -174,6 +193,7 @@ public:
                , frame_number_(0)\r
        {\r
                channel->output()->add(consumer_);\r
+               consumer_->block_until_first_frame_available();\r
                CASPAR_LOG(info) << print() << L" Initialized";\r
        }\r
 \r
@@ -189,7 +209,7 @@ public:
        {\r
                auto format_desc = consumer_->get_video_format_desc();\r
 \r
-               if(frame_buffer_.size() > 1)\r
+               if(frame_buffer_.size() > 0)\r
                {\r
                        auto frame = frame_buffer_.front();\r
                        frame_buffer_.pop();\r
index 84a671fd0d1090d65557ccb694e177fd2578d4e4..86f794d7931de34db2cadc97b94e579a514edc39 100644 (file)
@@ -46,9 +46,14 @@ namespace caspar { namespace core {
 class layer_consumer : public write_frame_consumer
 {      
        tbb::concurrent_bounded_queue<safe_ptr<basic_frame>>    frame_buffer_;
+       boost::promise<void>                                                                    first_frame_promise_;
+       boost::unique_future<void>                                                              first_frame_available_;
+       bool                                                                                                    first_frame_reported_;
 
 public:
-       layer_consumer() 
+       layer_consumer()
+               : first_frame_available_(first_frame_promise_.get_future())
+               , first_frame_reported_(false)
        {
                frame_buffer_.set_capacity(2);
        }
@@ -61,7 +66,13 @@ public:
 
        virtual void send(const safe_ptr<basic_frame>& src_frame) override
        {
-               frame_buffer_.try_push(src_frame);
+               bool pushed = frame_buffer_.try_push(src_frame);
+
+               if (pushed && !first_frame_reported_)
+               {
+                       first_frame_promise_.set_value();
+                       first_frame_reported_ = true;
+               }
        }
 
        virtual std::wstring print() const override
@@ -78,6 +89,13 @@ public:
                }
                return frame;
        }
+
+       void block_until_first_frame_available()
+       {
+               if (!first_frame_available_.timed_wait(boost::posix_time::seconds(2)))
+                       CASPAR_LOG(warning)
+                                       << print() << L" Timed out while waiting for first frame";
+       }
 };
 
 class layer_producer : public frame_producer
@@ -103,6 +121,7 @@ public:
                , frame_number_(0)
        {
                stage_->add_layer_consumer(this, layer_, consumer_);
+               consumer_->block_until_first_frame_available();
                CASPAR_LOG(info) << print() << L" Initialized";
        }