]> git.sesse.net Git - casparcg/commitdiff
- Increased consumer timeout to 10 seconds.
authorHelge Norberg <helge.norberg@svt.se>
Fri, 31 Oct 2014 10:47:02 +0000 (11:47 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 31 Oct 2014 10:47:02 +0000 (11:47 +0100)
- Implemented a new AMCP command called GL
  o GL GC - garbage collects GL resources not currently in use.
  o GL INFO - provides information about GL resource usage.

15 files changed:
core/consumer/output.cpp
core/mixer/gpu/device_buffer.cpp
core/mixer/gpu/device_buffer.h
core/mixer/gpu/host_buffer.cpp
core/mixer/gpu/host_buffer.h
core/mixer/gpu/ogl_device.cpp
core/mixer/gpu/ogl_device.h
protocol/amcp/AMCPCommand.h
protocol/amcp/AMCPCommandsImpl.cpp
protocol/amcp/AMCPCommandsImpl.h
protocol/amcp/AMCPProtocolStrategy.cpp
protocol/amcp/AMCPProtocolStrategy.h
shell/main.cpp
shell/server.cpp
shell/server.h

index 9e2b05e61dd979195a40b236c6bb99df375dd8ff..00ba91e1d474aeb67bbd027c34209f80625e0ae2 100644 (file)
@@ -44,6 +44,8 @@
 #include <boost/property_tree/ptree.hpp>\r
 \r
 namespace caspar { namespace core {\r
+\r
+const long SEND_TIMEOUT_MILLIS = 10000L;\r
        \r
 struct output::implementation\r
 {              \r
@@ -254,7 +256,7 @@ public:
                                                \r
                                        try\r
                                        {\r
-                                               if (!result_future.timed_wait(boost::posix_time::seconds(2)))\r
+                                               if (!result_future.timed_wait(boost::posix_time::seconds(SEND_TIMEOUT_MILLIS)))\r
                                                {\r
                                                        BOOST_THROW_EXCEPTION(timed_out() << msg_info(narrow(print()) + " " + narrow(consumer->print()) + " Timed out during send"));\r
                                                }\r
@@ -274,7 +276,7 @@ public:
                                                        consumer->initialize(format_desc_, audio_channel_layout_, channel_index_);\r
                                                        auto retry_future = consumer->send(frame);\r
 \r
-                                                       if (!retry_future.timed_wait(boost::posix_time::seconds(2)))\r
+                                                       if (!retry_future.timed_wait(boost::posix_time::seconds(SEND_TIMEOUT_MILLIS)))\r
                                                        {\r
                                                                BOOST_THROW_EXCEPTION(timed_out() << msg_info(narrow(print()) + " " + narrow(consumer->print()) + " Timed out during retry"));\r
                                                        }\r
index c3a2fdd519890df35a3b1b7cc47d354d66c5a8c8..13016840be23d501df20b281ea881cbe58e0d275 100644 (file)
@@ -32,6 +32,8 @@
 \r
 #include <tbb/atomic.h>\r
 \r
+#include <boost/property_tree/ptree.hpp>\r
+\r
 namespace caspar { namespace core {\r
        \r
 static GLenum FORMAT[] = {0, GL_RED, GL_RG, GL_BGR, GL_BGRA};\r
@@ -42,24 +44,30 @@ unsigned int format(size_t stride)
        return FORMAT[stride];\r
 }\r
 \r
+static tbb::atomic<int> g_instance_id;\r
 static tbb::atomic<int> g_total_count;\r
+static tbb::atomic<int> g_total_size;\r
 \r
 struct device_buffer::implementation : boost::noncopyable\r
 {\r
        GLuint                  id_;\r
+       int                             instance_id_;\r
 \r
        const size_t    width_;\r
        const size_t    height_;\r
        const size_t    stride_;\r
+       const size_t    size_;\r
        const bool              mipmapped_;\r
 \r
        fence                   fence_;\r
 \r
 public:\r
        implementation(size_t width, size_t height, size_t stride, bool mipmapped) \r
-               : width_(width)\r
+               : instance_id_(++instance_id_)\r
+               , width_(width)\r
                , height_(height)\r
                , stride_(stride)\r
+               , size_(static_cast<size_t>(width * height * stride * (mipmapped ? 1.33 : 1.0)))\r
                , mipmapped_(mipmapped)\r
        {       \r
                GL(glGenTextures(1, &id_));\r
@@ -77,7 +85,9 @@ public:
                }\r
 \r
                GL(glBindTexture(GL_TEXTURE_2D, 0));\r
-               CASPAR_LOG(trace) << "[device_buffer] [" << ++g_total_count << L"] allocated size:" << width*height*stride;     \r
+               g_total_size += size_;\r
+               ++g_total_count;\r
+               CASPAR_LOG(trace) << "[device_buffer] [" << instance_id_ << L"] allocated size:" << size_ << " for a total of: " << g_total_size;\r
        }\r
 \r
        void enable_anosotropic_filtering_if_available()\r
@@ -102,7 +112,9 @@ public:
                try\r
                {\r
                        GL(glDeleteTextures(1, &id_));\r
-                       //CASPAR_LOG(trace) << "[device_buffer] [" << --g_total_count << L"] deallocated size:" << width_*height_*stride_;\r
+                       g_total_size -= size_;\r
+                       --g_total_count;\r
+                       CASPAR_LOG(trace) << "[device_buffer] [" << instance_id_ << L"] deallocated size:" << size_ << " for a remaining total of: " << g_total_size;\r
                }\r
                catch(...)\r
                {\r
@@ -148,11 +160,21 @@ device_buffer::device_buffer(size_t width, size_t height, size_t stride, bool mi
 size_t device_buffer::stride() const { return impl_->stride_; }\r
 size_t device_buffer::width() const { return impl_->width_; }\r
 size_t device_buffer::height() const { return impl_->height_; }\r
+size_t device_buffer::size() const { return impl_->size_; }\r
 void device_buffer::bind(int index){impl_->bind(index);}\r
 void device_buffer::unbind(){impl_->unbind();}\r
 void device_buffer::begin_read(){impl_->begin_read();}\r
 bool device_buffer::ready() const{return impl_->ready();}\r
 int device_buffer::id() const{ return impl_->id_;}\r
 \r
+boost::property_tree::wptree device_buffer::info()\r
+{\r
+       boost::property_tree::wptree info;\r
+\r
+       info.add(L"total_count", g_total_count);\r
+       info.add(L"total_size", g_total_size);\r
+\r
+       return info;\r
+}\r
 \r
-}}
\ No newline at end of file
+}}\r
index 6739795a7a972f2c132e489d2e646c42581e4a3b..3c3f24b55c7a999c15dfbda87bf89dbe8cef44c3 100644 (file)
@@ -24,6 +24,7 @@
 #include <common/memory/safe_ptr.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
+#include <boost/property_tree/ptree_fwd.hpp>\r
 \r
 #include <memory>\r
 \r
@@ -36,6 +37,7 @@ public:
        size_t stride() const;  \r
        size_t width() const;\r
        size_t height() const;\r
+       size_t size() const;\r
        bool mipmapped() const;\r
 \r
        void bind(int index);\r
@@ -43,6 +45,8 @@ public:
                \r
        void begin_read();\r
        bool ready() const;\r
+\r
+       static boost::property_tree::wptree info();\r
 private:\r
        friend class ogl_device;\r
        device_buffer(size_t width, size_t height, size_t stride, bool mipmapped);\r
index 92627402cfeff49d555eb9b3f79da09ff42f0f9b..02c1baced1f1491d549375c30530e6ccf972f31d 100644 (file)
 \r
 #include <tbb/atomic.h>\r
 \r
+#include <boost/property_tree/ptree.hpp>\r
+\r
 namespace caspar { namespace core {\r
 \r
+static tbb::atomic<int> g_w_instance_id;\r
 static tbb::atomic<int> g_w_total_count;\r
+static tbb::atomic<int> g_w_total_size;\r
+static tbb::atomic<int> g_r_instance_id;\r
 static tbb::atomic<int> g_r_total_count;\r
+static tbb::atomic<int> g_r_total_size;\r
                                                                                                                                                                                                                                                                                                                                \r
 struct host_buffer::implementation : boost::noncopyable\r
-{      \r
+{\r
+       int                             instance_id_;\r
        GLuint                  pbo_;\r
        const size_t    size_;\r
        void*                   data_;\r
-       GLenum                  usage_;\r
+       usage_t                 usage_;\r
        GLenum                  target_;\r
        fence                   fence_;\r
 \r
 public:\r
        implementation(size_t size, usage_t usage) \r
-               : size_(size)\r
+               : instance_id_(++(usage == write_only ? g_w_instance_id : g_r_instance_id))\r
+               , size_(size)\r
                , data_(nullptr)\r
                , pbo_(0)\r
                , target_(usage == write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
-               , usage_(usage == write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
+               , usage_(usage)\r
        {\r
                GL(glGenBuffers(1, &pbo_));\r
                GL(glBindBuffer(target_, pbo_));\r
-               if(usage_ != write_only)        \r
-                       GL(glBufferData(target_, size_, NULL, usage_)); \r
+               GL(glBufferData(target_, size_, NULL, usage_ == write_only ? GL_STREAM_DRAW : GL_STREAM_READ));\r
                GL(glBindBuffer(target_, 0));\r
 \r
                if(!pbo_)\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to allocate buffer."));\r
 \r
-               CASPAR_LOG(trace) << "[host_buffer] [" << ++(usage_ == write_only ? g_w_total_count : g_r_total_count) << L"] allocated size:" << size_ << " usage: " << (usage == write_only ? "write_only" : "read_only");\r
+               ++(usage_ == write_only ? g_w_total_count : g_r_total_count);\r
+               auto total_size = (usage_ == write_only ? g_w_total_size : g_r_total_size) += size_;\r
+               CASPAR_LOG(trace) << "[host_buffer] [" << instance_id_ << L"] allocated size:" << size_ << " (total: " << total_size << ") usage: " << (usage_ == write_only ? "write_only" : "read_only");\r
        }       \r
 \r
        ~implementation()\r
@@ -73,7 +82,9 @@ public:
                try\r
                {\r
                        GL(glDeleteBuffers(1, &pbo_));\r
-                       //CASPAR_LOG(trace) << "[host_buffer] [" << --(usage_ == write_only ? g_w_total_count : g_r_total_count) << L"] deallocated size:" << size_ << " usage: " << (usage_ == write_only ? "write_only" : "read_only");\r
+                       --(usage_ == write_only ? g_w_total_count : g_r_total_count);\r
+                       auto total_size = (usage_ == write_only ? g_w_total_size : g_r_total_size) -= size_;\r
+                       CASPAR_LOG(trace) << "[host_buffer] [" << instance_id_ << L"] deallocated size:" << size_ << "(remaining total: " << total_size << ") usage: " << (usage_ == write_only ? "write_only" : "read_only");\r
                }\r
                catch(...)\r
                {\r
@@ -86,11 +97,12 @@ public:
                if(data_)\r
                        return;\r
 \r
+               GL(glBindBuffer(target_, pbo_));\r
+\r
                if(usage_ == write_only)                        \r
-                       GL(glBufferData(target_, size_, NULL, usage_)); // Notify OpenGL that we don't care about previous data.\r
+                       GL(glBufferData(target_, size_, NULL, GL_STREAM_DRAW)); // Notify OpenGL that we don't care about previous data.\r
                \r
-               GL(glBindBuffer(target_, pbo_));\r
-               data_ = GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY));  \r
+               data_ = GL2(glMapBuffer(target_, usage_ == host_buffer::write_only ? GL_WRITE_ONLY : GL_READ_ONLY));\r
                GL(glBindBuffer(target_, 0)); \r
                if(!data_)\r
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target_ OpenGL Pixel Buffer Object."));\r
@@ -149,4 +161,16 @@ size_t host_buffer::size() const { return impl_->size_; }
 bool host_buffer::ready() const{return impl_->ready();}\r
 void host_buffer::wait(ogl_device& ogl){impl_->wait(ogl);}\r
 \r
+boost::property_tree::wptree host_buffer::info()\r
+{\r
+       boost::property_tree::wptree info;\r
+\r
+       info.add(L"total_read_count", g_r_total_count);\r
+       info.add(L"total_write_count", g_w_total_count);\r
+       info.add(L"total_read_size", g_r_total_size);\r
+       info.add(L"total_write_size", g_w_total_size);\r
+\r
+       return info;\r
+}\r
+\r
 }}
\ No newline at end of file
index d3759c3b83c3915f7837397dc85afdc6a174b1f4..9fdb370af81f6d6e5f4222cb586628d7cc2b34e5 100644 (file)
@@ -22,6 +22,7 @@
 #pragma once\r
 \r
 #include <boost/noncopyable.hpp>\r
+#include <boost/property_tree/ptree_fwd.hpp>\r
 \r
 #include <common/memory/safe_ptr.h>\r
 \r
@@ -51,6 +52,8 @@ public:
        void begin_read(size_t width, size_t height, unsigned int format);\r
        bool ready() const;\r
        void wait(ogl_device& ogl);\r
+\r
+       static boost::property_tree::wptree info();\r
 private:\r
        friend class ogl_device;\r
        host_buffer(size_t size, usage_t usage);\r
index 1ea4a74d121ab3e50a542b9365eac6ac23ff177a..0ea77fbb4641b625975a0eeca14650045352f734 100644 (file)
@@ -32,6 +32,7 @@
 #include <common/gl/gl_check.h>\r
 \r
 #include <boost/foreach.hpp>\r
+#include <boost/property_tree/ptree.hpp>\r
 \r
 #include <gl/glew.h>\r
 \r
@@ -237,6 +238,97 @@ void ogl_device::yield()
        executor_.yield();\r
 }\r
 \r
+boost::property_tree::wptree ogl_device::info() const\r
+{\r
+       boost::property_tree::wptree info;\r
+\r
+       boost::property_tree::wptree pooled_device_buffers;\r
+       size_t total_pooled_device_buffer_size = 0;\r
+       size_t total_pooled_device_buffer_count = 0;\r
+\r
+       for (size_t i = 0; i < device_pools_.size(); ++i)\r
+       {\r
+               auto& pools = device_pools_.at(i);\r
+               bool mipmapping = i > 3;\r
+               int stride = mipmapping ? i - 3 : i + 1;\r
+\r
+               BOOST_FOREACH(auto& pool, pools)\r
+               {\r
+                       auto width = pool.first >> 16;\r
+                       auto height = pool.first & 0x0000FFFF;\r
+                       auto size = width * height * stride;\r
+                       auto count = pool.second->items.size();\r
+\r
+                       if (count == 0)\r
+                               continue;\r
+\r
+                       boost::property_tree::wptree pool_info;\r
+\r
+                       pool_info.add(L"stride", stride);\r
+                       pool_info.add(L"mipmapping", mipmapping);\r
+                       pool_info.add(L"width", width);\r
+                       pool_info.add(L"height", height);\r
+                       pool_info.add(L"size", size);\r
+                       pool_info.add(L"count", count);\r
+\r
+                       total_pooled_device_buffer_size += size * count;\r
+                       total_pooled_device_buffer_count += count;\r
+\r
+                       pooled_device_buffers.add_child(L"device_buffer_pool", pool_info);\r
+               }\r
+       }\r
+\r
+       info.add_child(L"gl.details.pooled_device_buffers", pooled_device_buffers);\r
+\r
+       boost::property_tree::wptree pooled_host_buffers;\r
+       size_t total_read_size = 0;\r
+       size_t total_write_size = 0;\r
+       size_t total_read_count = 0;\r
+       size_t total_write_count = 0;\r
+\r
+       for (size_t i = 0; i < host_pools_.size(); ++i)\r
+       {\r
+               auto& pools = host_pools_.at(i);\r
+               host_buffer::usage_t usage = static_cast<host_buffer::usage_t>(i);\r
+\r
+               BOOST_FOREACH(auto& pool, pools)\r
+               {\r
+                       auto size = pool.first;\r
+                       auto count = pool.second->items.size();\r
+\r
+                       if (count == 0)\r
+                               continue;\r
+\r
+                       boost::property_tree::wptree pool_info;\r
+\r
+                       pool_info.add(L"usage", usage == host_buffer::read_only\r
+                               ? L"read_only" : L"write_only");\r
+                       pool_info.add(L"size", size);\r
+                       pool_info.add(L"count", count);\r
+\r
+                       pooled_host_buffers.add_child(L"host_buffer_pool", pool_info);\r
+\r
+                       (usage == host_buffer::read_only\r
+                                       ? total_read_count : total_write_count) += count;\r
+                       (usage == host_buffer::read_only\r
+                                       ? total_read_size : total_write_size) += size * count;\r
+               }\r
+       }\r
+\r
+       info.add_child(L"gl.details.pooled_host_buffers", pooled_host_buffers);\r
+\r
+       info.add(L"gl.summary.pooled_device_buffers.total_count", total_pooled_device_buffer_count);\r
+       info.add(L"gl.summary.pooled_device_buffers.total_size", total_pooled_device_buffer_size);\r
+       info.add_child(L"gl.summary.all_device_buffers", device_buffer::info());\r
+       info.add(L"gl.summary.pooled_host_buffers.total_read_count", total_read_count);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_write_count", total_write_count);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_read_size", total_read_size);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_write_size", total_write_size);\r
+       info.add_child(L"gl.summary.all_host_buffers", host_buffer::info());\r
+\r
+       return info;\r
+}\r
+\r
 boost::unique_future<void> ogl_device::gc()\r
 {      \r
        return begin_invoke([=]\r
index 2896412dcca1961ea29b3c0f03bae6fa9003db29..66b935d1320f6a748f8f04871b2c1c0f3ac9ce93 100644 (file)
@@ -36,6 +36,7 @@
 \r
 #include <boost/noncopyable.hpp>\r
 #include <boost/thread/future.hpp>\r
+#include <boost/property_tree/ptree_fwd.hpp>\r
 \r
 #include <array>\r
 #include <unordered_map>\r
@@ -121,6 +122,7 @@ public:
        safe_ptr<host_buffer> create_host_buffer(size_t size, host_buffer::usage_t usage);\r
        \r
        void yield();\r
+       boost::property_tree::wptree info() const;\r
        boost::unique_future<void> gc();\r
 \r
        std::wstring version();\r
index 6dcacb52dfa51a9dbf328d546068d0cc5fc8c65f..2f12754b48b99cdef53308b4f3b92b90485a033f 100644 (file)
@@ -26,6 +26,7 @@
 #include <core/consumer/frame_consumer.h>\r
 #include <core/parameters/parameters.h>\r
 #include <core/video_channel.h>\r
+#include <core/mixer/gpu/ogl_device.h>\r
 #include <core/thumbnail_generator.h>\r
 \r
 #include <boost/algorithm/string.hpp>\r
@@ -83,6 +84,9 @@ namespace caspar { namespace protocol { namespace amcp {
                void SetLayerIntex(int layerIndex){layerIndex_ = layerIndex;}\r
                int GetLayerIndex(int defaultValue = 0) const{return layerIndex_ != -1 ? layerIndex_ : defaultValue;}\r
 \r
+               void SetOglDevice(const safe_ptr<core::ogl_device>& device){ogl_ = device;}\r
+               std::shared_ptr<core::ogl_device> GetOglDevice() const { return ogl_; }\r
+\r
                virtual void Clear();\r
 \r
                AMCPCommandScheduling GetScheduling()\r
@@ -102,6 +106,7 @@ namespace caspar { namespace protocol { namespace amcp {
                unsigned int channelIndex_;\r
                int layerIndex_;\r
                IO::ClientInfoPtr pClientInfo_;\r
+               std::shared_ptr<core::ogl_device> ogl_;\r
                std::shared_ptr<core::video_channel> pChannel_;\r
                std::vector<safe_ptr<core::video_channel>> channels_;\r
                std::shared_ptr<core::thumbnail_generator> thumb_gen_;\r
index f49dc79ff3c7713fdd462faf224e9845ceb5fccd..6d3bfac9ddaa8eb7313c1981c1365883a31f939c 100644 (file)
@@ -2385,6 +2385,51 @@ bool SetCommand::DoExecute()
        return true;\r
 }\r
 \r
+bool GlCommand::DoExecute()\r
+{\r
+       try\r
+       {\r
+               std::wstring command = _parameters.at(0);\r
+\r
+               if (command == TEXT("GC"))\r
+                       return DoExecuteGc();\r
+               else if (command == TEXT("INFO"))\r
+                       return DoExecuteInfo();\r
+       }\r
+       catch(...)\r
+       {\r
+               CASPAR_LOG_CURRENT_EXCEPTION();\r
+       }\r
+\r
+       SetReplyString(TEXT("403 GL ERROR\r\n"));\r
+       return false;\r
+}\r
+\r
+bool GlCommand::DoExecuteGc()\r
+{\r
+       if (!GetOglDevice()->gc().timed_wait(boost::posix_time::seconds(2)))\r
+               BOOST_THROW_EXCEPTION(timed_out());\r
+\r
+       SetReplyString(TEXT("202 GL GC OK\r\n"));\r
+       return true;\r
+}\r
+\r
+bool GlCommand::DoExecuteInfo()\r
+{\r
+       std::wstringstream reply_string;\r
+       boost::property_tree::xml_writer_settings<wchar_t> w(' ', 3);\r
+\r
+       auto info = GetOglDevice()->info();\r
+\r
+       reply_string << L"201 GL INFO OK\r\n";\r
+       boost::property_tree::write_xml(reply_string, info, w);\r
+       reply_string << L"\r\n";\r
+\r
+       SetReplyString(reply_string.str());\r
+\r
+       return true;\r
+}\r
+\r
 bool KillCommand::DoExecute()\r
 {\r
        GetShutdownServerNow().set_value(false); // False for not attempting to restart.\r
index 569a1cb50c55cf818e4ba89ce92d061715f9a7a7..ccd730813c8c73113dfabf47017f22ec088f35ab 100644 (file)
@@ -249,6 +249,14 @@ class KillCommand : public AMCPCommandBase<false, AddToQueue, 0>
        bool DoExecute();\r
 };\r
 \r
+class GlCommand : public AMCPCommandBase<false, AddToQueue, 0>\r
+{\r
+       std::wstring print() const { return L"GlCommand";}\r
+       bool DoExecute();\r
+       bool DoExecuteInfo();\r
+       bool DoExecuteGc();\r
+};\r
+\r
 class RestartCommand : public AMCPCommandBase<false, AddToQueue, 0>\r
 {\r
        std::wstring print() const { return L"RestartCommand";}\r
index 231ddee66e6bd43a9615e8392cf6a83e44f5f14e..a711021ad03dbb96cee700f2bee001e080981de9 100644 (file)
@@ -57,10 +57,12 @@ AMCPProtocolStrategy::AMCPProtocolStrategy(
                const std::vector<safe_ptr<core::video_channel>>& channels,\r
                const std::shared_ptr<core::thumbnail_generator>& thumb_gen,\r
                const safe_ptr<core::media_info_repository>& media_info_repo,\r
+               const safe_ptr<core::ogl_device>& ogl_device,\r
                boost::promise<bool>& shutdown_server_now)\r
        : channels_(channels)\r
        , thumb_gen_(thumb_gen)\r
        , media_info_repo_(media_info_repo)\r
+       , ogl_(ogl_device)\r
        , shutdown_server_now_(shutdown_server_now)\r
 {\r
        AMCPCommandQueuePtr pGeneralCommandQueue(new AMCPCommandQueue());\r
@@ -211,6 +213,7 @@ AMCPCommandPtr AMCPProtocolStrategy::InterpretCommandString(const std::wstring&
                                pCommand->SetChannels(channels_);\r
                                pCommand->SetThumbGenerator(thumb_gen_);\r
                                pCommand->SetMediaInfoRepo(media_info_repo_);\r
+                               pCommand->SetOglDevice(ogl_);\r
                                pCommand->SetShutdownServerNow(shutdown_server_now_);\r
                                //Set scheduling\r
                                if(commandSwitch.size() > 0) {\r
@@ -348,6 +351,7 @@ AMCPCommandPtr AMCPProtocolStrategy::CommandFactory(const std::wstring& str)
        else if(s == TEXT("VERSION"))           return std::make_shared<VersionCommand>();\r
        else if(s == TEXT("BYE"))                       return std::make_shared<ByeCommand>();\r
        else if(s == TEXT("SET"))                       return std::make_shared<SetCommand>();\r
+       else if(s == TEXT("GL"))                        return std::make_shared<GlCommand>();\r
        else if(s == TEXT("THUMBNAIL"))         return std::make_shared<ThumbnailCommand>();\r
        //else if(s == TEXT("MONITOR"))\r
        //{\r
index a4e392e648d60e2b48824417b3bc1b4791d0fd81..f885ff09d2a8dc0e2dadd55598937e22027d2a29 100644 (file)
@@ -53,6 +53,7 @@ public:
                        const std::vector<safe_ptr<core::video_channel>>& channels,\r
                        const std::shared_ptr<core::thumbnail_generator>& thumb_gen,\r
                        const safe_ptr<core::media_info_repository>& media_info_repo,\r
+                       const safe_ptr<core::ogl_device>& ogl_device,\r
                        boost::promise<bool>& shutdown_server_now);\r
        virtual ~AMCPProtocolStrategy();\r
 \r
@@ -75,6 +76,7 @@ private:
        std::vector<safe_ptr<core::video_channel>> channels_;\r
        std::shared_ptr<core::thumbnail_generator> thumb_gen_;\r
        safe_ptr<core::media_info_repository> media_info_repo_;\r
+       safe_ptr<core::ogl_device> ogl_;\r
        boost::promise<bool>& shutdown_server_now_;\r
        std::vector<AMCPCommandQueuePtr> commandQueues_;\r
        static const std::wstring MessageDelimiter;\r
index c931511517616fc6a632b0d7672bcdc1845f4d89..15f843bf30a9e7a340e14b8ee1ae2608f2275680 100644 (file)
@@ -318,6 +318,7 @@ int main(int argc, char* argv[])
                                                caspar_server.get_channels(),\r
                                                caspar_server.get_thumbnail_generator(),\r
                                                caspar_server.get_media_info_repo(),\r
+                                               caspar_server.get_ogl_device(),\r
                                                shutdown_server_now);\r
 \r
                                // Create a dummy client which prints amcp responses to console.\r
index de47b1f5aa3e823974e9968b3a12f99395cca0f8..05318aa9fc2ae50d8736fb19a9541ba1f44beffe 100644 (file)
@@ -379,7 +379,7 @@ struct server::implementation : boost::noncopyable
        safe_ptr<IO::IProtocolStrategy> create_protocol(const std::wstring& name) const\r
        {\r
                if(boost::iequals(name, L"AMCP"))\r
-                       return make_safe<amcp::AMCPProtocolStrategy>(channels_, thumbnail_generator_, media_info_repo_, shutdown_server_now_);\r
+                       return make_safe<amcp::AMCPProtocolStrategy>(channels_, thumbnail_generator_, media_info_repo_, ogl_, shutdown_server_now_);\r
                else if(boost::iequals(name, L"CII"))\r
                        return make_safe<cii::CIIProtocolStrategy>(channels_);\r
                else if(boost::iequals(name, L"CLOCK"))\r
@@ -429,6 +429,11 @@ safe_ptr<media_info_repository> server::get_media_info_repo() const
        return impl_->media_info_repo_;\r
 }\r
 \r
+safe_ptr<ogl_device> server::get_ogl_device() const\r
+{\r
+       return impl_->ogl_;\r
+}\r
+\r
 core::monitor::subject& server::monitor_output()\r
 {\r
        return *impl_->monitor_subject_;\r
index d547505b12ab97ad0ef018d32116814f15dccd6f..d7538a53ef039cb16fb276eeb8327725b89fe495 100644 (file)
@@ -37,6 +37,7 @@ namespace core {
        class video_channel;\r
        class thumbnail_generator;\r
        struct media_info_repository;\r
+       class ogl_device;\r
 }\r
 \r
 class server : boost::noncopyable\r
@@ -46,6 +47,7 @@ public:
        const std::vector<safe_ptr<core::video_channel>> get_channels() const;\r
        std::shared_ptr<core::thumbnail_generator> get_thumbnail_generator() const;\r
        safe_ptr<core::media_info_repository> get_media_info_repo() const;\r
+       safe_ptr<core::ogl_device> get_ogl_device() const;\r
 \r
        core::monitor::subject& monitor_output();\r
 \r