]> git.sesse.net Git - casparcg/blobdiff - core/producer/channel/channel_producer.cpp
Fixed bug in channel_producer
[casparcg] / core / producer / channel / channel_producer.cpp
index ae1c0c81721ee079b7f427ca67f63eb803e7c5d9..98d845ca0880f5986a5199cfe5138e79ac26418c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
+* Copyright 2013 Sveriges Television AB http://casparcg.com/\r
 *\r
 * This file is part of CasparCG (www.casparcg.com).\r
 *\r
@@ -23,6 +23,7 @@
 \r
 #include "channel_producer.h"\r
 \r
+#include "../../monitor/monitor.h"\r
 #include "../../consumer/frame_consumer.h"\r
 #include "../../consumer/output.h"\r
 #include "../../video_channel.h"\r
@@ -33,6 +34,8 @@
 #include "../../mixer/read_frame.h"\r
 \r
 #include <common/exception/exceptions.h>\r
+#include <common/memory/memcpy.h>\r
+#include <common/concurrency/future_util.h>\r
 \r
 #include <tbb/concurrent_queue.h>\r
 \r
@@ -40,15 +43,17 @@ namespace caspar { namespace core {
 \r
 class channel_consumer : public frame_consumer\r
 {      \r
-       tbb::concurrent_bounded_queue<std::shared_ptr<read_frame>> frame_buffer_;\r
-       core::video_format_desc format_desc_;\r
-       int                                             channel_index_;\r
-       tbb::atomic<bool>               is_running_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<read_frame>>      frame_buffer_;\r
+       core::video_format_desc                                                                         format_desc_;\r
+       int                                                                                                                     channel_index_;\r
+       tbb::atomic<bool>                                                                                       is_running_;\r
+       tbb::atomic<int64_t>                                                                            current_age_;\r
 \r
 public:\r
        channel_consumer() \r
        {\r
                is_running_ = true;\r
+               current_age_ = 0;\r
                frame_buffer_.set_capacity(3);\r
        }\r
 \r
@@ -59,16 +64,21 @@ public:
 \r
        // frame_consumer\r
 \r
-       virtual bool send(const safe_ptr<read_frame>& frame) override\r
+       virtual boost::unique_future<bool> send(const safe_ptr<read_frame>& frame) override\r
        {\r
                frame_buffer_.try_push(frame);\r
-               return is_running_;\r
+               return caspar::wrap_as_future(is_running_.load());\r
        }\r
 \r
        virtual void initialize(const core::video_format_desc& format_desc, int channel_index) override\r
        {\r
                format_desc_    = format_desc;\r
-               channel_index_ = channel_index;\r
+               channel_index_  = channel_index;\r
+       }\r
+\r
+       virtual int64_t presentation_frame_age_millis() const override\r
+       {\r
+               return current_age_;\r
        }\r
 \r
        virtual std::wstring print() const override\r
@@ -117,13 +127,18 @@ public:
                if(!is_running_)\r
                        return make_safe<read_frame>();\r
                std::shared_ptr<read_frame> frame;\r
-               frame_buffer_.try_pop(frame);\r
+               \r
+               if (frame_buffer_.try_pop(frame))\r
+                       current_age_ = frame->get_age_millis();\r
+\r
                return frame;\r
        }\r
 };\r
        \r
 class channel_producer : public frame_producer\r
 {\r
+       monitor::subject                                        monitor_subject_;\r
+\r
        const safe_ptr<frame_factory>           frame_factory_;\r
        const safe_ptr<channel_consumer>        consumer_;\r
 \r
@@ -168,17 +183,17 @@ public:
                frame_number_++;\r
                \r
                core::pixel_format_desc desc;\r
-               bool double_speed = std::abs(frame_factory_->get_video_format_desc().fps / 2.0 - format_desc.fps) < 0.01;               \r
-               bool half_speed = std::abs(format_desc.fps / 2.0 - frame_factory_->get_video_format_desc().fps) < 0.01;\r
+               bool double_speed       = std::abs(frame_factory_->get_video_format_desc().fps / 2.0 - format_desc.fps) < 0.01;         \r
+               bool half_speed         = std::abs(format_desc.fps / 2.0 - frame_factory_->get_video_format_desc().fps) < 0.01;\r
 \r
-               if(half_speed && frame_number_ % 2 == 0)\r
+               if(half_speed && frame_number_ % 2 == 0) // Skip frame\r
                        return receive(0);\r
 \r
                desc.pix_fmt = core::pixel_format::bgra;\r
                desc.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4));\r
                auto frame = frame_factory_->create_frame(this, desc);\r
 \r
-               memcpy(frame->image_data().begin(), read_frame->image_data().begin(), read_frame->image_data().size());\r
+               fast_memcpy(frame->image_data().begin(), read_frame->image_data().begin(), read_frame->image_data().size());\r
                frame->commit();\r
 \r
                frame_buffer_.push(frame);      \r
@@ -199,17 +214,23 @@ public:
                return L"channel[]";\r
        }\r
 \r
-       boost::property_tree::wptree info() const override\r
+       virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
                info.add(L"type", L"channel-producer");\r
                return info;\r
        }\r
+\r
+       monitor::source& monitor_output() \r
+       {\r
+               return monitor_subject_;\r
+       }\r
 };\r
 \r
 safe_ptr<frame_producer> create_channel_producer(const safe_ptr<core::frame_factory>& frame_factory, const safe_ptr<video_channel>& channel)\r
 {\r
-       return make_safe<channel_producer>(frame_factory, channel);\r
+       return create_producer_print_proxy(\r
+                       make_safe<channel_producer>(frame_factory, channel));\r
 }\r
 \r
 }}
\ No newline at end of file