]> git.sesse.net Git - casparcg/commitdiff
-
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 15:33:13 +0000 (15:33 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 15:33:13 +0000 (15:33 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@488 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

35 files changed:
common/concurrency/executor.h
common/diagnostics/graph.cpp
common/diagnostics/graph.h
common/memory/safe_ptr.h
core/channel.cpp
core/channel.h
core/consumer/bluefish/bluefish_consumer.cpp
core/consumer/bluefish/bluefish_consumer.h
core/consumer/decklink/decklink_consumer.cpp
core/consumer/decklink/decklink_consumer.h
core/consumer/ffmpeg/ffmpeg_consumer.cpp
core/consumer/ffmpeg/ffmpeg_consumer.h
core/consumer/frame_consumer.h
core/consumer/frame_consumer_device.cpp
core/consumer/frame_consumer_device.h
core/consumer/oal/oal_consumer.cpp
core/consumer/oal/oal_consumer.h
core/consumer/ogl/ogl_consumer.cpp
core/consumer/ogl/ogl_consumer.h
core/producer/color/color_producer.cpp
core/producer/decklink/decklink_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/input.cpp
core/producer/flash/flash_producer.cpp
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
mixer/frame_mixer_device.cpp
mixer/frame_mixer_device.h
shell/caspar.config
shell/main.cpp
shell/shell.vcxproj

index f84c46ddfe9c51036e3620c8cdbad68851d8ac93..89d30b1173933292ffe73db54c9c6c5332f467e0 100644 (file)
@@ -81,13 +81,15 @@ public:
 \r
        void wait()\r
        {\r
-               invoke([]{});\r
+               if(is_running_)\r
+                       invoke([]{});\r
        }\r
 \r
        void clear()\r
        {\r
                std::function<void()> func;\r
-               while(true)\r
+               auto size = execution_queue_.size();\r
+               for(int n = 0; n < size; ++n)\r
                {\r
                        try\r
                        {\r
index 08ab5b7f06222f4e6c463ac6fc73da7f84ac63c1..ae9024da5cc9fd14f10912f79e4f9906bce05cae 100644 (file)
@@ -85,7 +85,7 @@ private:
 \r
        void render(sf::RenderTarget& target)\r
        {\r
-               auto count = std::max<size_t>(10, drawables_.size());\r
+               auto count = std::max<size_t>(8, drawables_.size());\r
                float target_dy = 1.0f/static_cast<float>(count);\r
 \r
                float last_y = 0.0f;\r
@@ -241,11 +241,19 @@ public:
 struct graph::implementation : public drawable\r
 {\r
        std::map<std::string, diagnostics::line> lines_;\r
+       const printer parent_printer_;\r
        std::string name_;\r
-       std::string display_name_;\r
+\r
+       int counter_;\r
 \r
        implementation(const std::string& name) \r
-               : name_(name), display_name_(name_){}\r
+               : name_(name)\r
+               , counter_(0){}\r
+\r
+       implementation(const printer& parent_printer) \r
+               : parent_printer_(parent_printer)\r
+               , name_(parent_printer_ ? narrow(parent_printer_()) : "")\r
+               , counter_(0){}\r
 \r
        void update(const std::string& name, float value)\r
        {\r
@@ -286,34 +294,32 @@ struct graph::implementation : public drawable
                        lines_[name].guide(diagnostics::guide(value));\r
                });\r
        }\r
-\r
-       void set_display_name(const std::string& name)\r
-       {\r
-               context::begin_invoke([=]\r
-               {\r
-                       display_name_ = name;\r
-               });     \r
-       }\r
-\r
+       \r
 private:\r
        void render(sf::RenderTarget& target)\r
        {\r
+               if(counter_++ > 25) // Don't update name too often since print can be implemented with locks.\r
+               {\r
+                       counter_ = 0;\r
+                       if(parent_printer_)\r
+                               name_ = narrow(parent_printer_());\r
+               }\r
                const size_t text_size = 15;\r
                const size_t text_margin = 2;\r
-               const size_t text_offset = text_size+text_margin*2;\r
+               const size_t text_offset = (text_size+text_margin*2)*2;\r
 \r
-               sf::String text(display_name_.c_str(), sf::Font::GetDefaultFont(), text_size);\r
+               sf::String text(name_.c_str(), sf::Font::GetDefaultFont(), text_size);\r
                text.SetStyle(sf::String::Italic);\r
                text.Move(text_margin, text_margin);\r
                \r
                glPushMatrix();\r
                        glScaled(1.0f/GetScale().x, 1.0f/GetScale().y, 1.0f);\r
                        target.Draw(text);\r
-                       float x_offset = text.GetPosition().x + text.GetRect().Right + text_margin*4;\r
+                       float x_offset = text_margin;\r
                        for(auto it = lines_.begin(); it != lines_.end(); ++it)\r
                        {                                               \r
                                sf::String line_text(it->first, sf::Font::GetDefaultFont(), text_size);\r
-                               line_text.SetPosition(x_offset, text_margin);\r
+                               line_text.SetPosition(x_offset, text_margin+text_offset/2);\r
                                auto c = it->second.get_color();\r
                                line_text.SetColor(sf::Color(c.red*255.0f, c.green*255.0f, c.blue*255.0f, c.alpha*255.0f));\r
                                target.Draw(line_text);\r
@@ -354,16 +360,25 @@ graph::graph(const std::string& name) : impl_(env::properties().get("configurati
                context::register_drawable(impl_);\r
 }\r
 \r
+graph::graph(const printer& parent_printer) : impl_(env::properties().get("configuration.diagnostics.graphs", true) ? new implementation(parent_printer) : nullptr)\r
+{\r
+       if(impl_)\r
+               context::register_drawable(impl_);\r
+}\r
+\r
 void graph::update(const std::string& name, float value){if(impl_)impl_->update(name, value);}\r
 void graph::set(const std::string& name, float value){if(impl_)impl_->set(name, value);}\r
 void graph::tag(const std::string& name){if(impl_)impl_->tag(name);}\r
 void graph::guide(const std::string& name, float value){if(impl_)impl_->guide(name, value);}\r
 void graph::set_color(const std::string& name, color c){if(impl_)impl_->set_color(name, c);}\r
-void graph::set_display_name(const std::string& name){if(impl_)impl_->set_display_name(name);}\r
 \r
 safe_ptr<graph> create_graph(const std::string& name)\r
 {\r
        return safe_ptr<graph>(new graph(name));\r
 }\r
+safe_ptr<graph> create_graph(const printer& parent_printer)\r
+{\r
+       return safe_ptr<graph>(new graph(parent_printer));\r
+}\r
 \r
 }}
\ No newline at end of file
index bb6d6646003aa642885293bc1f7f4695261bca82..aab1136326bd97d236865acc7644497b7f663e08 100644 (file)
@@ -2,6 +2,8 @@
 \r
 #include "../memory/safe_ptr.h"\r
 \r
+#include "../utility/printable.h"\r
+\r
 #include <string>\r
 \r
 namespace caspar { namespace diagnostics {\r
@@ -23,19 +25,21 @@ struct color
 class graph\r
 {\r
        friend safe_ptr<graph> create_graph(const std::string& name);\r
+       friend safe_ptr<graph> create_graph(const printer& parent_printer);\r
        graph(const std::string& name);\r
+       graph(const printer& parent_printer);\r
 public:\r
        void update(const std::string& name, float value);\r
        void set(const std::string& name, float value);\r
        void tag(const std::string& name);\r
        void guide(const std::string& name, float value);\r
        void set_color(const std::string& name, color c);\r
-       void set_display_name(const std::string& name);\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
 \r
 safe_ptr<graph> create_graph(const std::string& name);\r
+safe_ptr<graph> create_graph(const printer& parent_printer);\r
        \r
 }}
\ No newline at end of file
index acc17eb6acd2f2f4ec3b5ae2bdc6a8800173da1f..7b214870e3baf13f6d124f223d1942e520cda6c8 100644 (file)
@@ -4,11 +4,15 @@
 #include <type_traits>\r
 #include <exception>\r
 \r
+#include <tbb/spin_mutex.h>\r
+\r
 namespace caspar {\r
        \r
 template<typename T>\r
 class safe_ptr\r
 {      \r
+       std::shared_ptr<T> impl_;\r
+       tbb::spin_mutex mutex_;\r
        template <typename> friend class safe_ptr;\r
 public:\r
        typedef T element_type;\r
@@ -105,9 +109,6 @@ public:
        \r
        template<class D, class U> \r
        D* get_deleter(safe_ptr<U> const& ptr) { return impl_.get_deleter(); }  // noexcept\r
-       \r
-private:       \r
-       std::shared_ptr<T> impl_;\r
 };\r
 \r
 template<class T, class U>\r
index 32602e3a734ef62183d7969b09bb411915c596b6..b68e6c06d5a756e799550413562c4a836e9dbb4d 100644 (file)
@@ -29,36 +29,35 @@ namespace caspar { namespace core {
 struct channel::implementation : boost::noncopyable\r
 {                                      \r
        const int index_;\r
+       const video_format_desc format_desc_;\r
 \r
        std::shared_ptr<frame_consumer_device>  consumer_;\r
        std::shared_ptr<frame_mixer_device>             mixer_;\r
        std::shared_ptr<frame_producer_device>  producer_;\r
 \r
-       const video_format_desc format_desc_;\r
-\r
 public:\r
        implementation(int index, const video_format_desc& format_desc)  \r
                : index_(index)\r
                , format_desc_(format_desc)\r
-               , consumer_(new frame_consumer_device(format_desc))\r
-               , mixer_(new frame_mixer_device(format_desc, std::bind(&frame_consumer_device::send, consumer_.get(), std::placeholders::_1)))\r
-               , producer_(new frame_producer_device(safe_ptr<frame_factory>(mixer_), std::bind(&frame_mixer_device::send, mixer_.get(), std::placeholders::_1), std::bind(&implementation::print, this)))     {}\r
+               , consumer_(new frame_consumer_device(std::bind(&implementation::print, this), format_desc))\r
+               , mixer_(new frame_mixer_device(std::bind(&implementation::print, this), format_desc, std::bind(&frame_consumer_device::send, consumer_.get(), std::placeholders::_1)))\r
+               , producer_(new frame_producer_device(std::bind(&implementation::print, this), safe_ptr<frame_factory>(mixer_), std::bind(&frame_mixer_device::send, mixer_.get(), std::placeholders::_1)))     {}\r
 \r
        ~implementation()\r
        {\r
                // Shutdown order is important! Destroy all created frames to mixer before destroying mixer.\r
-               CASPAR_LOG(info) << print() << " shutting down channel.";\r
+               CASPAR_LOG(info) << print() << " Shutting down channel.";\r
                producer_.reset();\r
-               CASPAR_LOG(info) << print() << "successfully shut down producer-device.";\r
+               CASPAR_LOG(info) << print() << " Successfully shut down producer-device.";\r
                consumer_.reset();\r
-               CASPAR_LOG(info) << print() << "successfully shut down consumer-device.";\r
+               CASPAR_LOG(info) << print() << " Successfully shut down consumer-device.";\r
                mixer_.reset();\r
-               CASPAR_LOG(info) << print() << "successfully shut down mixer-device.";\r
+               CASPAR_LOG(info) << print() << " Successfully shut down mixer-device.";\r
        }\r
 \r
        std::wstring print() const\r
        {\r
-               return L"channel[" + boost::lexical_cast<std::wstring>(index_) + L"]";\r
+               return L"channel[" + format_desc_.name + L", " + boost::lexical_cast<std::wstring>(index_+1) + L"]";\r
        }\r
 };\r
 \r
@@ -68,5 +67,6 @@ frame_producer_device& channel::producer() { return *impl_->producer_;}
 frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \r
 frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \r
 const video_format_desc& channel::get_video_format_desc() const{return impl_->format_desc_;}\r
+std::wstring channel::print() const { return impl_->print();}\r
 \r
 }}
\ No newline at end of file
index ddb16b49e2c1937af71334c8458ac3698dbf4f1f..ce895debfe9e9f4cc8679df5cf349060698201be 100644 (file)
@@ -33,6 +33,8 @@ public:
 \r
        const video_format_desc& get_video_format_desc() const;\r
 \r
+       std::wstring print() const;\r
+\r
 private:\r
        struct implementation;\r
        safe_ptr<implementation> impl_;\r
index f3cbb5085db204c0f5948b9a8892440c8f277576..c4cc97ac1af4a2d6ddd9b13731005d7659b50f0f 100644 (file)
@@ -83,6 +83,7 @@ void blue_initialize()
                \r
 struct bluefish_consumer::implementation : boost::noncopyable\r
 {\r
+       printer                         parent_printer_;\r
        std::wstring            model_name_;\r
        const unsigned int      device_index_;\r
 \r
@@ -244,6 +245,11 @@ public:
 \r
                CASPAR_LOG(info) << print() << TEXT(" Successfully initialized for ") << format_desc_ << TEXT(".");\r
        }\r
+\r
+       void set_parent_printer(const printer& parent_printer)\r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
        \r
        void enable_video_output()\r
        {\r
@@ -342,13 +348,14 @@ public:
        \r
        std::wstring print() const\r
        {\r
-               return model_name_ + L" [output-" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
        }\r
 };\r
 \r
 bluefish_consumer::bluefish_consumer(bluefish_consumer&& other) : impl_(std::move(other.impl_)){}\r
 bluefish_consumer::bluefish_consumer(unsigned int device_index, bool embed_audio) : impl_(new implementation(device_index, embed_audio)){}     \r
 void bluefish_consumer::initialize(const video_format_desc& format_desc){impl_->initialize(format_desc);}\r
+void bluefish_consumer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 void bluefish_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
 size_t bluefish_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
        \r
index 814b6abbd375b0fd1e8b35c414daf6cd53e9f06c..2fae9d1a55a92532689c18b0760fc7897ff52e8c 100644 (file)
@@ -33,6 +33,7 @@ public:
        bluefish_consumer(bluefish_consumer&& other);\r
        \r
        virtual void initialize(const video_format_desc& format_desc);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual void send(const safe_ptr<const read_frame>&);\r
        virtual size_t buffer_depth() const;\r
 private:\r
index 3811a141c44dc70a9768eca910f5efbf5a0bb618..3bfa9b2ec37e3157567ac6125fef14d4dc21dcf0 100644 (file)
@@ -59,6 +59,7 @@ struct decklink_output : public IDeckLinkVideoOutputCallback, public IDeckLinkAu
                ~co_init(){CoUninitialize();}\r
        } co_;\r
        \r
+       const printer   parent_printer_;\r
        std::wstring    model_name_;\r
        const size_t    device_index_;\r
 \r
@@ -86,8 +87,9 @@ struct decklink_output : public IDeckLinkVideoOutputCallback, public IDeckLinkAu
        tbb::concurrent_bounded_queue<safe_ptr<const read_frame>> audio_frame_buffer_;\r
 \r
 public:\r
-       decklink_output(size_t device_index, bool embed_audio, bool internalKey) \r
-               : model_name_(L"DECKLINK")\r
+       decklink_output(const printer& parent_printer, size_t device_index, bool embed_audio, bool internalKey) \r
+               : parent_printer_(parent_printer)\r
+               , model_name_(L"DECKLINK")\r
                , device_index_(device_index)\r
                , audio_container_(5)\r
                , embed_audio_(embed_audio)\r
@@ -272,12 +274,13 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return model_name_ + L" [output-" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
        }\r
 };\r
 \r
 struct decklink_consumer::implementation\r
 {\r
+       printer parent_printer_;\r
        std::unique_ptr<decklink_output> input_;\r
 \r
        executor executor_;\r
@@ -289,7 +292,7 @@ public:
                executor_.start();\r
                executor_.invoke([&]\r
                {\r
-                       input_.reset(new decklink_output(device_index, embed_audio, internalKey));\r
+                       input_.reset(new decklink_output(parent_printer_, device_index, embed_audio, internalKey));\r
                });\r
        }\r
 \r
@@ -309,6 +312,11 @@ public:
                });\r
        }\r
 \r
+       void set_parent_printer(const printer& parent_printer)\r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
+\r
        void send(const safe_ptr<const read_frame>& frame)\r
        {\r
                input_->send(frame);\r
@@ -323,6 +331,7 @@ public:
 decklink_consumer::decklink_consumer(size_t device_index, bool embed_audio, bool internalKey) : impl_(new implementation(device_index, embed_audio, internalKey)){}\r
 decklink_consumer::decklink_consumer(decklink_consumer&& other) : impl_(std::move(other.impl_)){}\r
 void decklink_consumer::initialize(const video_format_desc& format_desc){impl_->initialize(format_desc);}\r
+void decklink_consumer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 void decklink_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
 size_t decklink_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
        \r
index 5242c7a3c723a2a1159f64f399bc610208a2a850..025110a13ccb27e621b5ba4354cf1e8da140528c 100644 (file)
@@ -32,6 +32,7 @@ public:
        decklink_consumer(decklink_consumer&& other);\r
        \r
        virtual void initialize(const video_format_desc& format_desc);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual void send(const safe_ptr<const read_frame>&);\r
        virtual size_t buffer_depth() const;\r
 private:\r
index f70d70b3e4243bbc8d5902f73017b7443968b5a9..733a9a9da02f97b4a63fc3dcccfe4a8255fe9e3d 100644 (file)
@@ -54,6 +54,7 @@ namespace caspar { namespace core {
        \r
 struct ffmpeg_consumer::implementation : boost::noncopyable\r
 {              \r
+       printer parent_printer_;\r
        const std::string filename_;\r
 \r
        // Audio\r
@@ -187,6 +188,11 @@ public:
                \r
                av_write_header(oc_.get()); // write the stream header, if any \r
        }\r
+       \r
+       void set_parent_printer(const printer& parent_printer) \r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
 \r
        AVStream* add_video_stream(enum CodecID codec_id)\r
        { \r
@@ -392,6 +398,7 @@ ffmpeg_consumer::ffmpeg_consumer(ffmpeg_consumer&& other) : impl_(std::move(othe
 void ffmpeg_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
 size_t ffmpeg_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 void ffmpeg_consumer::initialize(const video_format_desc& format_desc) {impl_->initialize(format_desc);}\r
+void ffmpeg_consumer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 \r
 safe_ptr<frame_consumer> create_ffmpeg_consumer(const std::vector<std::wstring>& params)\r
 {\r
index e7992bfddba96fe110238001a26f3a20c746ba66..6465dc338627f48854833020c2449b4f7f0d1924 100644 (file)
@@ -31,6 +31,7 @@ public:
        ffmpeg_consumer(ffmpeg_consumer&& other);\r
        \r
        virtual void initialize(const video_format_desc& format_desc);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual void send(const safe_ptr<const read_frame>&);\r
        virtual size_t buffer_depth() const;\r
 private:\r
index 0f7444d1e427149cf6c7c2fb2a4d03f540d8a7ef..7c17859adaf620266bc6a08260c0997ce0a98d8e 100644 (file)
@@ -23,6 +23,8 @@
 \r
 #include <boost/noncopyable.hpp>\r
 \r
+#include <common/utility/printable.h>\r
+\r
 namespace caspar { namespace core {\r
        \r
 class read_frame;\r
@@ -35,6 +37,7 @@ struct frame_consumer : boost::noncopyable
        virtual void send(const safe_ptr<const read_frame>& frame) = 0;\r
        virtual size_t buffer_depth() const = 0;\r
        virtual void initialize(const video_format_desc& format_desc) = 0;\r
+       virtual void set_parent_printer(const printer& parent_printer) = 0;\r
 \r
        static const safe_ptr<frame_consumer>& empty()\r
        {\r
@@ -43,6 +46,7 @@ struct frame_consumer : boost::noncopyable
                        virtual void send(const safe_ptr<const read_frame>&){}\r
                        virtual size_t buffer_depth() const{return 0;}\r
                        void initialize(const video_format_desc&){}\r
+                       void set_parent_printer(const printer&){}\r
                };\r
                static safe_ptr<frame_consumer> consumer = make_safe<empty_frame_consumer>();\r
                return consumer;\r
index cbff69a9ebe7676c8b21ce3c6de74a20fad2820e..db5c2e34a5e752fdc1167376309313a04eb0a93b 100644 (file)
@@ -21,6 +21,7 @@ namespace caspar { namespace core {
        \r
 struct frame_consumer_device::implementation\r
 {      \r
+       const printer parent_printer_;\r
        timer clock_;\r
 \r
        boost::circular_buffer<safe_ptr<const read_frame>> buffer_;\r
@@ -31,8 +32,9 @@ struct frame_consumer_device::implementation
        \r
        executor executor_;     \r
 public:\r
-       implementation(const video_format_desc& format_desc) \r
-               : format_desc_(format_desc)\r
+       implementation(const printer& parent_printer, const video_format_desc& format_desc) \r
+               : parent_printer_(parent_printer)\r
+               , format_desc_(format_desc)\r
                , executor_(L"frame_consumer_device")\r
        {               \r
                executor_.set_capacity(2);\r
@@ -51,6 +53,7 @@ public:
 \r
        void add(int index, safe_ptr<frame_consumer>&& consumer)\r
        {               \r
+               consumer->set_parent_printer(std::bind(&implementation::print, this));\r
                consumer->initialize(format_desc_);\r
                executor_.invoke([&]\r
                {\r
@@ -98,10 +101,15 @@ public:
                        clock_.tick(1.0/format_desc_.fps);\r
                });\r
        }\r
+\r
+       std::wstring print() const\r
+       {\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"consumer";\r
+       }\r
 };\r
 \r
 frame_consumer_device::frame_consumer_device(frame_consumer_device&& other) : impl_(std::move(other.impl_)){}\r
-frame_consumer_device::frame_consumer_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+frame_consumer_device::frame_consumer_device(const printer& parent_printer, const video_format_desc& format_desc) : impl_(new implementation(parent_printer, format_desc)){}\r
 void frame_consumer_device::add(int index, safe_ptr<frame_consumer>&& consumer){impl_->add(index, std::move(consumer));}\r
 void frame_consumer_device::remove(int index){impl_->remove(index);}\r
 void frame_consumer_device::send(const safe_ptr<const read_frame>& future_frame) { impl_->send(future_frame); }\r
index 7b9c9a96f07f9c5d10f8338e316b6e7f2c2d1559..77434446deea6ee28ce012fc2d3c02f584fc32f9 100644 (file)
@@ -3,6 +3,7 @@
 #include "../consumer/frame_consumer.h"\r
 \r
 #include <common/memory/safe_ptr.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <vector>\r
 \r
@@ -16,7 +17,7 @@ struct video_format_desc;
 class frame_consumer_device : boost::noncopyable\r
 {\r
 public:\r
-       explicit frame_consumer_device(const video_format_desc& format_desc);\r
+       explicit frame_consumer_device(const printer& parent_printer, const video_format_desc& format_desc);\r
        frame_consumer_device(frame_consumer_device&& other);\r
 \r
        void add(int index, safe_ptr<frame_consumer>&& consumer);\r
index bcb41bf07822da3d7c6b367c2abd30e55e97b78b..5b49ab61dfd8ce70971d8b82e73699fe749dee1b 100644 (file)
@@ -36,6 +36,7 @@ namespace caspar { namespace core {
 \r
 struct oal_consumer::implementation : public sf::SoundStream, boost::noncopyable\r
 {\r
+       printer parent_printer_;\r
        safe_ptr<diagnostics::graph> graph_;\r
        timer perf_timer_;\r
 \r
@@ -72,7 +73,12 @@ public:
                Play();         \r
                CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
        }\r
-       \r
+\r
+       void set_parent_printer(const printer& parent_printer)\r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
+                       \r
        void send(const safe_ptr<const read_frame>& frame)\r
        {                               \r
                if(!frame->audio_data().empty())\r
@@ -100,7 +106,7 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"Default Audio Device [output]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"oal";\r
        }\r
 };\r
 \r
@@ -109,6 +115,7 @@ oal_consumer::oal_consumer() : impl_(new implementation()){}
 void oal_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
 size_t oal_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 void oal_consumer::initialize(const video_format_desc& format_desc){impl_->initialize(format_desc);}\r
+void oal_consumer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 \r
 safe_ptr<frame_consumer> create_oal_consumer(const std::vector<std::wstring>& params)\r
 {\r
index 3f07675adcfac64f0ac23fab0b555137bb335e2f..759bad70c35067e83f50dc1f950d4824b2851f8e 100644 (file)
@@ -31,6 +31,8 @@ public:
        oal_consumer(oal_consumer&& other);\r
 \r
        virtual void initialize(const video_format_desc& format_desc);  \r
+       virtual void set_parent_printer(const printer& parent_printer);\r
+\r
        virtual void send(const safe_ptr<const read_frame>&);\r
        virtual size_t buffer_depth() const;\r
 private:\r
index 223860dda796b899b1a19cec3af3473c4574a682..d2f0372f282170d0aaddd6bcd5042fc141d7ec89 100644 (file)
@@ -43,7 +43,8 @@
 namespace caspar { namespace core {\r
 \r
 struct ogl_consumer::implementation : boost::noncopyable\r
-{                      \r
+{              \r
+       printer parent_printer_;\r
        boost::unique_future<void> active_;\r
 \r
        float wratio_;\r
@@ -80,11 +81,10 @@ public:
                , screen_y_(0)\r
                , screen_index_(screen_index)\r
                , graph_(diagnostics::create_graph(narrow(print())))\r
+               , executor_(print())\r
        {               \r
                graph_->guide("frame-time", 0.5);\r
                graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
-\r
-               CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
        }\r
 \r
        ~implementation()\r
@@ -141,7 +141,7 @@ public:
                executor_.start();\r
                executor_.invoke([=]\r
                {\r
-                       window_.Create(sf::VideoMode(format_desc_.width, format_desc_.height, 32), "CasparCG", windowed_ ? sf::Style::Titlebar : sf::Style::Fullscreen);\r
+                       window_.Create(sf::VideoMode(format_desc_.width, format_desc_.height, 32), narrow(print()), windowed_ ? sf::Style::Titlebar : sf::Style::Fullscreen);\r
                        window_.ShowMouseCursor(false);\r
                        window_.SetPosition(screen_x_, screen_y_);\r
                        window_.SetSize(screen_width_, screen_height_);\r
@@ -184,6 +184,12 @@ public:
                        glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);\r
                });\r
                active_ = executor_.begin_invoke([]{});\r
+               CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
+       }\r
+\r
+       void set_parent_printer(const printer& parent_printer)\r
+       {\r
+               parent_printer_ = parent_printer;\r
        }\r
        \r
        std::pair<float, float> None()\r
@@ -269,7 +275,7 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"OpenGL Device [output-" + boost::lexical_cast<std::wstring>(screen_index_) + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"ogl[" + boost::lexical_cast<std::wstring>(screen_index_) + L"]";\r
        }\r
 \r
        size_t buffer_depth() const{return 2;}\r
@@ -280,6 +286,7 @@ ogl_consumer::ogl_consumer(unsigned int screen_index, stretch stretch, bool wind
 void ogl_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
 size_t ogl_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 void ogl_consumer::initialize(const video_format_desc& format_desc){impl_->initialize(format_desc);}\r
+void ogl_consumer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 \r
 safe_ptr<frame_consumer> create_ogl_consumer(const std::vector<std::wstring>& params)\r
 {\r
index 487f7c3aa7c761c317a7ed0c8767a393a7880501..fe6eaca83e6b4ec8b3fa462241244177d73cf9a3 100644 (file)
@@ -41,6 +41,7 @@ public:
        ogl_consumer(ogl_consumer&& other);\r
        \r
        virtual void initialize(const video_format_desc& format_desc);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual void send(const safe_ptr<const read_frame>&);\r
        virtual size_t buffer_depth() const;\r
 private:\r
index 1f8484e5517c9ce2ff7f40dfa96c69774a166fac..58f6888a8753c72ed2eedbcd4e7abae43f17a59a 100644 (file)
@@ -36,7 +36,9 @@ class color_producer : public frame_producer
 \r
 public:\r
 \r
-       explicit color_producer(const std::wstring& color) : color_str_(color), frame_(draw_frame::empty())\r
+       explicit color_producer(const std::wstring& color) \r
+               : color_str_(color)\r
+               , frame_(draw_frame::empty())\r
        {\r
                if(color.length() != 9 || color[0] != '#')\r
                        BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(narrow(color)) << msg_info("Invalid color code"));\r
index 879a9fd1680a9bed34f39302b8b6e8a1041617c4..481125b834b16896c9e40647fdd72dcd5ce3d627 100644 (file)
@@ -46,6 +46,8 @@
 \r
 #pragma warning(push)\r
 \r
+#include <functional>\r
+\r
 namespace caspar { namespace core {\r
 \r
 class decklink_input : public IDeckLinkInputCallback\r
@@ -103,7 +105,7 @@ public:
                decklink_->GetModelName(&pModelName);\r
                model_name_ = std::wstring(pModelName);\r
 \r
-               graph_ = diagnostics::create_graph(narrow(print()));\r
+               graph_ = diagnostics::create_graph(boost::bind(&decklink_input::print, this));\r
                graph_->guide("tick-time", 0.5);\r
                graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
                \r
index 80c3c6bb84c7b8785d2267071ae408b737140c9a..342c98c688e6145560b11de1c39cac847c9ed063 100644 (file)
@@ -17,6 +17,7 @@
 #include <tbb/parallel_invoke.h>\r
 \r
 #include <deque>\r
+#include <functional>\r
 \r
 namespace caspar { namespace core { namespace ffmpeg{\r
        \r
@@ -26,7 +27,7 @@ struct ffmpeg_producer : public frame_producer
        const bool                                                      loop_;\r
        printer                                                         parent_printer_;\r
        \r
-       safe_ptr<diagnostics::graph>            graph_;\r
+       std::shared_ptr<diagnostics::graph>     graph_;\r
        timer                                                           perf_timer_;\r
                \r
        std::unique_ptr<audio_decoder>          audio_decoder_;\r
@@ -44,24 +45,19 @@ struct ffmpeg_producer : public frame_producer
 public:\r
        explicit ffmpeg_producer(const std::wstring& filename, bool loop) \r
                : filename_(filename)\r
-               , loop_(loop)\r
-               , graph_(diagnostics::create_graph(narrow(print())))            \r
+               , loop_(loop) \r
                , last_frame_(draw_frame(draw_frame::empty()))\r
                \r
        {\r
+               graph_ = diagnostics::create_graph(boost::bind(&ffmpeg_producer::print, this)); \r
                graph_->guide("frame-time", 0.5);\r
                graph_->set_color("frame-time",  diagnostics::color(1.0f, 0.0f, 0.0f));\r
        }\r
-\r
-       ~ffmpeg_producer()\r
-       {\r
-               CASPAR_LOG(info) << print() << " stopping.";\r
-       }\r
-\r
+       \r
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
        {\r
                frame_factory_ = frame_factory;\r
-               input_.reset(new input(graph_, filename_, loop_, std::bind(&ffmpeg_producer::print, this)));\r
+               input_.reset(new input(safe_ptr<diagnostics::graph>(graph_), filename_, loop_, std::bind(&ffmpeg_producer::print, this)));\r
                video_decoder_.reset(input_->get_video_codec_context().get() ? new video_decoder(input_->get_video_codec_context().get(), frame_factory) : nullptr);\r
                audio_decoder_.reset(input_->get_audio_codec_context().get() ? new audio_decoder(input_->get_audio_codec_context().get(), frame_factory->get_video_format_desc().fps) : nullptr);\r
        }\r
index fb4fa539ec952b5954140811c60f50d56f47d4f0..b8f89728873a084629b121a1c45526a3b209278f 100644 (file)
@@ -211,7 +211,7 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"[async_input]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"async_input";\r
        }\r
 };\r
 \r
index fc808b3bb51146ff4f19aca1821c2868484c3ddb..9488376e59a7862a1d002a24c310addf5c197da5 100644 (file)
@@ -38,6 +38,8 @@
 \r
 #include <boost/filesystem.hpp>\r
 \r
+#include <functional>\r
+\r
 namespace caspar { namespace core { namespace flash {\r
                \r
 bool interlaced(double fps, const video_format_desc& format_desc)\r
@@ -197,7 +199,7 @@ struct flash_producer::implementation
        const std::wstring filename_;   \r
        tbb::atomic<int> fps_;\r
 \r
-       safe_ptr<diagnostics::graph> graph_;\r
+       std::shared_ptr<diagnostics::graph> graph_;\r
 \r
        safe_ptr<draw_frame> tail_;\r
        tbb::concurrent_bounded_queue<safe_ptr<draw_frame>> frame_buffer_;\r
@@ -214,24 +216,17 @@ struct flash_producer::implementation
                                        boost::lexical_cast<std::wstring>(fps_) + \r
                                        (interlaced(fps_, format_desc_) ? L"i" : L"p") + L"]";          \r
        }       \r
-\r
-       void set_fps(double fps)\r
-       {\r
-               int fps100 = static_cast<int>(renderer_->fps()*100.0);\r
-               if(fps_.fetch_and_store(fps100) != fps100)\r
-                       graph_->set_display_name(narrow(print()));      \r
-       }\r
-       \r
+               \r
 public:\r
        implementation(const std::wstring& filename) \r
-               : filename_(filename)\r
-               , graph_(diagnostics::create_graph(narrow(print())))\r
+               : filename_(filename)           \r
                , tail_(draw_frame::empty())            \r
                , executor_(print())\r
        {       \r
                if(!boost::filesystem::exists(filename))\r
                        BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));  \r
-\r
+                \r
+               graph_ = diagnostics::create_graph(boost::bind(&implementation::print, this));\r
                fps_ = 0;\r
                graph_->set_color("output-buffer", diagnostics::color(0.0f, 1.0f, 0.0f));       \r
        }\r
@@ -278,7 +273,7 @@ public:
                                do{frame = renderer_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()-2);}\r
                                while(frame_buffer_.try_push(frame) && frame == draw_frame::empty());\r
                                graph_->set("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity()));    \r
-                               set_fps(renderer_->fps());\r
+                               fps_.fetch_and_store(static_cast<int>(renderer_->fps()*100.0));\r
                        }\r
                        catch(...)\r
                        {\r
@@ -296,7 +291,7 @@ public:
                {\r
                        if(!renderer_)\r
                        {\r
-                               renderer_.reset(new flash_renderer(graph_, frame_factory_, filename_, [=]{return print();}));\r
+                               renderer_.reset(new flash_renderer(safe_ptr<diagnostics::graph>(graph_), frame_factory_, filename_, [=]{return print();}));\r
                                while(frame_buffer_.try_push(draw_frame::empty())){}            \r
                        }\r
 \r
index a43fc8f89520a8cd2fb619884a87b75cfcd8c4aa..32c8b3e1bc951e0c027b1d73ca83997d692a7597 100644 (file)
@@ -35,13 +35,13 @@ struct frame_producer_device::implementation : boost::noncopyable
        mutable executor executor_;\r
 \r
 public:\r
-       implementation(const safe_ptr<frame_factory>& factory, const output_func& output, const printer& parent_printer)  \r
+       implementation(const printer& parent_printer, const safe_ptr<frame_factory>& factory, const output_func& output)  \r
                : parent_printer_(parent_printer)\r
                , factory_(factory)\r
                , output_(output)\r
        {\r
                for(int n = 0; n < frame_producer_device::MAX_LAYER+1; ++n)\r
-                       layers_.push_back(layer(n, parent_printer_));\r
+                       layers_.push_back(layer(n, std::bind(&implementation::print, this)));\r
 \r
                executor_.start();\r
                executor_.begin_invoke([=]{tick();});\r
@@ -148,9 +148,14 @@ public:
                        return layers_.at(index).foreground();\r
                });\r
        }\r
+\r
+       std::wstring print() const\r
+       {\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"producer";\r
+       }\r
 };\r
 \r
-frame_producer_device::frame_producer_device(const safe_ptr<frame_factory>& factory, const output_func& output, const printer& printer) : impl_(new implementation(factory, output, printer)){}\r
+frame_producer_device::frame_producer_device(const printer& parent_printer, const safe_ptr<frame_factory>& factory, const output_func& output) : impl_(new implementation(parent_printer, factory, output)){}\r
 frame_producer_device::frame_producer_device(frame_producer_device&& other) : impl_(std::move(other.impl_)){}\r
 void frame_producer_device::load(size_t index, const safe_ptr<frame_producer>& producer, bool play_on_load){impl_->load(index, producer, play_on_load);}\r
 void frame_producer_device::preview(size_t index, const safe_ptr<frame_producer>& producer){impl_->preview(index, producer);}\r
index 3989c343846675c2dc67f9e34ccf30268e65ee53..8a70fafc2494e243f67eda43ae9d3c75dc3b4970 100644 (file)
@@ -30,7 +30,7 @@ public:
 \r
        typedef std::function<void(const std::vector<safe_ptr<draw_frame>>&)> output_func;\r
 \r
-       explicit frame_producer_device(const safe_ptr<frame_factory>& factory, const output_func& output, const printer& printer);\r
+       explicit frame_producer_device(const printer& parent_printer, const safe_ptr<frame_factory>& factory, const output_func& output);\r
        frame_producer_device(frame_producer_device&& other);\r
                \r
        void load(size_t index, const safe_ptr<frame_producer>& producer, bool play_on_load = false);\r
index 14ba9f3a9caa40879ef0cbb6cf07c6335607a701..f8a863d9ca4098013f6c53a93ec404e86df4b498 100644 (file)
@@ -14,7 +14,7 @@
 #include <mixer/audio/audio_mixer.h>\r
 #include <mixer/audio/audio_transform.h>\r
 \r
-#include <tbb/recursive_mutex.h>\r
+#include <tbb/spin_mutex.h>\r
 \r
 namespace caspar { namespace core {\r
 \r
@@ -27,7 +27,7 @@ class frame_producer_remover
        {\r
                auto name = producer->print();\r
                producer = frame_producer::empty();\r
-               CASPAR_LOG(info) << L"async_remover[" + boost::lexical_cast<std::wstring>(--count_) + L"] Removed: " << name << L".";\r
+               CASPAR_LOG(info) <<  name << L" Removed.";\r
        }\r
 public:\r
 \r
@@ -40,19 +40,19 @@ public:
        void remove(safe_ptr<frame_producer>&& producer)\r
        {\r
                CASPAR_ASSERT(producer.unique());\r
-               CASPAR_LOG(info) << L"async_remover[" + boost::lexical_cast<std::wstring>(++count_) + L"] Removing: " << producer->print() << L".";\r
                executor_.begin_invoke(std::bind(&frame_producer_remover::do_remove, this, std::move(producer)));\r
        }\r
 };\r
 \r
 frame_producer_remover g_remover;\r
 \r
+\r
 struct layer::implementation : boost::noncopyable\r
 {                              \r
-       tbb::recursive_mutex            mutex_;\r
+       mutable tbb::spin_mutex         printer_mutex_;\r
        printer                                         parent_printer_;\r
-       tbb::atomic<int>                        index_;\r
-\r
+       int                                                     index_;\r
+       \r
        safe_ptr<frame_producer>        foreground_;\r
        safe_ptr<frame_producer>        background_;\r
        safe_ptr<draw_frame>            last_frame_;\r
@@ -60,18 +60,14 @@ struct layer::implementation : boost::noncopyable
 public:\r
        implementation(int index, const printer& parent_printer) \r
                : parent_printer_(parent_printer)\r
+               , index_(index)\r
                , foreground_(frame_producer::empty())\r
                , background_(frame_producer::empty())\r
                , last_frame_(draw_frame::empty())\r
-               , is_paused_(false)\r
-       {\r
-               index_ = index;\r
-       }\r
+               , is_paused_(false){}\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load)\r
        {               \r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-\r
                background_ = frame_producer;\r
                is_paused_ = false;\r
                if(play_on_load)\r
@@ -80,22 +76,18 @@ public:
 \r
        void preview(const safe_ptr<frame_producer>& frame_producer)\r
        {\r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-\r
                load(frame_producer, true);\r
                receive();\r
                pause();\r
        }\r
        \r
        void play()\r
-       {               \r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-       \r
+       {                       \r
                if(!is_paused_)                 \r
                {\r
                        background_->set_leading_producer(foreground_);\r
                        foreground_ = background_;\r
-                       CASPAR_LOG(info) << foreground_->print() << L" Started.";\r
+                       CASPAR_LOG(info) << foreground_->print() << L" Activated.";\r
                        background_ = frame_producer::empty();\r
                }\r
                is_paused_ = false;\r
@@ -103,24 +95,18 @@ public:
 \r
        void pause()\r
        {\r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-\r
                is_paused_ = true;\r
        }\r
 \r
        void stop()\r
        {\r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-\r
                pause();\r
                last_frame_ = draw_frame::empty();\r
                foreground_ = frame_producer::empty();\r
        }\r
 \r
        void clear()\r
-       {\r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-               \r
+       {               \r
                foreground_ = frame_producer::empty();\r
                background_ = frame_producer::empty();\r
                last_frame_ = draw_frame::empty();\r
@@ -129,8 +115,6 @@ public:
        \r
        safe_ptr<draw_frame> receive()\r
        {               \r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-\r
                if(is_paused_)\r
                {\r
                        last_frame_->get_audio_transform().set_gain(0.0);\r
@@ -146,48 +130,63 @@ public:
 \r
                                auto following = foreground_->get_following_producer();\r
                                following->set_leading_producer(foreground_);\r
+                               following->set_parent_printer(boost::bind(&implementation::print, this));\r
                                g_remover.remove(std::move(foreground_));\r
                                foreground_ = following;\r
-                               CASPAR_LOG(info) << foreground_->print() << L" Started.";\r
+                               CASPAR_LOG(info) << foreground_->print() << L" Activated.";\r
 \r
                                last_frame_ = receive();\r
                        }\r
                }\r
                catch(...)\r
                {\r
-                       CASPAR_LOG(error) << print() << L"Unhandled Exception: ";\r
+                       CASPAR_LOG(error) << print() << L" Unhandled Exception: ";\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                        stop();\r
                }\r
 \r
                return last_frame_;\r
        }\r
-       \r
-       void swap(implementation& other)\r
-       {\r
-               tbb::recursive_mutex::scoped_lock lock(mutex_);\r
-               std::swap(foreground_, other.foreground_);\r
-               std::swap(background_, other.background_);\r
-               std::swap(last_frame_, other.last_frame_);\r
-               std::swap(is_paused_, other.is_paused_);\r
-       }\r
-       \r
+               \r
        std::wstring print() const\r
        {\r
-               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"layer[" + boost::lexical_cast<std::wstring>(index_) + L"]";\r
+               std::wstring parent_print = L"";\r
+               {\r
+                       tbb::spin_mutex::scoped_lock lock(printer_mutex_);\r
+                       if(parent_printer_)\r
+                               parent_print = parent_printer_() + L"/";\r
+               }\r
+               return parent_print + L"layer[" + boost::lexical_cast<std::wstring>(index_) + L"]";\r
        }\r
 };\r
 \r
-layer::layer(int index, const printer& parent_printer) : impl_(new implementation(index, parent_printer)){}\r
-layer::layer(layer&& other) : impl_(std::move(other.impl_)){}\r
+layer::layer(int index, const printer& parent_printer)\r
+{\r
+       impl_ = new implementation(index, parent_printer);\r
+}\r
+layer::~layer()\r
+{\r
+       if(!impl_)\r
+               return;\r
+\r
+       impl_->clear();\r
+       delete impl_.fetch_and_store(nullptr);\r
+}\r
+layer::layer(layer&& other)\r
+{\r
+       impl_ = other.impl_.fetch_and_store(nullptr);\r
+}\r
 layer& layer::operator=(layer&& other)\r
 {\r
-       impl_ = std::move(other.impl_);\r
+       impl_ = other.impl_.fetch_and_store(nullptr);\r
        return *this;\r
 }\r
 void layer::swap(layer& other)\r
 {\r
-       impl_->swap(*other.impl_);\r
+       impl_ = other.impl_.compare_and_swap(impl_, other.impl_);\r
+       tbb::spin_mutex::scoped_lock lock(other.impl_->printer_mutex_);\r
+       std::swap(impl_->index_, other.impl_->index_);\r
+       std::swap(impl_->parent_printer_, other.impl_->parent_printer_);\r
 }\r
 void layer::load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load){return impl_->load(frame_producer, play_on_load);} \r
 void layer::preview(const safe_ptr<frame_producer>& frame_producer){return impl_->preview(frame_producer);}    \r
index 556183f7e6e2f940ef5bd22d7f163ac4d65a60cd..b21caaa13aab03294504fb07528284399799b25e 100644 (file)
@@ -18,6 +18,7 @@ class layer : boost::noncopyable
 {\r
 public:\r
        layer(int index, const printer& parent_printer = nullptr); // nothrow\r
+       ~layer();\r
        layer(layer&& other); // nothrow\r
        layer& operator=(layer&& other); // nothrow\r
 \r
@@ -38,7 +39,7 @@ public:
        std::wstring print() const;\r
 private:\r
        struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
+       tbb::atomic<implementation*> impl_;\r
 };\r
 \r
 }}
\ No newline at end of file
index 1e0feb6a09839beaadb3662bf7abef005c074030..bb74d6d8715f8e463c71d179df7e0a89ebc681ae 100644 (file)
@@ -51,6 +51,7 @@ struct transition_producer::implementation : boost::noncopyable
                , dest_producer_(dest)\r
                , source_producer_(frame_producer::empty())\r
        {\r
+               dest_producer_->set_parent_printer(std::bind(&implementation::dest_print, this));\r
                frame_buffer_.push_back(draw_frame::empty());\r
        }\r
                                \r
@@ -63,7 +64,6 @@ struct transition_producer::implementation : boost::noncopyable
 \r
        virtual void set_parent_printer(const printer& parent_printer) \r
        {\r
-               dest_producer_->set_parent_printer(std::bind(&implementation::print, this));\r
                parent_printer_ = parent_printer;\r
        }\r
 \r
@@ -75,6 +75,7 @@ struct transition_producer::implementation : boost::noncopyable
        void set_leading_producer(const safe_ptr<frame_producer>& producer)\r
        {\r
                source_producer_ = producer;\r
+               source_producer_->set_parent_printer(std::bind(&implementation::source_print, this));\r
        }\r
 \r
        safe_ptr<draw_frame> receive()\r
@@ -188,8 +189,11 @@ struct transition_producer::implementation : boost::noncopyable
 \r
        std::wstring print() const\r
        {\r
-               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"transition[length:" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"transition[" + info_.name() + L":" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
        }\r
+\r
+       std::wstring source_print() const { return print() + L"/source";}\r
+       std::wstring dest_print() const { return print() + L"/dest";}\r
 };\r
 \r
 transition_producer::transition_producer(transition_producer&& other) : impl_(std::move(other.impl_)){}\r
index 5a2f1698c6f065db32ab5403e3b828f02a7cca66..1cb2735f2b00a74cf22224ec14218bda342421c4 100644 (file)
@@ -51,6 +51,19 @@ struct transition_direction
 struct transition_info\r
 {\r
        transition_info() : type(transition::cut), duration(0), direction(transition_direction::from_left){}\r
+\r
+       std::wstring name() const\r
+       {\r
+               switch(type)\r
+               {\r
+               case transition::cut: return L"cut";\r
+               case transition::mix: return L"mix";\r
+               case transition::push: return L"push";\r
+               case transition::slide: return L"slide";\r
+               case transition::wipe: return L"wipe";\r
+               default: return L"";\r
+               }\r
+       }\r
        \r
        size_t                                          duration;\r
        transition_direction::type      direction;\r
index e37fd87d223d3ff8c9d4b5150ec5f16140fcdad4..b4dae9ac785bda289527632988892fc189b97444 100644 (file)
@@ -12,6 +12,7 @@
 #include <common/exception/exceptions.h>\r
 #include <common/concurrency/executor.h>\r
 #include <common/diagnostics/graph.h>\r
+#include <common/utility/assert.h>\r
 #include <common/utility/timer.h>\r
 #include <common/gl/gl_check.h>\r
 \r
@@ -28,6 +29,7 @@ namespace caspar { namespace core {
        \r
 struct frame_mixer_device::implementation : boost::noncopyable\r
 {              \r
+       const printer                   parent_printer_;\r
        const video_format_desc format_desc_;\r
 \r
        safe_ptr<diagnostics::graph> graph_;\r
@@ -44,12 +46,13 @@ struct frame_mixer_device::implementation : boost::noncopyable
 \r
        executor executor_;\r
 public:\r
-       implementation(const video_format_desc& format_desc, const output_func& output) \r
-               : format_desc_(format_desc)\r
+       implementation(const printer& parent_printer, const video_format_desc& format_desc, const output_func& output) \r
+               : parent_printer_(parent_printer)\r
+               , format_desc_(format_desc)\r
                , graph_(diagnostics::create_graph(narrow(print())))\r
                , image_mixer_(format_desc)\r
                , output_(output)\r
-               , executor_(L"frame_mixer_device")\r
+               , executor_(print())\r
        {\r
                graph_->guide("frame-time", 0.5f);      \r
                graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
@@ -62,7 +65,7 @@ public:
                \r
        ~implementation()\r
        {\r
-               CASPAR_LOG(info) << print() << L" Shutting down.";      \r
+               executor_.clear();\r
        }\r
 \r
        void send(const std::vector<safe_ptr<draw_frame>>& frames)\r
@@ -126,11 +129,11 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"Video/Audio Mixer [" + format_desc_.name + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"mixer";\r
        }\r
 };\r
        \r
-frame_mixer_device::frame_mixer_device(const video_format_desc& format_desc, const output_func& output) : impl_(new implementation(format_desc, output)){}\r
+frame_mixer_device::frame_mixer_device(const printer& parent_printer, const video_format_desc& format_desc, const output_func& output) : impl_(new implementation(parent_printer, format_desc, output)){}\r
 frame_mixer_device::frame_mixer_device(frame_mixer_device&& other) : impl_(std::move(other.impl_)){}\r
 void frame_mixer_device::send(const std::vector<safe_ptr<draw_frame>>& frames){impl_->send(frames);}\r
 const video_format_desc& frame_mixer_device::get_video_format_desc() const { return impl_->format_desc_; }\r
index b72c080171778f79f64947218023d4be363c5f1d..c64ddc393e1aa943d1d6d086c945e235cf1de42a 100644 (file)
 \r
 #include "frame_factory.h"\r
 \r
+#include "image/image_mixer.h"\r
+#include "audio/audio_mixer.h"\r
+\r
 #include "frame/write_frame.h"\r
 #include "frame/pixel_format.h"\r
 \r
 #include <common/memory/safe_ptr.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <functional>\r
 \r
-#include "image/image_mixer.h"\r
-#include "audio/audio_mixer.h"\r
-\r
 namespace caspar { namespace core {\r
        \r
 struct video_format;\r
@@ -42,7 +43,7 @@ class frame_mixer_device : public frame_factory
 public:\r
        typedef std::function<void(const safe_ptr<const read_frame>&)> output_func;\r
 \r
-       frame_mixer_device(const video_format_desc& format_desc, const output_func& output);\r
+       frame_mixer_device(const printer& parent_printer, const video_format_desc& format_desc, const output_func& output);\r
        frame_mixer_device(frame_mixer_device&& other); // nothrow\r
                \r
        void send(const std::vector<safe_ptr<draw_frame>>& frames); // nothrow\r
index 7f969638fa1f997937c85dde331960a9196a4d0a..70e65894ebb9df69e536ce2dc2da1607486086c5 100644 (file)
         </bluefish>-->\r
       </consumers>\r
     </channel>\r
-  </channels>\r
+    <channel>\r
+      <videomode>PAL</videomode>\r
+      <consumers>\r
+        <ogl>\r
+          <device>1</device>\r
+          <stretch>uniform</stretch>\r
+          <windowed>true</windowed>\r
+        </ogl>\r
+      </consumers>\r
+    </channel>\r
+</channels>\r
   <controllers>\r
     <tcp>\r
       <port>5250</port>\r
index 2acb40d4290579894813d485ca3c88a30359be57..5118e59f23e24f81504356f60efe6c0099de54e3 100644 (file)
@@ -75,6 +75,31 @@ public:
                //CASPAR_LOG(debug) << L"Stopped TBB Worker Thread.";\r
        }\r
 };\r
+\r
+void setup_console_window()\r
+{      \r
+       auto hOut = GetStdHandle(STD_OUTPUT_HANDLE);\r
+\r
+       EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED);\r
+       DrawMenuBar(GetConsoleWindow());\r
+\r
+       auto coord = GetLargestConsoleWindowSize(hOut);\r
+       coord.X /= 2;\r
+\r
+       SetConsoleScreenBufferSize(hOut, coord);\r
+\r
+       SMALL_RECT DisplayArea = {0, 0, 0, 0};\r
+       DisplayArea.Right = coord.X-1;\r
+       DisplayArea.Bottom = coord.Y-1;\r
+       SetConsoleWindowInfo(hOut, TRUE, &DisplayArea);\r
+               \r
+       std::wstringstream str;\r
+       str << "CasparCG Server " << env::version();\r
+       SetConsoleTitle(str.str().c_str());\r
+\r
+       std::wcout << L"Copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\n" << std::endl;\r
+       std::wcout << L"Starting CasparCG Video Playout Server Ver: " << env::version() << std::endl;\r
+}\r
  \r
 int main(int argc, wchar_t* argv[])\r
 {      \r
@@ -93,16 +118,8 @@ int main(int argc, wchar_t* argv[])
                timeBeginPeriod(1);\r
 \r
                // Start caspar\r
-               std::wstringstream str;\r
-               str << "CasparCG " << env::version();\r
-               SetConsoleTitle(str.str().c_str());\r
-\r
-               std::wcout << L"Copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\n" << std::endl;\r
-               std::wcout << L"Starting CasparCG Video Playout Server Ver: " << env::version() << std::endl;\r
 \r
-               EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED);\r
-               DrawMenuBar(GetConsoleWindow());\r
-               MoveWindow(GetConsoleWindow(), 800, 0, 800, 1000, true);\r
+               setup_console_window();\r
 \r
        #ifdef _DEBUG\r
                _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );\r
index 64ab3e90dbb604bd2c2b1d108174f17e27d150ae..6b97907a5ee79dfbee40663eb6689284b068a6b3 100644 (file)
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">$(SolutionName)</TargetName>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
-    <LinkIncremental>false</LinkIncremental>\r
+    <LinkIncremental>true</LinkIncremental>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <LinkIncremental>false</LinkIncremental>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Amplify|Win32'">\r
-    <LinkIncremental>false</LinkIncremental>\r
+    <LinkIncremental>true</LinkIncremental>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">\r
-    <LinkIncremental>false</LinkIncremental>\r
+    <LinkIncremental>true</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <PreBuildEvent>\r
       <IgnoreSpecificDefaultLibraries>LIBC.LIB;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
-      <GenerateMapFile>true</GenerateMapFile>\r
+      <GenerateMapFile>false</GenerateMapFile>\r
       <MapFileName>\r
       </MapFileName>\r
       <SubSystem>Console</SubSystem>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <IgnoreSpecificDefaultLibraries>LIBC.lib</IgnoreSpecificDefaultLibraries>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <GenerateMapFile>true</GenerateMapFile>\r
+      <GenerateMapFile>false</GenerateMapFile>\r
       <MapExports>true</MapExports>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <IgnoreSpecificDefaultLibraries>LIBC.lib</IgnoreSpecificDefaultLibraries>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <GenerateMapFile>true</GenerateMapFile>\r
+      <GenerateMapFile>false</GenerateMapFile>\r
       <MapExports>true</MapExports>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <IgnoreSpecificDefaultLibraries>LIBC.lib</IgnoreSpecificDefaultLibraries>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <GenerateMapFile>true</GenerateMapFile>\r
+      <GenerateMapFile>false</GenerateMapFile>\r
       <MapExports>true</MapExports>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>\r