]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Improved logging. Added "parent logging".
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 01:39:12 +0000 (01:39 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Feb 2011 01:39:12 +0000 (01:39 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@486 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

24 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/exception/exceptions.h
common/utility/printable.h [new file with mode: 0644]
core/channel.cpp
core/channel.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/ffmpeg/input.h
core/producer/flash/cg_producer.cpp
core/producer/flash/cg_producer.h
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/frame_producer.h
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/producer/image/image_producer.cpp
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
shell/boostrapper.cpp

index ea3f66df9ce31136838e465322ec2004dfb7659d..f0eb2ab5f2beebfd10cc0a07ba82c1950948cf7a 100644 (file)
     <ClInclude Include="env.h" />\r
     <ClInclude Include="stdafx.h" />\r
     <ClInclude Include="utility\assert.h" />\r
+    <ClInclude Include="utility\printable.h" />\r
     <ClInclude Include="utility\string_convert.h" />\r
     <ClInclude Include="utility\timer.h" />\r
   </ItemGroup>\r
index 658daa79cbb19c96824559812eff5c130274fa46..3194db3277e4a89d2737df77d974977bec88330b 100644 (file)
@@ -96,5 +96,8 @@
     <ClInclude Include="diagnostics\graph.h">\r
       <Filter>Source\diagnostics</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="utility\printable.h">\r
+      <Filter>Source\utility</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 9d33450fe7e93a62d51872356aa1d4e93c70e349..97ec085a17b05b1d4c14bcae58b9c6d1e91f22d4 100644 (file)
@@ -10,6 +10,7 @@ namespace caspar {
 typedef boost::error_info<struct tag_arg_name_info, std::string> arg_name_info;\r
 typedef boost::error_info<struct tag_arg_value_info, std::string> arg_value_info;\r
 typedef boost::error_info<struct tag_msg_info, std::string> msg_info;\r
+typedef boost::error_info<struct tag_source_info, std::string> source_info;\r
 typedef boost::error_info<struct tag_inner_info, std::exception_ptr> inner_info;\r
 typedef boost::error_info<struct tag_line_info, int> line_info;\r
 \r
diff --git a/common/utility/printable.h b/common/utility/printable.h
new file mode 100644 (file)
index 0000000..40b0ceb
--- /dev/null
@@ -0,0 +1,11 @@
+#pragma once\r
+\r
+#include <string>\r
+#include <functional>\r
+#include <memory>\r
+\r
+namespace caspar {\r
+\r
+typedef std::function<std::wstring()> printer;\r
+\r
+}
\ No newline at end of file
index 2b3c54a9c1de2fd9f60efb4ba613e3bf222ed9dd..32602e3a734ef62183d7969b09bb411915c596b6 100644 (file)
@@ -12,6 +12,7 @@
 #include "producer/layer.h"\r
 \r
 #include <common/concurrency/executor.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <boost/range/algorithm_ext/erase.hpp>\r
 \r
 \r
 #include <memory>\r
 \r
+#ifdef _MSC_VER\r
+#pragma warning(disable : 4355)\r
+#endif\r
+\r
 namespace caspar { namespace core {\r
 \r
 struct channel::implementation : boost::noncopyable\r
 {                                      \r
+       const int index_;\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
@@ -30,27 +37,33 @@ struct channel::implementation : boost::noncopyable
        const video_format_desc format_desc_;\r
 \r
 public:\r
-       implementation(const video_format_desc& format_desc)  \r
-               : format_desc_(format_desc)\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)))      {}\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
 \r
        ~implementation()\r
        {\r
                // Shutdown order is important! Destroy all created frames to mixer before destroying mixer.\r
-               CASPAR_LOG(info) << "Shutting down channel.";\r
+               CASPAR_LOG(info) << print() << " shutting down channel.";\r
                producer_.reset();\r
-               CASPAR_LOG(info) << "Successfully shut down producer-device.";\r
+               CASPAR_LOG(info) << print() << "successfully shut down producer-device.";\r
                consumer_.reset();\r
-               CASPAR_LOG(info) << "Successfully shut down consumer-device.";\r
+               CASPAR_LOG(info) << print() << "successfully shut down consumer-device.";\r
                mixer_.reset();\r
-               CASPAR_LOG(info) << "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
        }\r
 };\r
 \r
+channel::channel(int index, const video_format_desc& format_desc) : impl_(new implementation(index, format_desc)){}\r
 channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
-channel::channel(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
 frame_producer_device& channel::producer() { return *impl_->producer_;} \r
 frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \r
 frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \r
index 0605fde8ebbc47c22dc68b160279894f41781dcf..ddb16b49e2c1937af71334c8458ac3698dbf4f1f 100644 (file)
@@ -24,7 +24,7 @@ namespace caspar { namespace core {
 class channel : boost::noncopyable\r
 {\r
 public:\r
-       explicit channel(const video_format_desc& format_desc);\r
+       explicit channel(int index, const video_format_desc& format_desc);\r
        channel(channel&& other);\r
 \r
        frame_producer_device& producer();\r
index 371e1dd6686845bda5756475670db06a9f298ce5..1f8484e5517c9ce2ff7f40dfa96c69774a166fac 100644 (file)
@@ -32,6 +32,7 @@ class color_producer : public frame_producer
 {\r
        safe_ptr<draw_frame> frame_;\r
        std::wstring color_str_;\r
+       printer parent_printer_;\r
 \r
 public:\r
 \r
@@ -49,10 +50,12 @@ public:
                str >> std::hex >> value;       \r
                frame_ = std::move(frame);\r
        }\r
+\r
+       virtual void set_parent_printer(const printer& parent_printer){parent_printer_ = parent_printer;}\r
        \r
        virtual safe_ptr<draw_frame> receive() { return frame_; }\r
        \r
-       virtual std::wstring print() const { return + L"color[" + color_str_ + L"]"; }\r
+       virtual std::wstring print() const { return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"color[" + color_str_ + L"]"; }\r
 };\r
 \r
 safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params)\r
index d32ca84bfe63d4478c9949e102cc9a24aefd715d..879a9fd1680a9bed34f39302b8b6e8a1041617c4 100644 (file)
@@ -56,6 +56,7 @@ class decklink_input : public IDeckLinkInputCallback
                ~co_init(){CoUninitialize();}\r
        } co_;\r
 \r
+       printer parent_printer_;\r
        const video_format_desc format_desc_;\r
        std::wstring model_name_;\r
        const size_t device_index_;\r
@@ -76,8 +77,9 @@ class decklink_input : public IDeckLinkInputCallback
 \r
 public:\r
 \r
-       decklink_input(const video_format_desc& format_desc, size_t device_index, const std::shared_ptr<frame_factory>& frame_factory)\r
-               : format_desc_(format_desc)\r
+       decklink_input(const video_format_desc& format_desc, size_t device_index, const std::shared_ptr<frame_factory>& frame_factory, const printer& parent_printer)\r
+               : parent_printer_(parent_printer)\r
+               , format_desc_(format_desc)\r
                , device_index_(device_index)\r
                , model_name_(L"DECKLINK")\r
                , frame_factory_(frame_factory)\r
@@ -130,7 +132,7 @@ public:
                if(FAILED(input_->StartStreams()))\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to start input stream."));\r
 \r
-               CASPAR_LOG(info) << print() << " Successfully initialized decklink for " << format_desc_.name;\r
+               CASPAR_LOG(info) << print() << " successfully initialized decklink for " << format_desc_.name;\r
        }\r
 \r
        ~decklink_input()\r
@@ -234,13 +236,14 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return model_name_ + L" [input-" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L" [" + model_name_ + L"device:" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
        }\r
 };\r
        \r
 class decklink_producer : public frame_producer\r
 {      \r
        const size_t device_index_;\r
+       printer parent_printer_;\r
 \r
        std::unique_ptr<decklink_input> input_;\r
        \r
@@ -266,9 +269,11 @@ public:
                executor_.start();\r
                executor_.invoke([=]\r
                {\r
-                       input_.reset(new decklink_input(format_desc_, device_index_, frame_factory));\r
+                       input_.reset(new decklink_input(format_desc_, device_index_, frame_factory, parent_printer_));\r
                });\r
        }\r
+\r
+       virtual void set_parent_printer(const printer& parent_printer) { parent_printer_ = parent_printer;}\r
        \r
        virtual safe_ptr<draw_frame> receive()\r
        {\r
@@ -277,7 +282,7 @@ public:
        \r
        std::wstring print() const\r
        {\r
-               return input_ ? input_->print() : L"Unknown Decklink [input-" + boost::lexical_cast<std::wstring>(device_index_) + L"]";\r
+               return  (parent_printer_ ? parent_printer_() + L"/" : L"") + (input_ ? input_->print() : L"Unknown Decklink [input-" + boost::lexical_cast<std::wstring>(device_index_) + L"]");\r
        }\r
 };\r
 \r
index 5d1e865be08f9e5674bc7fa82d9f15e5c3d803c0..80c3c6bb84c7b8785d2267071ae408b737140c9a 100644 (file)
@@ -23,6 +23,8 @@ namespace caspar { namespace core { namespace ffmpeg{
 struct ffmpeg_producer : public frame_producer\r
 {\r
        const std::wstring                                      filename_;\r
+       const bool                                                      loop_;\r
+       printer                                                         parent_printer_;\r
        \r
        safe_ptr<diagnostics::graph>            graph_;\r
        timer                                                           perf_timer_;\r
@@ -38,13 +40,13 @@ struct ffmpeg_producer : public frame_producer
        safe_ptr<draw_frame>                            last_frame_;\r
        std::shared_ptr<frame_factory>          frame_factory_;\r
 \r
-       input                                                           input_; \r
+       std::unique_ptr<input>                          input_; \r
 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
                , last_frame_(draw_frame(draw_frame::empty()))\r
-               , input_(graph_, filename, loop)\r
                \r
        {\r
                graph_->guide("frame-time", 0.5);\r
@@ -59,23 +61,29 @@ public:
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
        {\r
                frame_factory_ = frame_factory;\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
+               input_.reset(new input(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
                \r
+       virtual void set_parent_printer(const printer& parent_printer) \r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
+\r
        virtual safe_ptr<draw_frame> receive()\r
        {\r
                perf_timer_.reset();\r
 \r
-               while(ouput_channel_.empty() && !input_.is_eof())\r
+               while(ouput_channel_.empty() && !input_->is_eof())\r
                {       \r
                        aligned_buffer video_packet;\r
                        if(video_frame_channel_.size() < 3 && video_decoder_)   \r
-                               video_packet = input_.get_video_packet();               \r
+                               video_packet = input_->get_video_packet();              \r
                        \r
                        aligned_buffer audio_packet;\r
                        if(audio_chunk_channel_.size() < 3 && audio_decoder_)   \r
-                               audio_packet = input_.get_audio_packet();               \r
+                               audio_packet = input_->get_audio_packet();              \r
 \r
                        tbb::parallel_invoke(\r
                        [&]\r
@@ -152,7 +160,7 @@ public:
                        last_frame_->get_audio_transform().set_gain(0.0); // last_frame should not have audio\r
                        ouput_channel_.pop();\r
                }\r
-               else if(input_.is_eof())\r
+               else if(input_->is_eof())\r
                        return draw_frame::eof();\r
 \r
                return result;\r
@@ -160,7 +168,7 @@ public:
 \r
        virtual std::wstring print() const\r
        {\r
-               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
        }\r
 };\r
 \r
index b099a148cad08fe0f67c86e3d57ac3dba3895b47..fb4fa539ec952b5954140811c60f50d56f47d4f0 100644 (file)
@@ -6,6 +6,7 @@
 \r
 #include <common/concurrency/executor.h>\r
 #include <common/diagnostics/graph.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <tbb/concurrent_queue.h>\r
 #include <tbb/queuing_mutex.h>\r
@@ -34,6 +35,7 @@ struct input::implementation : boost::noncopyable
 {              \r
        static const size_t PACKET_BUFFER_COUNT = 50;\r
 \r
+       printer parent_printer_;\r
        safe_ptr<diagnostics::graph> graph_;\r
 \r
        std::shared_ptr<AVFormatContext> format_context_;       // Destroy this last\r
@@ -55,8 +57,9 @@ struct input::implementation : boost::noncopyable
        \r
        executor executor_;\r
 public:\r
-       explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop) \r
-               : graph_(graph)\r
+       explicit implementation(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, const printer& parent_printer) \r
+               : parent_printer_(parent_printer)\r
+               , graph_(graph)\r
                , loop_(loop)\r
                , video_s_index_(-1)\r
                , audio_s_index_(-1)\r
@@ -71,6 +74,7 @@ public:
                if((errn = -av_open_input_file(&weak_format_context_, narrow(filename).c_str(), nullptr, 0, nullptr)) > 0)\r
                        BOOST_THROW_EXCEPTION(\r
                                file_read_error() << \r
+                               source_info(narrow(print())) << \r
                                msg_info("No format context found.") << \r
                                boost::errinfo_api_function("av_open_input_file") <<\r
                                boost::errinfo_errno(errn) <<\r
@@ -81,24 +85,28 @@ public:
                if((errn = -av_find_stream_info(format_context_.get())) > 0)\r
                        BOOST_THROW_EXCEPTION(\r
                                file_read_error() << \r
+                               source_info(narrow(print())) << \r
                                boost::errinfo_api_function("av_find_stream_info") <<\r
                                msg_info("No stream found.") << \r
                                boost::errinfo_errno(errn));\r
 \r
                video_codec_context_ = open_stream(CODEC_TYPE_VIDEO, video_s_index_);\r
                if(!video_codec_context_)\r
-                       CASPAR_LOG(warning) << "Could not open any video stream.";\r
+                       CASPAR_LOG(warning) << print() << " Could not open any video stream.";\r
                \r
                audio_codex_context_ = open_stream(CODEC_TYPE_AUDIO, audio_s_index_);\r
                if(!audio_codex_context_)\r
-                       CASPAR_LOG(warning) << "Could not open any audio stream.";\r
+                       CASPAR_LOG(warning) << print() << " Could not open any audio stream.";\r
 \r
                if(!video_codec_context_ && !audio_codex_context_)\r
-                       BOOST_THROW_EXCEPTION(file_read_error() << msg_info("No video or audio codec context found."));         \r
+                       BOOST_THROW_EXCEPTION(\r
+                               file_read_error() << \r
+                               source_info(narrow(print())) << \r
+                               msg_info("No video or audio codec context found."));            \r
                                        \r
                executor_.start();\r
                executor_.begin_invoke([this]{read_file();});\r
-               CASPAR_LOG(info) << print() << " started.";\r
+               CASPAR_LOG(info) << print() << " Started.";\r
        }\r
 \r
        ~implementation()\r
@@ -106,7 +114,7 @@ public:
                executor_.clear();\r
                executor_.stop();\r
                cond_.notify_all();\r
-               CASPAR_LOG(info) << print() << " stopped.";\r
+               CASPAR_LOG(info) << print() << " Stopped.";\r
        }\r
                                                        \r
        std::shared_ptr<AVCodecContext> open_stream(int codec_type, int& s_index)\r
@@ -170,7 +178,7 @@ public:
          \r
                bool result = av_seek_frame(format_context_.get(), stream_index, seek_target, flags) >= 0;\r
                if(!result)\r
-                       CASPAR_LOG(warning) << "Failed to seek frame.";\r
+                       CASPAR_LOG(warning) << print() << " Failed to seek frame.";\r
                return result;\r
        }\r
                \r
@@ -203,11 +211,11 @@ public:
 \r
        std::wstring print() const\r
        {\r
-               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"] buffer thread";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"[async_input]";\r
        }\r
 };\r
 \r
-input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop) : impl_(new implementation(graph, filename, loop)){}\r
+input::input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, const printer& parent_printer) : impl_(new implementation(graph, filename, loop, parent_printer)){}\r
 const std::shared_ptr<AVCodecContext>& input::get_video_codec_context() const{return impl_->video_codec_context_;}\r
 const std::shared_ptr<AVCodecContext>& input::get_audio_codec_context() const{return impl_->audio_codex_context_;}\r
 bool input::is_eof() const{return impl_->is_eof();}\r
index 78e51029a694c2ef2a39b0379e9fb6b2792cc5ef..34bde78258f7e76ec562312b3086fab2bda27b9e 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once\r
 \r
 #include <common/diagnostics/graph.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <tbb/cache_aligned_allocator.h>\r
 \r
@@ -16,7 +17,7 @@ typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>>
 class input : boost::noncopyable\r
 {\r
 public:\r
-       explicit input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop);\r
+       explicit input(const safe_ptr<diagnostics::graph>& graph, const std::wstring& filename, bool loop, const printer& parent_printer);\r
        const std::shared_ptr<AVCodecContext>& get_video_codec_context() const;\r
        const std::shared_ptr<AVCodecContext>& get_audio_codec_context() const;\r
 \r
index 216fa7256f5fe1cd3149d3b3edb239635cc30248..9db8567ec37321544860e680c34dde9910959665 100644 (file)
@@ -16,6 +16,9 @@ namespace caspar { namespace core { namespace flash {
        \r
 struct cg_producer::implementation : boost::noncopyable\r
 {\r
+       printer parent_printer_;\r
+       safe_ptr<flash_producer> flash_producer_;\r
+       std::shared_ptr<frame_factory> frame_factory_;\r
 public:\r
        implementation() \r
                : flash_producer_(flash_producer(env::template_host())){}\r
@@ -23,6 +26,7 @@ public:
        void clear()\r
        {\r
                flash_producer_ = flash_producer(env::template_host());\r
+               flash_producer_->set_parent_printer(parent_printer_);\r
                flash_producer_->initialize(safe_ptr<frame_factory>(frame_factory_));\r
        }\r
 \r
@@ -77,15 +81,18 @@ public:
        {\r
                frame_factory_ = frame_factory;\r
                flash_producer_->initialize(frame_factory);\r
+               flash_producer_->set_parent_printer(parent_printer_);\r
+       }\r
+\r
+       void set_parent_printer(const printer& parent_printer) \r
+       {\r
+               parent_printer_ = parent_printer;\r
        }\r
 \r
        std::wstring print() const\r
        {\r
                return flash_producer_->print();\r
        }\r
-\r
-       safe_ptr<flash_producer> flash_producer_;\r
-       std::shared_ptr<frame_factory> frame_factory_;\r
 };\r
        \r
 safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<channel>& channel, int render_layer)\r
@@ -126,5 +133,6 @@ void cg_producer::next(int layer){impl_->next(layer);}
 void cg_producer::update(int layer, const std::wstring& data){impl_->update(layer, data);}\r
 void cg_producer::invoke(int layer, const std::wstring& label){impl_->invoke(layer, label);}\r
 void cg_producer::initialize(const safe_ptr<frame_factory>& frame_factory){impl_->initialize(frame_factory);}\r
+void cg_producer::set_parent_printer(const printer& parent_printer) { impl_->set_parent_printer(parent_printer);}\r
 std::wstring cg_producer::print() const{return impl_->print();}\r
 }}}
\ No newline at end of file
index 1a21e7eb1fb35f5b0e0c44b50bb7c9598f272c36..0522c3021076f04674b67bc8a1a3dd371105cb4e 100644 (file)
@@ -17,6 +17,7 @@ public:
        \r
        virtual safe_ptr<draw_frame> receive();\r
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
 \r
        void clear();\r
        void add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& start_from_label = TEXT(""), const std::wstring& data = TEXT(""));\r
index 06acbb5df0e5f2bab52ad85243feacc39e32327b..fc808b3bb51146ff4f19aca1821c2868484c3ddb 100644 (file)
@@ -52,7 +52,8 @@ class flash_renderer
                co_init(){CoInitialize(nullptr);}\r
                ~co_init(){CoUninitialize();}\r
        } co_;\r
-\r
+       \r
+       printer parent_printer_;\r
        const std::wstring filename_;\r
        const video_format_desc format_desc_;\r
 \r
@@ -70,11 +71,15 @@ class flash_renderer
        safe_ptr<diagnostics::graph> graph_;\r
        timer perf_timer_;\r
 \r
-       std::function<std::wstring()> print_;\r
+       std::wstring print()\r
+       {\r
+               return parent_printer_();\r
+       }\r
 \r
 public:\r
-       flash_renderer(const safe_ptr<diagnostics::graph>& graph, const std::shared_ptr<frame_factory>& frame_factory, const std::wstring& filename, const std::function<std::wstring()>& print) \r
-               : graph_(graph)\r
+       flash_renderer(const safe_ptr<diagnostics::graph>& graph, const std::shared_ptr<frame_factory>& frame_factory, const std::wstring& filename, const printer& parent_printer) \r
+               : parent_printer_(parent_printer)\r
+               , graph_(graph)\r
                , filename_(filename)\r
                , format_desc_(frame_factory->get_video_format_desc())\r
                , frame_factory_(frame_factory)\r
@@ -82,7 +87,6 @@ public:
                , hdc_(CreateCompatibleDC(0), DeleteDC)\r
                , ax_(nullptr)\r
                , head_(draw_frame::empty())\r
-               , print_(print)\r
        {\r
                graph_->guide("frame-time", 0.5f);\r
                graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));  \r
@@ -90,25 +94,25 @@ public:
                graph_->set_color("underflow", diagnostics::color(0.6f, 0.3f, 0.9f));                   \r
                \r
                if(FAILED(CComObject<caspar::flash::FlashAxContainer>::CreateInstance(&ax_)))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to create FlashAxContainer"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to create FlashAxContainer"));\r
                \r
-               ax_->set_print(print_);\r
+               ax_->set_print(parent_printer_);\r
 \r
                if(FAILED(ax_->CreateAxControl()))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to Create FlashAxControl"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to Create FlashAxControl"));\r
                \r
                CComPtr<IShockwaveFlash> spFlash;\r
                if(FAILED(ax_->QueryControl(&spFlash)))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to Query FlashAxControl"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to Query FlashAxControl"));\r
                                                                                                \r
                if(FAILED(spFlash->put_Playing(true)) )\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to start playing Flash"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to start playing Flash"));\r
 \r
                if(FAILED(spFlash->put_Movie(CComBSTR(filename.c_str()))))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to Load Template Host"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to Load Template Host"));\r
                                                                                \r
                if(FAILED(spFlash->put_ScaleMode(2)))  //Exact fit. Scale without respect to the aspect ratio.\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print_()) + "Failed to Set Scale Mode"));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + "Failed to Set Scale Mode"));\r
                                                                                                                \r
                ax_->SetFormat(format_desc_);\r
                \r
@@ -123,7 +127,7 @@ public:
 \r
                bmp_.reset(CreateDIBSection(static_cast<HDC>(hdc_.get()), &info, DIB_RGB_COLORS, reinterpret_cast<void**>(&bmp_data_), 0, 0), DeleteObject);\r
                SelectObject(static_cast<HDC>(hdc_.get()), bmp_.get()); \r
-               CASPAR_LOG(info) << print() << L" Thread started.";\r
+               CASPAR_LOG(info) << parent_printer_() << L" Thread started.";\r
        }\r
 \r
        ~flash_renderer()\r
@@ -133,13 +137,13 @@ public:
                        ax_->DestroyAxControl();\r
                        ax_->Release();\r
                }\r
-               CASPAR_LOG(info) << print_() << L" Thread ended.";\r
+               CASPAR_LOG(info) << print() << L" Thread ended.";\r
        }\r
        \r
        void param(const std::wstring& param)\r
        {               \r
                if(!ax_->FlashCall(param))\r
-                       CASPAR_LOG(warning) << print_() << " Flash function call failed. Param: " << param << ".";\r
+                       CASPAR_LOG(warning) << print() << " Flash function call failed. Param: " << param << ".";\r
                graph_->tag("param");\r
        }\r
        \r
@@ -189,6 +193,7 @@ private:
 \r
 struct flash_producer::implementation\r
 {      \r
+       printer parent_printer_;\r
        const std::wstring filename_;   \r
        tbb::atomic<int> fps_;\r
 \r
@@ -205,7 +210,7 @@ struct flash_producer::implementation
                \r
        std::wstring print() const\r
        { \r
-               return L"flash[" + boost::filesystem::wpath(filename_).filename() + L", " + \r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"flash[" + boost::filesystem::wpath(filename_).filename() + L", " + \r
                                        boost::lexical_cast<std::wstring>(fps_) + \r
                                        (interlaced(fps_, format_desc_) ? L"i" : L"p") + L"]";          \r
        }       \r
@@ -248,6 +253,11 @@ public:
                executor_.start();\r
        }\r
 \r
+       virtual void set_parent_printer(const printer& parent_printer) \r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
+\r
        virtual safe_ptr<draw_frame> receive()\r
        {               \r
                if(!renderer_)\r
@@ -308,6 +318,7 @@ flash_producer::flash_producer(const std::wstring& filename) : impl_(new impleme
 safe_ptr<draw_frame> flash_producer::receive(){return impl_->receive();}\r
 void flash_producer::param(const std::wstring& param){impl_->param(param);}\r
 void flash_producer::initialize(const safe_ptr<frame_factory>& frame_factory) { impl_->initialize(frame_factory);}\r
+void flash_producer::set_parent_printer(const printer& parent_printer){impl_->set_parent_printer(parent_printer);}\r
 std::wstring flash_producer::print() const {return impl_->print();}\r
 \r
 std::wstring flash_producer::find_template(const std::wstring& template_name)\r
index b316e03e94492b064814802713afbb4562295605..f43bc437d8a9906d3321f2319d1e568693956634 100644 (file)
@@ -33,6 +33,7 @@ public:
 \r
        virtual safe_ptr<draw_frame> receive();\r
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual std::wstring print() const;\r
 \r
        void param(const std::wstring& param);\r
index 2b399e49693ab86628193d8eaf3ccdc5e4a11dfc..aafe2dd1d4a86cec949635ed0280b66654a264bc 100644 (file)
@@ -23,6 +23,7 @@
 #include "../mixer/frame_factory.h"\r
 \r
 #include <common/memory/safe_ptr.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
@@ -74,6 +75,8 @@ public:
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory) = 0;\r
 \r
+       virtual void set_parent_printer(const printer& parent_printer) = 0;\r
+\r
        static const safe_ptr<frame_producer>& empty()  // nothrow\r
        {\r
                struct empty_frame_producer : public frame_producer\r
@@ -81,6 +84,7 @@ public:
                        virtual safe_ptr<draw_frame> receive(){return draw_frame::empty();}\r
                        virtual void initialize(const safe_ptr<frame_factory>&){}\r
                        virtual std::wstring print() const { return L"empty";}\r
+                       virtual void set_parent_printer(const printer& parent_printer) {}\r
                };\r
                static safe_ptr<frame_producer> producer = make_safe<empty_frame_producer>();\r
                return producer;\r
index 46f97c85cb5c71d7138efdafc94885a4aa7008a0..e8f534c0b3ec56e3f7a8413f3b5f394455b9288d 100644 (file)
@@ -8,6 +8,7 @@
 #include "layer.h"\r
 \r
 #include <common/concurrency/executor.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <boost/range/algorithm_ext/erase.hpp>\r
 #include <boost/lexical_cast.hpp>\r
@@ -22,7 +23,9 @@ namespace caspar { namespace core {
 \r
 struct frame_producer_device::implementation : boost::noncopyable\r
 {              \r
-       std::array<layer, frame_producer_device::MAX_LAYER+1> layers_;          \r
+       const printer parent_printer_;\r
+\r
+       std::vector<layer> layers_;             \r
 \r
        tbb::spin_mutex output_mutex_;\r
        output_func output_;\r
@@ -30,11 +33,16 @@ struct frame_producer_device::implementation : boost::noncopyable
        const safe_ptr<frame_factory> factory_;\r
        \r
        mutable executor executor_;\r
+\r
 public:\r
-       implementation(const safe_ptr<frame_factory>& factory, const output_func& output)  \r
-               : factory_(factory)\r
+       implementation(const safe_ptr<frame_factory>& factory, const output_func& output, const printer& parent_printer)  \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
+\r
                executor_.start();\r
                executor_.begin_invoke([=]{tick();});\r
        }\r
@@ -73,6 +81,7 @@ public:
 \r
        void load(size_t index, const safe_ptr<frame_producer>& producer, bool play_on_load)\r
        {\r
+               producer->set_parent_printer(std::bind(&layer::print, &layers_.at(index)));\r
                producer->initialize(factory_);\r
                executor_.invoke([&]\r
                {\r
@@ -117,7 +126,7 @@ public:
        {\r
                executor_.invoke([&]\r
                {\r
-                       layers_.at(index) = std::move(layer());\r
+                       layers_.at(index) = std::move(layer(index, parent_printer_));\r
                });\r
        }\r
                \r
@@ -125,8 +134,8 @@ public:
        {\r
                executor_.invoke([&]\r
                {\r
-                       for(auto it = layers_.begin(); it != layers_.end(); ++it)\r
-                               *it = std::move(layer());\r
+                       for(size_t n = 0; n < layers_.size(); ++n)\r
+                               layers_[n] = layer(n, parent_printer_);\r
                });\r
        }       \r
        \r
@@ -165,7 +174,7 @@ public:
        }\r
 };\r
 \r
-frame_producer_device::frame_producer_device(const safe_ptr<frame_factory>& factory, const output_func& output) : impl_(new implementation(factory, output)){}\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(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 e5ad3d8a9db0732c59af3a13daa206f3d23cc21a..3989c343846675c2dc67f9e34ccf30268e65ee53 100644 (file)
@@ -3,6 +3,7 @@
 #include "frame_producer.h"\r
 \r
 #include <common/memory/safe_ptr.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
 #include <boost/thread/future.hpp>\r
@@ -29,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);\r
+       explicit frame_producer_device(const safe_ptr<frame_factory>& factory, const output_func& output, const printer& printer);\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 06c172516c4394dc42953213892db29cc0327a75..00096073d943255fddf80e8df78e8c683954f271 100644 (file)
@@ -20,6 +20,7 @@ namespace caspar { namespace core { namespace image{
 \r
 struct image_producer : public frame_producer\r
 {      \r
+       printer parent_printer_;\r
        std::shared_ptr<frame_factory> frame_factory_;\r
        std::wstring filename_;\r
        safe_ptr<draw_frame> frame_;\r
@@ -43,10 +44,15 @@ struct image_producer : public frame_producer
                std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin());\r
                frame_ = std::move(frame);\r
        }\r
+       \r
+       virtual void set_parent_printer(const printer& parent_printer) \r
+       {\r
+               parent_printer_ = parent_printer;\r
+       }\r
 \r
        virtual std::wstring print() const\r
        {\r
-               return L"image_producer. filename: " + filename_;\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"image_producer. filename: " + filename_;\r
        }\r
 };\r
 \r
index 11be6d174652ae65c9e3abf92010b8242da0f1be..149bddae840cf8819c53acf53dc620740f30de3c 100644 (file)
@@ -7,6 +7,7 @@
 \r
 #include <common/concurrency/executor.h>\r
 #include <common/utility/assert.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <mixer/frame/draw_frame.h>\r
 #include <mixer/image/image_mixer.h>\r
@@ -22,8 +23,9 @@ class frame_producer_remover
 \r
        void do_remove(safe_ptr<frame_producer>& producer)\r
        {\r
+               auto name = producer->print();\r
                producer = frame_producer::empty();\r
-               CASPAR_LOG(info) << L"frame_remover[" + boost::lexical_cast<std::wstring>(--count_) + L"] removed: " << producer->print();\r
+               CASPAR_LOG(info) << L"async_remover[" + boost::lexical_cast<std::wstring>(--count_) + L"] Removed: " << name << L".";\r
        }\r
 public:\r
 \r
@@ -36,7 +38,7 @@ public:
        void remove(safe_ptr<frame_producer>&& producer)\r
        {\r
                CASPAR_ASSERT(producer.unique());\r
-               CASPAR_LOG(info) << L"frame_remover[" + boost::lexical_cast<std::wstring>(++count_) + L"] removing: " << producer->print();\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
@@ -44,18 +46,23 @@ public:
 frame_producer_remover g_remover;\r
 \r
 struct layer::implementation : boost::noncopyable\r
-{                                      \r
+{                              \r
+       printer                                         parent_printer_;\r
        safe_ptr<frame_producer>        foreground_;\r
        safe_ptr<frame_producer>        background_;\r
        safe_ptr<draw_frame>            last_frame_;\r
        bool                                            is_paused_;\r
-\r
+       tbb::atomic<int>                        index_;\r
 public:\r
-       implementation() \r
-               : foreground_(frame_producer::empty())\r
+       implementation(int index, const printer& parent_printer) \r
+               : parent_printer_(parent_printer)\r
+               , foreground_(frame_producer::empty())\r
                , background_(frame_producer::empty())\r
                , last_frame_(draw_frame::empty())\r
-               , is_paused_(false){}\r
+               , is_paused_(false)\r
+       {\r
+               index_ = index;\r
+       }\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load)\r
        {                       \r
@@ -78,7 +85,7 @@ public:
                {\r
                        background_->set_leading_producer(foreground_);\r
                        foreground_ = background_;\r
-                       CASPAR_LOG(info) << foreground_->print() << L" started";\r
+                       CASPAR_LOG(info) << foreground_->print() << L" Started.";\r
                        background_ = frame_producer::empty();\r
                }\r
                is_paused_ = false;\r
@@ -121,24 +128,30 @@ public:
                                following->set_leading_producer(foreground_);\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" Started.";\r
 \r
                                last_frame_ = receive();\r
                        }\r
                }\r
                catch(...)\r
                {\r
+                       CASPAR_LOG(error) << print() << L"Unhandled Exception: ";\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                        stop();\r
                }\r
 \r
                return last_frame_;\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
+       }\r
 };\r
 \r
-layer::layer() \r
+layer::layer(int index, const printer& parent_printer\r
 {\r
-       impl_ = new implementation();\r
+       impl_ = new implementation(index, parent_printer);\r
 }\r
 layer::layer(layer&& other) \r
 {\r
@@ -156,6 +169,7 @@ layer& layer::operator=(layer&& other)
 void layer::swap(layer& other)\r
 {\r
        impl_ = other.impl_.compare_and_swap(impl_, other.impl_);\r
+       impl_->index_ = other.impl_->index_.compare_and_swap(impl_->index_, other.impl_->index_);\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
@@ -166,4 +180,5 @@ void layer::clear(){impl_->clear();}
 safe_ptr<draw_frame> layer::receive() {return impl_->receive();}\r
 safe_ptr<frame_producer> layer::foreground() const { return impl_->foreground_;}\r
 safe_ptr<frame_producer> layer::background() const { return impl_->background_;}\r
+std::wstring layer::print() const { return impl_->print();}\r
 }}
\ No newline at end of file
index 83878288a69ee4fbec89e10cc729efa65cb7a087..101943ecb91b02cc1d53910d4bd7be08cb993302 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once\r
 \r
 #include <common/memory/safe_ptr.h>\r
+#include <common/utility/printable.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
@@ -14,7 +15,7 @@ class draw_frame;
 class layer : boost::noncopyable\r
 {\r
 public:\r
-       layer(); // nothrow\r
+       layer(int index, const printer& parent_printer = nullptr); // nothrow\r
        layer(layer&& other); // nothrow\r
        ~layer(); // nothrow\r
        layer& operator=(layer&& other); // nothrow\r
@@ -33,6 +34,8 @@ public:
        safe_ptr<frame_producer> background() const; // nothrow\r
 \r
        safe_ptr<draw_frame> receive(); // nothrow\r
+\r
+       std::wstring print() const;\r
 private:\r
        struct implementation;\r
        tbb::atomic<implementation*> impl_;\r
index 7824bc65c53696e747c7e1224f34ca64002715c0..1e0feb6a09839beaadb3662bf7abef005c074030 100644 (file)
@@ -32,6 +32,7 @@ namespace caspar { namespace core {
 \r
 struct transition_producer::implementation : boost::noncopyable\r
 {      \r
+       printer parent_printer_;\r
        unsigned short                          current_frame_;\r
        \r
        const transition_info           info_;\r
@@ -60,6 +61,12 @@ struct transition_producer::implementation : boost::noncopyable
                format_desc_ = frame_factory_->get_video_format_desc();\r
        }\r
 \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
        safe_ptr<frame_producer> get_following_producer() const\r
        {\r
                return dest_producer_;\r
@@ -181,7 +188,7 @@ struct transition_producer::implementation : boost::noncopyable
 \r
        std::wstring print() const\r
        {\r
-               return L"transition[" + source_producer_->print() + L"->" + dest_producer_->print() + L"]";\r
+               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"transition[length:" + boost::lexical_cast<std::wstring>(info_.duration) + L"]";\r
        }\r
 };\r
 \r
@@ -191,6 +198,7 @@ safe_ptr<draw_frame> transition_producer::receive(){return impl_->receive();}
 safe_ptr<frame_producer> transition_producer::get_following_producer() const{return impl_->get_following_producer();}\r
 void transition_producer::set_leading_producer(const safe_ptr<frame_producer>& producer) { impl_->set_leading_producer(producer); }\r
 void transition_producer::initialize(const safe_ptr<frame_factory>& frame_factory) { impl_->initialize(frame_factory);}\r
+void transition_producer::set_parent_printer(const printer& parent_printer) {impl_->set_parent_printer(parent_printer);}\r
 std::wstring transition_producer::print() const { return impl_->print();}\r
 \r
 }}\r
index fcdd070554548001c3f038f5845de24244e56d9e..5a2f1698c6f065db32ab5403e3b828f02a7cca66 100644 (file)
@@ -68,6 +68,7 @@ public:
        virtual safe_ptr<frame_producer> get_following_producer() const;\r
        virtual void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
        virtual void initialize(const safe_ptr<frame_factory>& frame_factory);\r
+       virtual void set_parent_printer(const printer& parent_printer);\r
        virtual std::wstring print() const;\r
 private:\r
        struct implementation;\r
index 241a51120ab8f76a6aecd2d230b0ffc5058e5cea..fd28287628cffa20b5dcf0934ee127dfc7d8e6fe 100644 (file)
@@ -60,7 +60,7 @@ struct bootstrapper::implementation : boost::noncopyable
                        if(format_desc.format == video_format::invalid)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid videomode."));\r
                        \r
-                       channels_.push_back(channel(format_desc));\r
+                       channels_.push_back(channel(channels_.size(), format_desc));\r
                        \r
                        int index = 0;\r
                        BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))\r