]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2:
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 13 Dec 2010 22:48:38 +0000 (22:48 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 13 Dec 2010 22:48:38 +0000 (22:48 +0000)
 - Mayor change. Producers and Frames are now passed using safe_ptr.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@290 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

88 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/concurrency/Thread.cpp
common/concurrency/Thread.h
common/concurrency/executor.h
common/gl/frame_buffer_object.cpp
common/gl/frame_buffer_object.h
common/gl/pixel_buffer_object.cpp
common/gl/pixel_buffer_object.h
common/gl/shader_program.cpp
common/gl/shader_program.h
common/gl/utility.h
common/io/AsyncEventServer.cpp
common/io/AsyncEventServer.h
common/io/ProtocolStrategy.h
common/log/log.h
common/utility/safe_ptr.h [new file with mode: 0644]
common/utility/singleton_pool.h
common/utility/string_convert.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/frame_consumer.h
core/consumer/frame_consumer_device.cpp
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/core.vcxproj
core/core.vcxproj.filters
core/format/pixel_format.cpp [new file with mode: 0644]
core/format/pixel_format.h
core/processor/composite_frame.cpp
core/processor/composite_frame.h
core/processor/draw_frame.cpp [deleted file]
core/processor/draw_frame.h
core/processor/frame_processor_device.cpp
core/processor/frame_processor_device.h
core/processor/frame_renderer.cpp
core/processor/frame_renderer.h
core/processor/frame_shader.cpp
core/processor/fwd.h
core/processor/read_frame.cpp
core/processor/read_frame.h
core/processor/transform_frame.cpp
core/processor/transform_frame.h
core/processor/write_frame.cpp
core/processor/write_frame.h
core/producer/color/color_producer.cpp
core/producer/color/color_producer.h
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.h
core/producer/ffmpeg/input.cpp
core/producer/ffmpeg/video/video_transformer.cpp
core/producer/ffmpeg/video/video_transformer.h
core/producer/flash/cg_producer.cpp
core/producer/flash/cg_producer.h
core/producer/flash/ct_producer.cpp
core/producer/flash/ct_producer.h
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/frame_producer.cpp [new file with mode: 0644]
core/producer/frame_producer.h
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/producer/image/image_loader.cpp
core/producer/image/image_producer.cpp
core/producer/image/image_producer.h
core/producer/image/image_scroll_producer.cpp
core/producer/image/image_scroll_producer.h
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
core/protocol/amcp/AMCPCommandQueue.cpp
core/protocol/amcp/AMCPCommandQueue.h
core/protocol/amcp/AMCPCommandsImpl.cpp
core/protocol/amcp/AMCPProtocolStrategy.cpp
core/protocol/cii/CIIProtocolStrategy.cpp
core/protocol/cii/CIIProtocolStrategy.h
core/protocol/clk/CLKProtocolStrategy.cpp
core/protocol/media.cpp
core/protocol/media.h
core/server.cpp
shell/main.cpp

index 3e2469f85255f0b57dac3f68593552ebd1ed58d1..eb345ce01ea840537caee84f2afbefab7b791efe 100644 (file)
     <ClInclude Include="io\SocketInfo.h" />\r
     <ClInclude Include="log\log.h" />\r
     <ClInclude Include="stdafx.h" />\r
+    <ClInclude Include="utility\safe_ptr.h" />\r
     <ClInclude Include="utility\scope_exit.h" />\r
     <ClInclude Include="utility\singleton_pool.h" />\r
     <ClInclude Include="utility\string_convert.h" />\r
index 1bdedcdb9825ce252ff3a12a043a6e84ef5773b6..da1133826953ecf0ac44d8cf70474f884776b113 100644 (file)
     <ClInclude Include="utility\singleton_pool.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="utility\safe_ptr.h">\r
+      <Filter>Source\utility</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index e61a438f6e66769e2460d743e60b5fcc05756c19..a6594c6f46f921b7e1b43d8d435b73ddcd156fc6 100644 (file)
@@ -24,7 +24,6 @@
 #include "../exception/win32_exception.h"\r
 \r
 namespace caspar {\r
-namespace common {\r
        \r
 Event::Event(bool bManualReset, bool bInitialState) : handle_(0)\r
 {\r
@@ -140,5 +139,4 @@ void Thread::Run() {
        }while(bDoRestart);\r
 }\r
 \r
-}      //namespace common\r
 }      //namespace caspar
\ No newline at end of file
index eff7099c8d7e0c14ca80dd3095a3fb64f1cc4ba4..47058d8a48f99fb18ca44678e50502045eeb3b6d 100644 (file)
@@ -24,7 +24,7 @@
 #include <exception>\r
 #include <memory>\r
 \r
-namespace caspar { namespace common {\r
+namespace caspar {\r
        \r
 class IRunnable\r
 {\r
@@ -93,4 +93,4 @@ private:
        static bool             static_bInstallWin32ExceptionHandler_;\r
 };\r
 \r
-}}
\ No newline at end of file
+}
\ No newline at end of file
index 66255da87e81643656915a54069416eb143a85e8..0211495c815fd7264dbd54fb53874555b8b2fd07 100644 (file)
@@ -10,7 +10,7 @@
 \r
 #include <functional>\r
 \r
-namespace caspar { namespace common {\r
+namespace caspar {\r
 \r
 class executor\r
 {\r
@@ -128,4 +128,4 @@ private:
        tbb::concurrent_bounded_queue<std::function<void()>> execution_queue_;\r
 };\r
 \r
-}}
\ No newline at end of file
+}
\ No newline at end of file
index c5c7a582d77982c5437d9aeae8f5bb9c4c73e013..55075fd1d8354a00a974bfe941be9629379823e5 100644 (file)
@@ -8,7 +8,7 @@
 \r
 #include <memory>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
 \r
 struct frame_buffer_object::implementation\r
 {\r
@@ -46,4 +46,4 @@ public:
 \r
 frame_buffer_object::frame_buffer_object(size_t width, size_t height, GLenum mode) : impl_(new implementation(width, height, mode)){}\r
 void frame_buffer_object::bind_pixel_source() {impl_->bind_pixel_source();}\r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index 9cd9faf800cfb2dca154b2830cf2594a5c22cab5..3808c91bce975ca943b686fcfffad46aa401c4ef 100644 (file)
@@ -4,7 +4,7 @@
 \r
 #include <memory>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
 \r
 class frame_buffer_object\r
 {\r
@@ -17,4 +17,4 @@ private:
 };\r
 typedef frame_buffer_object fbo;\r
 \r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index e4c3c61acba27cb401b987c1de316dcfdfcf1c78..96190ad4dfa99737a48fa8dbe6d859aa98369ead 100644 (file)
@@ -5,7 +5,7 @@
 #include "../../common/exception/exceptions.h"\r
 #include "../../common/gl/utility.h"\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
                                                                                                                                                                                                                                                                                                                        \r
 struct pixel_buffer_object::implementation : boost::noncopyable\r
 {\r
@@ -198,4 +198,4 @@ size_t pixel_buffer_object::size() const {return impl_->size_;}
 bool pixel_buffer_object::is_reading() const { return impl_->reading_;}\r
 bool pixel_buffer_object::is_writing() const { return impl_->writing_;}\r
 void pixel_buffer_object::is_smooth(bool smooth){impl_->is_smooth(smooth);}\r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index 7cf69a612b926c1576dad9fb7a2d2aa80245b58f..9ca7056c44e6d1241a5198c741e3914258bfbc08 100644 (file)
@@ -9,7 +9,7 @@
 #include <boost/tuple/tuple.hpp>\r
 #include <boost/thread/future.hpp>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
        \r
 class pixel_buffer_object : boost::noncopyable\r
 {\r
@@ -49,4 +49,4 @@ typedef std::shared_ptr<pixel_buffer_object> pixel_buffer_object_ptr;
 \r
 typedef pixel_buffer_object pbo;\r
 typedef pixel_buffer_object_ptr pbo_ptr;\r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index 44b5abf5c9c3b288a1ef7d43720e8736b685620c..015e3b08a945b2801f9fbcfc8eee9df4a36569e8 100644 (file)
@@ -9,7 +9,7 @@
 \r
 #include <boost/noncopyable.hpp>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
 \r
 shader_program& shader_program::operator=(shader_program&& other) \r
 {\r
@@ -37,7 +37,7 @@ shader_program::shader_program(const std::string& vertex_source_str, const std::
                GL(glDeleteObjectARB(vertex_shader));\r
                std::stringstream str;\r
                str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
-               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+               BOOST_THROW_EXCEPTION(gl::gl_error() << msg_info(str.str()));\r
        }\r
                        \r
        const char* fragment_source = fragment_source_str.c_str();\r
@@ -55,7 +55,7 @@ shader_program::shader_program(const std::string& vertex_source_str, const std::
                GL(glDeleteObjectARB(fragmemt_shader));\r
                std::stringstream str;\r
                str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
-               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+               BOOST_THROW_EXCEPTION(gl::gl_error() << msg_info(str.str()));\r
        }\r
                        \r
        program_ = glCreateProgramObjectARB();\r
@@ -76,7 +76,7 @@ shader_program::shader_program(const std::string& vertex_source_str, const std::
                GL(glDeleteObjectARB(program_));\r
                std::stringstream str;\r
                str << "Failed to link shader program:" << std::endl << info << std::endl;\r
-               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+               BOOST_THROW_EXCEPTION(gl::gl_error() << msg_info(str.str()));\r
        }\r
        GL(glUseProgramObjectARB(program_));\r
        glUniform1i(glGetUniformLocation(program_, "plane[0]"), 0);\r
@@ -95,4 +95,4 @@ void shader_program::use()
        GL(glUseProgramObjectARB(program_));            \r
 }\r
 \r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index fc4c6f0044f800c5317e639e40ef75cea45020a2..b0e3d2d75b13523b05f514f4a2a0fbcc2ae1a447 100644 (file)
@@ -5,7 +5,7 @@
 \r
 #include <memory>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
                \r
 class shader_program : boost::noncopyable\r
 {\r
@@ -26,4 +26,4 @@ private:
 };\r
 typedef std::shared_ptr<shader_program> shader_program_ptr;\r
 \r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index c80ce3013abfeb1bf18214f2e0a9ca9a549a34e2..4437af60f816df8267e383015e39a5ba140efa68 100644 (file)
@@ -31,7 +31,7 @@
 \r
 #include <boost/lexical_cast.hpp>\r
 \r
-namespace caspar { namespace common { namespace gl {\r
+namespace caspar { namespace gl {\r
 \r
 struct gl_error : virtual caspar_exception{};\r
                \r
@@ -115,10 +115,10 @@ inline void SMFL_GLCheckError(const std::string& expr, const std::string& File,
        do \\r
        { \\r
                (expr);  \\r
-               caspar::common::gl::SMFL_GLCheckError(CASPAR_GL_EXPR_STR(expr), __FILE__, __LINE__);\\r
+               caspar::gl::SMFL_GLCheckError(CASPAR_GL_EXPR_STR(expr), __FILE__, __LINE__);\\r
        }while(0);\r
 #else\r
 #define GL(expr) expr\r
 #endif\r
 \r
-}}}
\ No newline at end of file
+}}
\ No newline at end of file
index 797cdc7450ef377cbdd7ac33eddf45b4e312db50..f9976fea07985087da22bed49a4646f41c3c3682 100644 (file)
@@ -37,9 +37,7 @@
 #endif\r
 \r
 namespace caspar { namespace IO {\r
-\r
-using namespace common;\r
-\r
+       \r
 #define CASPAR_MAXIMUM_SOCKET_CLIENTS  (MAXIMUM_WAIT_OBJECTS-1)        \r
 \r
 long AsyncEventServer::instanceCount_ = 0;\r
index 7e11d681a57dc24463ffafeba7c9b619412cf10e..5d9558e30e248d24d14c2b75887ca4f9b586b7b1 100644 (file)
@@ -45,7 +45,7 @@ namespace IO {
 \r
 typedef std::function<void(caspar::IO::SocketInfoPtr)> ClientDisconnectEvent;\r
 \r
-class AsyncEventServer : public common::IRunnable\r
+class AsyncEventServer : public IRunnable\r
 {\r
        static long instanceCount_;\r
 \r
@@ -67,7 +67,7 @@ public:
        void SetClientDisconnectHandler(ClientDisconnectEvent handler);\r
        \r
 private:\r
-       common::Thread  listenThread_;\r
+       Thread  listenThread_;\r
        void Run(HANDLE stopEvent);\r
        bool OnUnhandledException(const std::exception&) throw();\r
 \r
index b4cb97dbb3270811dea855e31bd9794d64c18e1c..ac056e1219eb22746127992bd7194b2c30218c1c 100644 (file)
 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
 *\r
 */\r
\r
-#ifndef _PROTOCOLSTRATEGY_H__\r
-#define _PROTOCOLSTRATEGY_H__\r
-\r
-#pragma once\r
+ #pragma once\r
 \r
 #include <string>\r
 #include "clientInfo.h"\r
@@ -42,6 +38,4 @@ public:
 typedef std::tr1::shared_ptr<IProtocolStrategy> ProtocolStrategyPtr;\r
 \r
 }      //namespace IO\r
-}      //namespace caspar\r
-\r
-#endif //_PROTOCOLSTRATEGY_H__
\ No newline at end of file
+}      //namespace caspar
\ No newline at end of file
index 157f12c53bfe35715ad946f182b3a2ca3b4fe84c..1cde097ef17195b6cc0214090ed3d8bb9c085e3a 100644 (file)
@@ -71,7 +71,7 @@ BOOST_LOG_DECLARE_GLOBAL_LOGGER_INIT(logger, caspar_logger)
 \r
 #define CASPAR_LOG_CURRENT_EXCEPTION() \\r
        try\\r
-       {CASPAR_LOG(error) << caspar::common::widen(boost::current_exception_diagnostic_information());}\\r
+       {CASPAR_LOG(error) << caspar::widen(boost::current_exception_diagnostic_information());}\\r
        catch(...){}\r
 \r
 }}\r
diff --git a/common/utility/safe_ptr.h b/common/utility/safe_ptr.h
new file mode 100644 (file)
index 0000000..17bca8b
--- /dev/null
@@ -0,0 +1,135 @@
+#pragma once\r
+\r
+#include "../exception/exceptions.h"\r
+\r
+#include <memory>\r
+#include <vector>\r
+#include <type_traits>\r
+\r
+namespace caspar {\r
+       \r
+template<typename T>\r
+class safe_ptr\r
+{      \r
+       template <typename> friend class safe_ptr;\r
+public:\r
+       typedef T element_type;\r
+       \r
+       safe_ptr() : impl_(std::make_shared<T>()){static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");}      \r
+       \r
+       safe_ptr(const safe_ptr<T>& other) : impl_(other.impl_){}\r
+       \r
+       template<typename Y>\r
+       safe_ptr(const safe_ptr<Y>& other, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(other.impl_){}\r
+               \r
+       template<typename Y>    \r
+       safe_ptr(const Y& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+               : impl_(std::make_shared<Y>(impl)) {}\r
+       \r
+       template<typename Y>    \r
+       safe_ptr(Y&& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+               : impl_(std::make_shared<Y>(std::forward<Y>(impl))) {}\r
+\r
+       template<typename Y>\r
+       typename std::enable_if<std::is_convertible<Y*, T*>::value, safe_ptr<T>&>::type\r
+       operator=(const safe_ptr<Y>& other)\r
+       {\r
+               safe_ptr<T> temp(other);\r
+               temp.swap(*this);\r
+               return *this;\r
+       }\r
+\r
+       template <typename Y>\r
+       typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, safe_ptr<T>&>::type\r
+       operator=(Y&& impl)\r
+       {\r
+               safe_ptr<T> temp(std::forward<T>(impl));\r
+               temp.swap(*this);\r
+               return *this;\r
+       }\r
+\r
+       T& operator*() const { return *impl_.get();}\r
+\r
+       T* operator->() const { return impl_.get();}\r
+\r
+       T* get() const { return impl_.get();}\r
+\r
+       bool unique() const { return impl_.unique();}\r
+\r
+       long use_count() const { return impl_.use_count();}\r
+                               \r
+       void swap(safe_ptr& other) { impl_.swap(other.impl_); } \r
+       \r
+       std::shared_ptr<T> get_shared() const   { return impl_; }\r
+\r
+       static safe_ptr<T> from_shared(const std::shared_ptr<T>& impl) { return safe_ptr<T>(impl); }\r
+\r
+private:               \r
+       \r
+       template<typename Y>    \r
+       safe_ptr(const std::shared_ptr<Y>& impl, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(impl)\r
+       {\r
+               if(!impl)\r
+                       BOOST_THROW_EXCEPTION(null_argument() << msg_info("impl"));\r
+       }\r
+\r
+       std::shared_ptr<T> impl_;\r
+};\r
+\r
+template<class T, class U>\r
+bool operator==(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+{\r
+       return a.get() == b.get();\r
+}\r
+\r
+template<class T, class U>\r
+bool operator!=(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+{\r
+       return a.get() != b.get();\r
+}\r
+\r
+template<class T, class U>\r
+bool operator<(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+{\r
+       return a.get() < b.get();\r
+}\r
+\r
+template<class T> void swap(safe_ptr<T> & a, safe_ptr<T> & b)\r
+{\r
+       a.swap(b);\r
+}\r
+\r
+template<class T> T* get_pointer(safe_ptr<T> const & p)\r
+{\r
+       return p.get();\r
+}\r
+\r
+template<typename T>\r
+safe_ptr<T> make_safe()\r
+{\r
+       static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
+       return safe_ptr<T>();\r
+}\r
+\r
+template<typename T, typename P0>\r
+safe_ptr<T> make_safe(P0&& p0)\r
+{\r
+       static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
+       return safe_ptr<T>(T(std::forward<P0>(p0)));\r
+}\r
+\r
+template<typename T, typename P0, typename P1>\r
+safe_ptr<T> make_safe(P0&& p0, P1&& p1)\r
+{\r
+       static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
+       return safe_ptr<T>(T(std::forward<P0>(p0), std::forward<P1>(p1)));\r
+}\r
+\r
+template<typename T, typename P0, typename P1, typename P2>\r
+safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2)\r
+{\r
+       static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
+       return safe_ptr<T>(T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
+}\r
+\r
+}
\ No newline at end of file
index b99eea93b0c53004a4261a184bbede3bb4c44a1c..d9047e1c7d1f7697c3364ed40f665275a0225ee8 100644 (file)
@@ -3,7 +3,7 @@
 #include <tbb/concurrent_queue.h>\r
 #include <tbb/scalable_allocator.h>\r
 \r
-namespace caspar { namespace common {\r
+namespace caspar {\r
 \r
 template <typename T>\r
 class singleton_pool\r
@@ -78,4 +78,4 @@ private:
        }\r
 };\r
 \r
-}}
\ No newline at end of file
+}
\ No newline at end of file
index a31d40c6ae8864dd4b5a0353519a7b328ecad26e..34ea86553a6c7189baef8f612e8ffeff75e039ea 100644 (file)
@@ -6,7 +6,7 @@
 #include <sstream>\r
 #include <boost/lexical_cast.hpp>\r
           \r
-namespace caspar { namespace common {\r
+namespace caspar {\r
 \r
 inline std::wstring widen(const std::string& str, const std::locale& locale = std::locale())\r
 {\r
@@ -76,4 +76,4 @@ inline T lexical_cast_or_default(const std::wstring str, T defaultValue = T())
        return defaultValue;\r
 }\r
 \r
-}}
\ No newline at end of file
+}
\ No newline at end of file
index 5df253ea02f01f99c28c8056fd08aaf2a1983cc6..44959a98c14125d99cbdc8ed949fd50f6fbdb4a0 100644 (file)
@@ -21,7 +21,7 @@ public:
                producer_device_->clear();\r
        }\r
        \r
-       void load(int render_layer, const frame_producer_ptr& producer, load_option::type option = load_option::none)\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none)\r
        {\r
                producer_device_->load(render_layer, producer, option);\r
        }\r
@@ -51,12 +51,12 @@ public:
                producer_device_->clear();\r
        }\r
        \r
-       boost::unique_future<frame_producer_ptr> foreground(int render_layer) const\r
+       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const\r
        {\r
                return producer_device_->foreground(render_layer);\r
        }\r
 \r
-       boost::unique_future<frame_producer_ptr> background(int render_layer) const\r
+       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const\r
        {\r
                return producer_device_->background(render_layer);\r
        }\r
@@ -74,14 +74,14 @@ private:
 \r
 channel::channel(const frame_producer_device_ptr& producer_device, const frame_processor_device_ptr& processor_device, const frame_consumer_device_ptr& consumer_device)\r
        : impl_(new implementation(producer_device, processor_device, consumer_device)){}\r
-void channel::load(int render_layer, const frame_producer_ptr& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
+void channel::load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
 void channel::pause(int render_layer){impl_->pause(render_layer);}\r
 void channel::play(int render_layer){impl_->play(render_layer);}\r
 void channel::stop(int render_layer){impl_->stop(render_layer);}\r
 void channel::clear(int render_layer){impl_->clear(render_layer);}\r
 void channel::clear(){impl_->clear();}\r
-boost::unique_future<frame_producer_ptr> channel::foreground(int render_layer) const{  return impl_->foreground(render_layer);}\r
-boost::unique_future<frame_producer_ptr> channel::background(int render_layer) const{return impl_->background(render_layer);}\r
+boost::unique_future<safe_ptr<frame_producer>> channel::foreground(int render_layer) const{    return impl_->foreground(render_layer);}\r
+boost::unique_future<safe_ptr<frame_producer>> channel::background(int render_layer) const{return impl_->background(render_layer);}\r
 const video_format_desc& channel::get_video_format_desc() const{       return impl_->get_video_format_desc();}\r
 \r
 }}
\ No newline at end of file
index d3b698a8a07d7bc854bba936fac05a89ddaf7af0..d05c1b0172f5eceda5b3e2d47529b6118c6277b9 100644 (file)
@@ -25,14 +25,14 @@ class channel : boost::noncopyable
 public:\r
        channel(const frame_producer_device_ptr& producer_device, const frame_processor_device_ptr& processor_device, const frame_consumer_device_ptr& consumer_device);\r
        \r
-       void load(int render_layer, const frame_producer_ptr& producer, load_option::type option = load_option::none);\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);\r
        void pause(int render_layer);\r
        void play(int render_layer);\r
        void stop(int render_layer);\r
        void clear(int render_layer);\r
        void clear();   \r
-       boost::unique_future<frame_producer_ptr> foreground(int render_layer) const;\r
-       boost::unique_future<frame_producer_ptr> background(int render_layer) const;\r
+       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const;\r
+       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const;\r
        const video_format_desc& get_video_format_desc() const;\r
 private:\r
        struct implementation;\r
index 6fc3866820eec6ada7212f2bacbc8c0884411633..5ab081c0ee567be41cc41345008748d715eb3ddd 100644 (file)
@@ -168,7 +168,7 @@ struct consumer::implementation : boost::noncopyable
                        CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");          \r
        }\r
 \r
-       void send(const read_frame& frame)\r
+       void send(const safe_ptr<read_frame>& frame)\r
        {                       \r
                static size_t audio_samples = 1920;\r
                static size_t audio_nchannels = 2;\r
@@ -186,12 +186,12 @@ struct consumer::implementation : boost::noncopyable
                                \r
                                if(embed_audio_)\r
                                {               \r
-                                       auto& frame_audio_data = frame.audio_data().empty() ? silence : frame.audio_data();\r
+                                       auto& frame_audio_data = frame->audio_data().empty() ? silence : frame->audio_data();\r
 \r
                                        encode_hanc(reinterpret_cast<BLUE_UINT32*>(hanc->data()), const_cast<short*>(frame_audio_data.data()), audio_samples, audio_nchannels);\r
                                                                \r
-                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame.pixel_data().begin()), \r
-                                                                                                        frame.pixel_data().size(), \r
+                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->pixel_data().begin()), \r
+                                                                                                        frame->pixel_data().size(), \r
                                                                                                         nullptr, \r
                                                                                                         BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
 \r
@@ -205,8 +205,8 @@ struct consumer::implementation : boost::noncopyable
                                }\r
                                else\r
                                {\r
-                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame.pixel_data().begin()),\r
-                                                                                                        frame.pixel_data().size(), \r
+                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->pixel_data().begin()),\r
+                                                                                                        frame->pixel_data().size(), \r
                                                                                                         nullptr,                 \r
                                                                                                         BlueImage_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
                        \r
@@ -262,7 +262,7 @@ struct consumer::implementation : boost::noncopyable
        }\r
 \r
        boost::unique_future<void> active_;\r
-       common::executor executor_;\r
+       executor executor_;\r
                        \r
        BlueVelvetPtr sdk_;\r
        \r
@@ -275,7 +275,7 @@ struct consumer::implementation : boost::noncopyable
        unsigned long   res_fmt_; \r
        unsigned long   engine_mode_;\r
 \r
-       boost::optional<read_frame> transferring_frame_;\r
+       boost::optional<safe_ptr<read_frame>> transferring_frame_;\r
 \r
        std::array<page_locked_buffer_ptr, 3> hanc_buffers_;\r
        int current_id_;\r
@@ -283,7 +283,7 @@ struct consumer::implementation : boost::noncopyable
 };\r
 \r
 consumer::consumer(const video_format_desc& format_desc, unsigned int device_index, bool embed_audio) : impl_(new implementation(format_desc, device_index, embed_audio)){}    \r
-void consumer::send(const read_frame& frame){impl_->send(frame);}\r
+void consumer::send(const safe_ptr<read_frame>& frame){impl_->send(frame);}\r
 frame_consumer::sync_mode consumer::synchronize(){return impl_->synchronize();}\r
 size_t consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 }}}\r
index 10f9a5288649da9d1aa6e393fd264f86ef37128e..37a0ce3791a4ac7e7f77fe15af367a6ed80a3b08 100644 (file)
@@ -29,7 +29,7 @@ class consumer : public frame_consumer
 public:\r
        consumer(const video_format_desc& format_desc, unsigned int deviceIndex, bool embed_audio = false);\r
        \r
-       virtual void send(const read_frame&);\r
+       virtual void send(const safe_ptr<read_frame>&);\r
        virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
index a54c5de825df3151274141d7fa922cc2d682d340..d2c0fb6d9b4a7e54ecf76d9ef6f43ccb04b339f6 100644 (file)
@@ -132,11 +132,11 @@ struct decklink_consumer::Implementation : boost::noncopyable
                CoUninitialize();\r
        }\r
        \r
-       void send(const read_frame& frame)\r
+       void send(const safe_ptr<read_frame>& frame)\r
        {\r
                active_ = executor_.begin_invoke([=]\r
                {               \r
-                       std::copy(frame.pixel_data().begin(), frame.pixel_data().end(), static_cast<char*>(reserved_frames_.front().first));\r
+                       std::copy(frame->pixel_data().begin(), frame->pixel_data().end(), static_cast<char*>(reserved_frames_.front().first));\r
                                \r
                        if(FAILED(output_->DisplayVideoFrameSync(reserved_frames_.front().second)))\r
                                CASPAR_LOG(error) << L"DECKLINK: Failed to display frame.";\r
@@ -157,7 +157,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
        }\r
                        \r
        boost::unique_future<void> active_;\r
-       common::executor executor_;\r
+       executor executor_;\r
 \r
        std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, 3> reserved_frames_;\r
 \r
@@ -171,7 +171,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
 };\r
 \r
 decklink_consumer::decklink_consumer(const video_format_desc& format_desc, bool internalKey) : pImpl_(new Implementation(format_desc, internalKey)){}\r
-void decklink_consumer::send(const read_frame& frame){pImpl_->send(frame);}\r
+void decklink_consumer::send(const safe_ptr<read_frame>& frame){pImpl_->send(frame);}\r
 frame_consumer::sync_mode decklink_consumer::synchronize(){return pImpl_->synchronize();}\r
 size_t decklink_consumer::buffer_depth() const{return pImpl_->buffer_depth();}\r
        \r
index eff9e8f01fa4ebaca7ea1081461b57f7612b96f5..b3f057c8ca96c1962538aed471cd4ec84dd02041 100644 (file)
@@ -30,7 +30,7 @@ class decklink_consumer : public frame_consumer
 public:\r
        explicit decklink_consumer(const video_format_desc& format_desc, bool internalKey = false);\r
        \r
-       virtual void send(const read_frame&);\r
+       virtual void send(const safe_ptr<read_frame>&);\r
        virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
index 6b4b4859fb97f985f8452d9e092ee02037c843d1..fc52ab3baeb03ded7e3fafa6790bfce5ddc78410 100644 (file)
@@ -38,7 +38,7 @@ struct frame_consumer : boost::noncopyable
 \r
        virtual ~frame_consumer() {}\r
 \r
-       virtual void send(const read_frame& frame) = 0;\r
+       virtual void send(const safe_ptr<read_frame>& frame) = 0;\r
        virtual sync_mode synchronize() = 0;\r
        virtual size_t buffer_depth() const = 0;\r
 };\r
index 538c461e71658d7e3a47fc720a21cebc42a2e284..b7aec6dd5004c614967b5d370d0dc3665cc86308 100644 (file)
@@ -56,7 +56,7 @@ public:
                        executor_.begin_invoke([=]{tick();});\r
        }\r
 \r
-       void process(const read_frame& frame)\r
+       void process(const safe_ptr<read_frame>& frame)\r
        {               \r
                buffer_.push_back(frame);\r
 \r
@@ -96,10 +96,10 @@ public:
                        buffer_.pop_front();\r
        }\r
 \r
-       common::executor executor_;     \r
+       executor executor_;     \r
 \r
        size_t max_depth_;\r
-       std::deque<read_frame> buffer_;         \r
+       std::deque<safe_ptr<read_frame>> buffer_;               \r
 \r
        std::vector<frame_consumer_ptr> consumers_;\r
        \r
index aa9d394fe578592e289d0009c5d62512c08a8eb8..f29fbff8cee600f1e02ff33ca34fe302f19caa24 100644 (file)
@@ -44,9 +44,9 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
                Stop();\r
        }\r
        \r
-       void send(const read_frame& frame)\r
+       void send(const safe_ptr<read_frame>& frame)\r
        {                               \r
-               input_.push(frame.audio_data()); \r
+               input_.push(frame->audio_data()); \r
 \r
                if(GetStatus() != Playing && input_.size() > 2)         \r
                        Play();         \r
@@ -113,7 +113,7 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
 };\r
 \r
 consumer::consumer(const video_format_desc&) : impl_(new implementation()){}\r
-void consumer::send(const read_frame& frame){impl_->send(frame);}\r
+void consumer::send(const safe_ptr<read_frame>& frame){impl_->send(frame);}\r
 frame_consumer::sync_mode consumer::synchronize(){return impl_->synchronize();}\r
 size_t consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 }}}\r
index 3f5530580f3d1b20d3344612c70ef77dbd5a8c46..0118c0598175824ed106af216c2af66af05e3ffe 100644 (file)
@@ -28,7 +28,7 @@ class consumer : public frame_consumer
 public:        \r
        explicit consumer(const video_format_desc& format_desc);\r
        \r
-       virtual void send(const read_frame&);\r
+       virtual void send(const safe_ptr<read_frame>&);\r
        virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
index e1383d516137e799cdac128a6c8236f9f07cc1fb..a390759b95249845611d86979c8096f550242e1d 100644 (file)
@@ -150,10 +150,10 @@ struct consumer::implementation : boost::noncopyable
                return std::make_pair(width, height);\r
        }\r
 \r
-       void render(const read_frame& frame)\r
+       void render(const safe_ptr<read_frame>& frame)\r
        {                                               \r
                auto ptr = pbos_.front().end_write();\r
-               std::copy_n(frame.pixel_data().begin(), frame.pixel_data().size(), reinterpret_cast<char*>(ptr));\r
+               std::copy_n(frame->pixel_data().begin(), frame->pixel_data().size(), reinterpret_cast<char*>(ptr));\r
 \r
                GL(glClear(GL_COLOR_BUFFER_BIT));       \r
                pbos_.back().bind_texture();                            \r
@@ -169,7 +169,7 @@ struct consumer::implementation : boost::noncopyable
                std::rotate(pbos_.begin(), pbos_.begin() + 1, pbos_.end());\r
        }\r
                \r
-       void send(const read_frame& frame)\r
+       void send(const safe_ptr<read_frame>& frame)\r
        {\r
                active_ = executor_.begin_invoke([=]\r
                {\r
@@ -193,7 +193,7 @@ struct consumer::implementation : boost::noncopyable
        }\r
                \r
        boost::unique_future<void> active_;\r
-       common::executor executor_;\r
+       executor executor_;\r
        \r
        float wratio_;\r
        float hratio_;\r
@@ -201,7 +201,7 @@ struct consumer::implementation : boost::noncopyable
        float wSize_;\r
        float hSize_;\r
 \r
-       std::array<common::gl::pixel_buffer_object, 2> pbos_;\r
+       std::array<gl::pixel_buffer_object, 2> pbos_;\r
 \r
        bool windowed_;\r
        unsigned int screen_width_;\r
@@ -217,7 +217,7 @@ struct consumer::implementation : boost::noncopyable
 \r
 consumer::consumer(const video_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed)\r
 : impl_(new implementation(format_desc, screen_index, stretch, windowed)){}\r
-void consumer::send(const read_frame& frame){impl_->send(frame);}\r
+void consumer::send(const safe_ptr<read_frame>& frame){impl_->send(frame);}\r
 frame_consumer::sync_mode consumer::synchronize(){return impl_->synchronize();}\r
 size_t consumer::buffer_depth() const{return impl_->buffer_depth();}\r
 }}}\r
index 5fd8146ac62511079c18273c9cbe1e9411c6423b..524e58054b9f03a1fc1e1f06e71c610d60deff8f 100644 (file)
@@ -38,7 +38,7 @@ class consumer : public frame_consumer
 public:        \r
        explicit consumer(const video_format_desc& format_desc, unsigned int screen_index = 0, stretch stretch = stretch::fill, bool windowed = false);\r
        \r
-       virtual void send(const read_frame&);\r
+       virtual void send(const safe_ptr<read_frame>&);\r
        virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
index f2041712bf5b8306a802bcaa02c4241fe6314472..722be679c09ca0b95a47fb7557546280930ae74a 100644 (file)
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="format\video_format.cpp">\r
+    <ClCompile Include="format\pixel_format.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="processor\composite_frame.cpp">\r
+    <ClCompile Include="format\video_format.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="processor\draw_frame.cpp">\r
+    <ClCompile Include="processor\composite_frame.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../stdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../stdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
+    <ClCompile Include="producer\frame_producer.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
     <ClCompile Include="producer\image\image_loader.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
index eb584b0940c5a65e6afeb770fbc5169f5eec06be..2f50212febf20fd9a7456cfffb700db37a8928b4 100644 (file)
     <ClCompile Include="producer\ffmpeg\input.cpp">\r
       <Filter>Source\channel\producer\ffmpeg\io</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="processor\draw_frame.cpp">\r
-      <Filter>Source\channel\processor\frame</Filter>\r
+    <ClCompile Include="producer\frame_producer.cpp">\r
+      <Filter>Source\channel\producer</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="format\pixel_format.cpp">\r
+      <Filter>Source\channel\format</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
diff --git a/core/format/pixel_format.cpp b/core/format/pixel_format.cpp
new file mode 100644 (file)
index 0000000..10d802f
--- /dev/null
@@ -0,0 +1,48 @@
+#include "..\StdAfx.h"\r
+\r
+#include "pixel_format.h"\r
+\r
+namespace caspar { namespace core {\r
+       \r
+size_t hash(const pixel_format_desc& desc)\r
+{\r
+       size_t hash = 0;\r
+       switch(desc.pix_fmt)\r
+       {\r
+       case pixel_format::ycbcr:\r
+       case pixel_format::ycbcra:\r
+               //  0-10 (11) width\r
+               // 11-21 (11) height\r
+               // 22-24 (3)  x-ratio\r
+               // 25-27 (3)  y-ratio\r
+               // 28-29 (2)  unused\r
+               // 30    (1)  alpha\r
+               // 31    (1)  yuv = true => 1\r
+               hash |= ( desc.planes[0].width                                                  & 0x7FF ) << 0;\r
+               hash |= ( desc.planes[0].height                                                 & 0x7FF ) << 11;\r
+               hash |= ((desc.planes[0].height/desc.planes[1].height)  & 0x7   ) << 22;\r
+               hash |= ((desc.planes[0].width/desc.planes[1].width)    & 0x7   ) << 25;\r
+               hash |= desc.pix_fmt == pixel_format::ycbcra ? (1 << 30) : 0;\r
+               hash |= 1 << 31;\r
+               return hash;\r
+       case pixel_format::bgra:\r
+       case pixel_format::rgba:\r
+       case pixel_format::argb:\r
+       case pixel_format::abgr:\r
+               \r
+               //0-10  (11) height\r
+               //11-21 (11) width\r
+               //22-29 (8)  unused\r
+               //30    (1)  alpha\r
+               //31    (1)  yuv = false => 0\r
+               hash |= (desc.planes[0].height & 0xFFFF) << 0;\r
+               hash |= (desc.planes[0].width  & 0xFFFF) << 15;\r
+               hash |= 1 << 30;\r
+               return hash;\r
+\r
+       default:\r
+               return hash;\r
+       };\r
+}\r
+       \r
+}}\r
index 41a3129c6b8556645b040d7fff222cccd5f03714..a6037b56ed4d5985d184148cf32374cd3b5e315e 100644 (file)
@@ -40,5 +40,26 @@ struct pixel_format_desc
        pixel_format::type pix_fmt;\r
        std::vector<plane> planes;\r
 };\r
+\r
+size_t hash(const pixel_format_desc& desc);\r
+       \r
+inline bool operator==(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
+{\r
+       return hash(lhs) == hash(rhs);\r
+}\r
+\r
+inline bool operator!=(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
+{\r
+       return !(lhs == rhs);\r
+}\r
        \r
-}}
\ No newline at end of file
+}}\r
+\r
+namespace std {\r
+\r
+template<> struct hash<caspar::core::pixel_format_desc>\r
+{\r
+       size_t operator()(const caspar::core::pixel_format_desc& desc) const { return caspar::core::hash(desc);}\r
+};\r
+\r
+}
\ No newline at end of file
index 6e7c5d7f793615d86012a3b7910174e4da9623b1..6283303f0f526393b442ce918391ab142c019c58 100644 (file)
@@ -14,24 +14,24 @@ namespace caspar { namespace core {
        \r
 struct composite_frame::implementation\r
 {      \r
-       implementation(std::vector<draw_frame>&& frames) : frames_(std::move(frames))\r
+       implementation(std::vector<safe_ptr<draw_frame>>&& frames) : frames_(std::move(frames))\r
        {               \r
                if(frames_.size() < 2)\r
                        return;\r
 \r
-               boost::range::for_each(frames_, [&](const draw_frame& frame)\r
+               boost::range::for_each(frames_, [&](const safe_ptr<draw_frame>& frame)\r
                {\r
                        if(audio_data_.empty())\r
-                               audio_data_ = frame.audio_data();\r
+                               audio_data_ = frame->audio_data();\r
                        else\r
                        {\r
                                tbb::parallel_for\r
                                (\r
-                                       tbb::blocked_range<size_t>(0, frame.audio_data().size()),\r
+                                       tbb::blocked_range<size_t>(0, frame->audio_data().size()),\r
                                        [&](const tbb::blocked_range<size_t>& r)\r
                                        {\r
                                                for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
-                                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + static_cast<int>(frame.audio_data()[n])) & 0xFFFF);                                             \r
+                                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + static_cast<int>(frame->audio_data()[n])) & 0xFFFF);                                            \r
                                        }\r
                                );\r
                        }\r
@@ -40,48 +40,49 @@ struct composite_frame::implementation
        \r
        void begin_write()\r
        {\r
-               boost::range::for_each(frames_, std::bind(&detail::draw_frame_access::begin_write, std::placeholders::_1));\r
+               boost::range::for_each(frames_, std::bind(&draw_frame::begin_write, std::placeholders::_1));\r
        }\r
 \r
        void end_write()\r
        {\r
-               boost::range::for_each(frames_, std::bind(&detail::draw_frame_access::end_write, std::placeholders::_1));\r
+               boost::range::for_each(frames_, std::bind(&draw_frame::end_write, std::placeholders::_1));\r
        }\r
        \r
        void draw(frame_shader& shader)\r
        {\r
-               boost::range::for_each(frames_, std::bind(&detail::draw_frame_access::draw, std::placeholders::_1, std::ref(shader)));\r
+               boost::range::for_each(frames_, std::bind(&draw_frame::draw, std::placeholders::_1, std::ref(shader)));\r
        }\r
 \r
        const std::vector<short>& audio_data()\r
        {\r
                static std::vector<short> no_audio;\r
-               return !audio_data_.empty() ? audio_data_ : (!frames_.empty() ? frames_.front().audio_data() : no_audio);\r
+               return !audio_data_.empty() ? audio_data_ : (!frames_.empty() ? frames_.front()->audio_data() : no_audio);\r
        }\r
                                \r
        std::vector<short> audio_data_;\r
-       std::vector<draw_frame> frames_;\r
+       std::vector<safe_ptr<draw_frame>> frames_;\r
 };\r
 \r
-composite_frame::composite_frame(std::vector<draw_frame>&& frames) : impl_(common::singleton_pool<implementation>::make_shared(std::move(frames))){}\r
+composite_frame::composite_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(singleton_pool<implementation>::make_shared(std::move(frames))){}\r
 composite_frame::composite_frame(composite_frame&& other) : impl_(std::move(other.impl_)){}\r
-composite_frame::composite_frame(const composite_frame& other) : impl_(common::singleton_pool<implementation>::make_shared(*other.impl_)){}\r
+composite_frame::composite_frame(const composite_frame& other) : impl_(singleton_pool<implementation>::make_shared(*other.impl_)){}\r
 void composite_frame::swap(composite_frame& other){impl_.swap(other.impl_);}\r
 composite_frame& composite_frame::operator=(const composite_frame& other)\r
 {\r
        composite_frame temp(other);\r
-       temp.impl_.swap(impl_);\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
 composite_frame& composite_frame::operator=(composite_frame&& other)\r
 {\r
-       impl_ = std::move(other.impl_);\r
+       composite_frame temp(std::move(other));\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
 \r
-composite_frame::composite_frame(draw_frame&& frame1, draw_frame&& frame2)\r
+composite_frame::composite_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2)\r
 {\r
-       std::vector<draw_frame> frames;\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(std::move(frame1));\r
        frames.push_back(std::move(frame2));\r
        impl_.reset(new implementation(std::move(frames)));\r
@@ -92,7 +93,7 @@ void composite_frame::end_write(){impl_->end_write();}
 void composite_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
 const std::vector<short>& composite_frame::audio_data() const {return impl_->audio_data();}\r
 \r
-composite_frame composite_frame::interlace(draw_frame&& frame1, draw_frame&& frame2, video_mode::type mode)\r
+safe_ptr<composite_frame> composite_frame::interlace(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2, video_mode::type mode)\r
 {                      \r
        transform_frame my_frame1 = std::move(frame1);\r
        transform_frame my_frame2 = std::move(frame2);\r
@@ -107,10 +108,10 @@ composite_frame composite_frame::interlace(draw_frame&& frame1, draw_frame&& fra
                my_frame2.video_mode(video_mode::upper);\r
        }\r
 \r
-       std::vector<draw_frame> frames;\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(std::move(my_frame1));\r
        frames.push_back(std::move(my_frame2));\r
-       return composite_frame(std::move(frames));\r
+       return make_safe<composite_frame>(std::move(frames));\r
 }\r
 \r
 }}
\ No newline at end of file
index 94afdf011a3952490da0a16f1000cec8d466ae3e..27ffc93b0e7c3a8463f5feddfdc9ba264a403fc9 100644 (file)
 \r
 namespace caspar { namespace core {\r
        \r
-class composite_frame : public detail::draw_frame_impl\r
+class composite_frame : public draw_frame\r
 {\r
 public:\r
-       explicit composite_frame(std::vector<draw_frame>&& frames);\r
-       composite_frame(draw_frame&& frame1, draw_frame&& frame2);\r
+       explicit composite_frame(std::vector<safe_ptr<draw_frame>>&& frames);\r
+       composite_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2);\r
        \r
        void swap(composite_frame& other);\r
 \r
        composite_frame(const composite_frame& other);\r
-       composite_frame& operator=(const composite_frame& other);\r
        composite_frame(composite_frame&& other);\r
+\r
+       composite_frame& operator=(const composite_frame& other);\r
        composite_frame& operator=(composite_frame&& other);\r
 \r
-       static composite_frame interlace(draw_frame&& frame1, draw_frame&& frame2, video_mode::type mode);\r
+       static safe_ptr<composite_frame> interlace(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2, video_mode::type mode);\r
        \r
        virtual const std::vector<short>& audio_data() const;\r
 \r
diff --git a/core/processor/draw_frame.cpp b/core/processor/draw_frame.cpp
deleted file mode 100644 (file)
index bb09353..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "../stdafx.h"\r
-\r
-#include "draw_frame.h"\r
-\r
-#include "frame_shader.h"\r
-\r
-namespace caspar { namespace core {\r
-       \r
-struct null_frame : public detail::draw_frame_impl\r
-{\r
-       virtual const std::vector<short>& audio_data() const\r
-       {\r
-               static std::vector<short> no_audio;\r
-               return no_audio;\r
-       }\r
-       virtual void begin_write(){}\r
-       virtual void end_write(){}\r
-       virtual void draw(frame_shader&){}\r
-};\r
-\r
-static const std::shared_ptr<null_frame>& get_empty()\r
-{\r
-       static auto empty = std::make_shared<null_frame>();\r
-       return empty;\r
-}\r
-       \r
-static const std::shared_ptr<null_frame>& get_eof()\r
-{\r
-       static auto eof = std::make_shared<null_frame>();\r
-       return eof;\r
-}\r
-\r
-draw_frame::draw_frame() : impl_(get_empty()){}\r
-draw_frame::draw_frame(const draw_frame& other) : impl_(other.impl_){}\r
-draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){other.impl_ = get_empty();}\r
-draw_frame::draw_frame(eof_frame){impl_ = get_eof();}\r
-draw_frame::draw_frame(empty_frame){impl_ = get_empty();}\r
-\r
-void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
-               \r
-bool draw_frame::operator==(const eof_frame&){return impl_ == get_eof();}\r
-bool draw_frame::operator==(const empty_frame&){return impl_ == get_empty();}\r
-bool draw_frame::operator==(const draw_frame& other){return impl_ == other.impl_;}\r
-       \r
-draw_frame& draw_frame::operator=(const draw_frame& other)\r
-{\r
-       draw_frame temp(other);\r
-       temp.swap(*this);\r
-       return *this;\r
-}\r
-\r
-draw_frame& draw_frame::operator=(draw_frame&& other)\r
-{\r
-       draw_frame temp(other);\r
-       temp.swap(*this);\r
-       return *this;\r
-}\r
-\r
-draw_frame& draw_frame::operator=(eof_frame&&)\r
-{\r
-       impl_ = get_eof();\r
-       return *this;\r
-}      \r
-\r
-draw_frame& draw_frame::operator=(empty_frame&&)\r
-{\r
-       impl_ = get_empty();\r
-       return *this;\r
-}      \r
-\r
-eof_frame draw_frame::eof(){return eof_frame();}\r
-empty_frame draw_frame::empty(){return empty_frame();}\r
-\r
-const std::vector<short>& draw_frame::audio_data() const{return impl_->audio_data();}  \r
-\r
-void draw_frame::begin_write(){impl_->begin_write();}\r
-void draw_frame::end_write(){impl_->end_write();}\r
-void draw_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
-\r
-}}
\ No newline at end of file
index b84ade755a033e79d638a2dd852ddf227ed43099..48d97dd850c01e02131c0754bc4f1fa0798714a9 100644 (file)
@@ -4,92 +4,60 @@
 \r
 #include <boost/noncopyable.hpp>\r
 #include <boost/range/iterator_range.hpp>\r
-#include <boost/variant.hpp>\r
 #include <boost/operators.hpp>\r
 \r
 #include <memory>\r
 #include <vector>\r
 #include <type_traits>\r
 \r
+#include "../../common/utility/safe_ptr.h"\r
+\r
 namespace caspar { namespace core {\r
                \r
-namespace detail\r
-{\r
-\r
-class draw_frame_impl : boost::noncopyable\r
+class draw_frame : boost::noncopyable\r
 {      \r
 public:\r
-       virtual ~draw_frame_impl(){}\r
+       virtual ~draw_frame(){}\r
 \r
        virtual const std::vector<short>& audio_data() const = 0;               \r
        virtual void begin_write() = 0;\r
        virtual void end_write() = 0;\r
        virtual void draw(frame_shader& shader) = 0;\r
-};\r
-\r
-struct draw_frame_access;\r
-\r
-}\r
-\r
-struct eof_frame{};\r
-struct empty_frame{};\r
-\r
-class draw_frame : boost::equality_comparable<draw_frame>, boost::equality_comparable<eof_frame>, boost::equality_comparable<empty_frame>\r
-{\r
-public:\r
-       draw_frame();\r
-       draw_frame(const draw_frame& other);\r
-       draw_frame(draw_frame&& other);\r
-       draw_frame(eof_frame);\r
-       draw_frame(empty_frame);\r
 \r
-       template<typename T>\r
-       draw_frame(T&& impl, typename std::enable_if<std::is_base_of<detail::draw_frame_impl, typename std::remove_reference<T>::type>::value, void>::type* dummy = nullptr)\r
-               : impl_(std::make_shared<T>(std::forward<T>(impl))) {dummy;}\r
-                       \r
-       void swap(draw_frame& other);\r
-       \r
-       template <typename T>\r
-       typename std::enable_if<std::is_base_of<detail::draw_frame_impl, typename std::remove_reference<T>::type>::value, draw_frame&>::type\r
-       operator=(T&& impl)\r
+       static safe_ptr<draw_frame> eof()\r
        {\r
-               draw_frame temp(std::forward<T>(impl));\r
-               temp.swap(*this);\r
-               return *this;\r
+               struct eof_frame : public draw_frame\r
+               {\r
+                       virtual const std::vector<short>& audio_data() const\r
+                       {\r
+                               static std::vector<short> audio_data;\r
+                               return audio_data;\r
+                       }\r
+                       virtual void begin_write(){}\r
+                       virtual void end_write(){}\r
+                       virtual void draw(frame_shader&){}\r
+               };\r
+               static safe_ptr<draw_frame> frame = make_safe<eof_frame>();\r
+               return frame;\r
        }\r
-       \r
-       draw_frame& operator=(const draw_frame& other);\r
-       draw_frame& operator=(draw_frame&& other);\r
 \r
-       draw_frame& operator=(eof_frame&&);\r
-       draw_frame& operator=(empty_frame&&);\r
-       \r
-       bool operator==(const draw_frame& other);\r
-       bool operator==(const eof_frame&);\r
-       bool operator==(const empty_frame&);\r
-\r
-       static eof_frame eof();\r
-       static empty_frame empty();\r
-               \r
-       const std::vector<short>& audio_data() const;\r
-private:               \r
-       friend struct detail::draw_frame_access;\r
-\r
-       void begin_write();\r
-       void end_write();\r
-       void draw(frame_shader& shader);\r
-\r
-       std::shared_ptr<detail::draw_frame_impl> impl_;\r
+       static safe_ptr<draw_frame> empty()\r
+       {\r
+               struct empty_frame : public draw_frame\r
+               {\r
+                       virtual const std::vector<short>& audio_data() const\r
+                       {\r
+                               static std::vector<short> audio_data;\r
+                               return audio_data;\r
+                       }\r
+                       virtual void begin_write(){}\r
+                       virtual void end_write(){}\r
+                       virtual void draw(frame_shader&){}\r
+               };\r
+               static safe_ptr<draw_frame> frame = make_safe<empty_frame>();\r
+               return frame;\r
+       }\r
 };\r
 \r
-namespace detail\r
-{\r
-       struct draw_frame_access\r
-       {\r
-               static void begin_write(draw_frame& frame){frame.begin_write();}\r
-               static void end_write(draw_frame& frame){frame.end_write();}\r
-               static void draw(draw_frame& frame, frame_shader& shader){frame.draw(shader);}\r
-       };\r
-}\r
 \r
 }}
\ No newline at end of file
index b3f165280040150033ff02f3edf8f5d8baaa977a..c3d9ebd2d8a4f92e85b46a79d91e7cb1c114fdcd 100644 (file)
 \r
 namespace caspar { namespace core {\r
        \r
-using namespace common::gl;\r
-\r
 struct frame_processor_device::implementation : boost::noncopyable\r
 {      \r
-       typedef tbb::concurrent_bounded_queue<pbo_ptr> pbo_pool;\r
-\r
        implementation(const video_format_desc& format_desc) : fmt_(format_desc), underrun_count_(0)\r
        {               \r
                output_.set_capacity(3);\r
@@ -46,15 +42,15 @@ struct frame_processor_device::implementation : boost::noncopyable
                });\r
        }\r
                                \r
-       void send(const draw_frame& frame)\r
+       void send(const safe_ptr<draw_frame>& frame)\r
        {                       \r
                auto future = executor_.begin_invoke([=]{return renderer_->render(frame);});    \r
                output_.push(std::move(future)); // Blocks\r
        }\r
 \r
-       read_frame receive()\r
+       safe_ptr<read_frame> receive()\r
        {\r
-               boost::shared_future<read_frame> future;\r
+               boost::shared_future<safe_ptr<read_frame>> future;\r
 \r
                if(!output_.try_pop(future))\r
                {\r
@@ -72,73 +68,45 @@ struct frame_processor_device::implementation : boost::noncopyable
                return future.get();\r
        }\r
        \r
-       write_frame create_frame(const pixel_format_desc& desc)\r
+       safe_ptr<write_frame> create_frame(const pixel_format_desc& desc)\r
        {\r
-               std::vector<pbo_pool*> pools(desc.planes.size());\r
-               boost::range::transform(desc.planes, pools.begin(), [&](const pixel_format_desc::plane& plane)\r
-               {\r
-                       return &pbo_pools_[((plane.width & 0x7FF)) << 0 | ((plane.height & 0x7FF)) << 11 | plane.channels];\r
-               });\r
-\r
-               bool filled = true;\r
-               std::vector<pbo_ptr> pbos(pools.size());\r
-               boost::range::transform(pools, pbos.begin(), [&](pbo_pool* pool) -> pbo_ptr\r
-               {\r
-                       pbo_ptr pbo;\r
-                       filled &= pool->try_pop(pbo);\r
-                       return pbo;\r
-               });\r
-               \r
-               if(!filled)\r
-               {\r
-                       executor_.invoke([&]\r
-                       {\r
-                               for(size_t n = 0; n < pbos.size(); ++n)\r
-                               {\r
-                                       if(!pbos[n])\r
-                                               pbos[n] = create_pooled_pbo(desc.planes[n], pools[n]);\r
-                               }\r
-                       });\r
-               }\r
+               auto pool = &pools_[desc];\r
+               std::shared_ptr<write_frame> frame;\r
+               if(!pool->try_pop(frame))\r
+                       frame = executor_.invoke([&]{return std::make_shared<write_frame>(desc);});\r
                \r
-               return write_frame(std::move(pbos), desc);\r
-       }\r
-\r
-       pbo_ptr create_pooled_pbo(const pixel_format_desc::plane& plane, pbo_pool* pool)\r
-       {\r
-               static GLenum mapping[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
-               auto pooled_pbo = std::make_shared<pbo>(plane.width, plane.height, mapping[plane.channels-1]);\r
-               pooled_pbo->end_write();\r
-               return pbo_ptr(pooled_pbo.get(), [=](pbo*)\r
+               frame = std::shared_ptr<write_frame>(frame.get(), [=](write_frame*)\r
                {\r
                        executor_.begin_invoke([=]\r
                        {\r
-                               pooled_pbo->end_write();\r
-                               pool->push(pooled_pbo);\r
+                               frame->reset();\r
+                               pool->push(frame);\r
                        });\r
                });\r
+\r
+               return safe_ptr<write_frame>::from_shared(frame);\r
        }\r
                                \r
-       common::executor executor_;     \r
+       executor executor_;     \r
 \r
        std::unique_ptr<sf::Context> ogl_context_;\r
        std::unique_ptr<frame_renderer> renderer_;      \r
                                \r
-       tbb::concurrent_bounded_queue<boost::shared_future<read_frame>> output_;        \r
+       tbb::concurrent_bounded_queue<boost::shared_future<safe_ptr<read_frame>>> output_;      \r
 \r
-       tbb::concurrent_unordered_map<int, pbo_pool> pbo_pools_;\r
+       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<std::shared_ptr<write_frame>>, std::hash<pixel_format_desc>> pools_;\r
        \r
        const video_format_desc fmt_;\r
        long underrun_count_;\r
 };\r
        \r
 frame_processor_device::frame_processor_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-void frame_processor_device::send(const draw_frame& frame){impl_->send(std::move(frame));}\r
-read_frame frame_processor_device::receive(){return impl_->receive();}\r
+void frame_processor_device::send(const safe_ptr<draw_frame>& frame){impl_->send(std::move(frame));}\r
+safe_ptr<read_frame> frame_processor_device::receive(){return impl_->receive();}\r
 const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_; }\r
 \r
-write_frame frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }           \r
-write_frame frame_processor_device::create_frame(size_t width, size_t height)\r
+safe_ptr<write_frame> frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }         \r
+safe_ptr<write_frame> frame_processor_device::create_frame(size_t width, size_t height)\r
 {\r
        // Create bgra frame\r
        pixel_format_desc desc;\r
@@ -147,7 +115,7 @@ write_frame frame_processor_device::create_frame(size_t width, size_t height)
        return create_frame(desc);\r
 }\r
                        \r
-write_frame frame_processor_device::create_frame()\r
+safe_ptr<write_frame> frame_processor_device::create_frame()\r
 {\r
        // Create bgra frame with output resolution\r
        pixel_format_desc desc;\r
index 2df3da6f7ca781ea6e0f7f7fbe4c271557d0e732..d899087434312b9e07d7b154e8ceb744354cc34b 100644 (file)
@@ -34,12 +34,12 @@ class frame_processor_device : boost::noncopyable
 public:\r
        frame_processor_device(const video_format_desc& format_desc);\r
                \r
-       void send(const draw_frame& frame);\r
-       read_frame receive();\r
+       void send(const safe_ptr<draw_frame>& frame);\r
+       safe_ptr<read_frame> receive();\r
        \r
-       write_frame create_frame(const pixel_format_desc& desc);                \r
-       write_frame create_frame(size_t width, size_t height);                  \r
-       write_frame create_frame();\r
+       safe_ptr<write_frame> create_frame(const pixel_format_desc& desc);              \r
+       safe_ptr<write_frame> create_frame(size_t width, size_t height);                        \r
+       safe_ptr<write_frame> create_frame();\r
        \r
        const video_format_desc& get_video_format_desc() const;\r
 private:\r
index e06cd84e08f1002f275630198e5431b0f866ab27..76450f8cc821b76504d0f01290cd7a47a8c858d5 100644 (file)
 \r
 namespace caspar { namespace core {\r
 \r
-using namespace common::gl;\r
-       \r
 struct frame_renderer::implementation : boost::noncopyable\r
-{      \r
-       typedef std::pair<pbo_ptr, std::vector<short>> reading_frame;\r
-       \r
+{              \r
        implementation(const video_format_desc& format_desc) : shader_(format_desc), format_desc_(format_desc),\r
-               reading_(create_reading(std::vector<short>())), fbo_(format_desc.width, format_desc.height)\r
+               reading_(create_reading()), fbo_(format_desc.width, format_desc.height), writing_(draw_frame::empty()), drawing_(draw_frame::empty())\r
        {       \r
                GL(glEnable(GL_POLYGON_STIPPLE));\r
                GL(glEnable(GL_TEXTURE_2D));\r
@@ -40,28 +36,28 @@ struct frame_renderer::implementation : boost::noncopyable
                GL(glDisable(GL_DEPTH_TEST));\r
                GL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));                  \r
                GL(glViewport(0, 0, format_desc.width, format_desc.height));\r
-               reading_.first->begin_read();\r
+               reading_->begin_read();\r
        }\r
                                \r
-       read_frame render(const draw_frame& frame)\r
+       safe_ptr<read_frame> render(const safe_ptr<draw_frame>& frame)\r
        {\r
-               reading_frame result;\r
+               safe_ptr<read_frame> result = create_reading();\r
                try\r
                {\r
                        drawing_ = writing_;\r
                        writing_ = frame;\r
                                                \r
-                       detail::draw_frame_access::begin_write(writing_);\r
+                       writing_->begin_write();\r
                                                \r
-                       reading_.first->end_read();\r
-                       result = reading_; \r
+                       reading_->end_read();\r
                                                \r
                        GL(glClear(GL_COLOR_BUFFER_BIT));\r
                                                \r
-                       detail::draw_frame_access::draw(drawing_, shader_);\r
+                       drawing_->draw(shader_);\r
                                \r
-                       reading_ = create_reading(std::vector<short>(drawing_.audio_data().begin(), drawing_.audio_data().end()));                      \r
-                       reading_.first->begin_read();\r
+                       result.swap(reading_);\r
+                       reading_->begin_read();\r
+                       reading_->audio_data(drawing_->audio_data());\r
                                                \r
                        drawing_ = draw_frame::empty();\r
                }\r
@@ -70,30 +66,30 @@ struct frame_renderer::implementation : boost::noncopyable
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
 \r
-               return read_frame(std::move(result.first), std::move(result.second));\r
+               return result;\r
        }\r
 \r
-       reading_frame create_reading(const std::vector<short>& audio_data)\r
+       safe_ptr<read_frame> create_reading()\r
        {\r
-               pbo_ptr new_pbo;\r
-               if(!pbo_pool_.try_pop(new_pbo))         \r
-                       new_pbo = std::make_shared<pbo>(format_desc_.width, format_desc_.height, GL_BGRA);              \r
-               new_pbo = pbo_ptr(new_pbo.get(), [=](pbo*){pbo_pool_.push(new_pbo);});\r
-               return reading_frame(std::move(new_pbo), audio_data);\r
+               std::shared_ptr<read_frame> frame;\r
+               if(!pool_.try_pop(frame))               \r
+                       frame = std::make_shared<read_frame>(format_desc_.width, format_desc_.height);\r
+               frame = std::shared_ptr<read_frame>(frame.get(), [=](read_frame*){pool_.push(frame);});\r
+               return safe_ptr<read_frame>::from_shared(frame);\r
        }\r
        \r
        const video_format_desc format_desc_;\r
-       const fbo fbo_;\r
+       const gl::fbo fbo_;\r
 \r
-       tbb::concurrent_bounded_queue<pbo_ptr> pbo_pool_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<read_frame>> pool_;\r
        \r
-       reading_frame   reading_;       \r
-       draw_frame              writing_;\r
-       draw_frame              drawing_;\r
+       safe_ptr<read_frame>    reading_;       \r
+       safe_ptr<draw_frame>    writing_;\r
+       safe_ptr<draw_frame>    drawing_;\r
        \r
        frame_shader shader_;\r
 };\r
        \r
 frame_renderer::frame_renderer(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-read_frame frame_renderer::render(const draw_frame& frame){return impl_->render(std::move(frame));}\r
+safe_ptr<read_frame> frame_renderer::render(const safe_ptr<draw_frame>& frame){return impl_->render(std::move(frame));}\r
 }}
\ No newline at end of file
index c1db06cd590b202572cec2af9c8803678d6d3538..b47d8a20ecebaa74ef0294a92a324721dabaa258 100644 (file)
@@ -21,6 +21,8 @@
 \r
 #include "fwd.h"\r
 \r
+#include "../../common/utility/safe_ptr.h"\r
+\r
 #include "../format/video_format.h"\r
 \r
 #include <boost/noncopyable.hpp>\r
@@ -34,7 +36,7 @@ class frame_renderer : boost::noncopyable
 public:\r
        frame_renderer(const video_format_desc& format_desc_);\r
                \r
-       read_frame render(const draw_frame& frame);\r
+       safe_ptr<read_frame> render(const safe_ptr<draw_frame>& frame);\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index f6062b07c482637e89bb538f3d21d734aec0d657..33e8e36e7e3adb299368dad9308e984bc732a7e2 100644 (file)
@@ -80,7 +80,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "}                                                                                                                                              "                       \r
                        "                                                                                                                                               ";\r
                        \r
-               shaders_[pixel_format::abgr] = common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::abgr] = gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -88,7 +88,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "       gl_FragColor = abgr.argb * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::argb]= common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::argb]= gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "       \r
                        "{                                                                                                                                              "\r
@@ -96,7 +96,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "       gl_FragColor = argb.grab * gl_Color;                                                            "       \r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::bgra]= common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::bgra]= gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -104,7 +104,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "       gl_FragColor = bgra.rgba * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::rgba] = common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::rgba] = gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -112,7 +112,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "       gl_FragColor = rgba.bgra * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::ycbcr] = common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::ycbcr] = gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -123,7 +123,7 @@ struct frame_shader::implementation : boost::noncopyable
                        "       gl_FragColor = ycbcra_to_bgra(y, cb, cr, a) * gl_Color;                 "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::ycbcra] = common::gl::shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::ycbcra] = gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -185,7 +185,7 @@ struct frame_shader::implementation : boost::noncopyable
 \r
        const video_format_desc format_desc_;\r
        pixel_format::type current_;\r
-       std::unordered_map<pixel_format::type, common::gl::shader_program> shaders_;\r
+       std::unordered_map<pixel_format::type, gl::shader_program> shaders_;\r
 };\r
 \r
 frame_shader::frame_shader(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
index 68c887b05078db36d9e95a1c4523306eaa7f25a8..1041c0c05fed847988b09a17e4ef19dccd2af43f 100644 (file)
@@ -8,7 +8,8 @@ class read_frame;
 class write_frame;\r
 class draw_frame;\r
 \r
-class draw_frame_impl;\r
+class draw_frame;\r
+\r
 class transform_frame;\r
 class composite_frame;\r
 \r
index 3306325b75e20e1cf8765706f0347f28b0687007..42a928842ef6a8572487e4cf48600981a9b13b87 100644 (file)
@@ -12,22 +12,29 @@ namespace caspar { namespace core {
                                                                                                                                                                                                                                                                                                                        \r
 struct read_frame::implementation : boost::noncopyable\r
 {\r
-       implementation(common::gl::pbo_ptr&& pbo, std::vector<short>&& audio_data) : pbo_(std::move(pbo)), audio_data_(std::move(audio_data)){}                         \r
-       common::gl::pbo_ptr pbo_;\r
-       std::vector<short> audio_data_;\r
+       implementation(size_t width, size_t height) : pbo_(width, height, GL_BGRA)\r
+       {\r
+               CASPAR_LOG(trace) << "Allocated read_frame.";\r
+       }                               \r
 \r
        const boost::iterator_range<const unsigned char*> pixel_data() const\r
        {\r
-               if(!pbo_ || !pbo_->data())\r
+               if(!pbo_.data())\r
                        return boost::iterator_range<const unsigned char*>();\r
 \r
-               auto ptr = static_cast<const unsigned char*>(pbo_->data());\r
-               return boost::iterator_range<const unsigned char*>(ptr, ptr+pbo_->size());\r
+               auto ptr = static_cast<const unsigned char*>(pbo_.data());\r
+               return boost::iterator_range<const unsigned char*>(ptr, ptr+pbo_.size());\r
        }\r
+\r
+       gl::pbo pbo_;\r
+       std::vector<short> audio_data_;\r
 };\r
-       \r
-read_frame::read_frame(common::gl::pbo_ptr&& pbo, std::vector<short>&& audio_data) : impl_(common::singleton_pool<implementation>::make_shared(std::move(pbo), std::move(audio_data))){}\r
+\r
+read_frame::read_frame(size_t width, size_t height) : impl_(singleton_pool<implementation>::make_shared(width, height)){}\r
 const boost::iterator_range<const unsigned char*> read_frame::pixel_data() const{return impl_->pixel_data();}\r
 const std::vector<short>& read_frame::audio_data() const { return impl_->audio_data_; }\r
+void read_frame::audio_data(const std::vector<short>& audio_data) { impl_->audio_data_ = audio_data; }\r
+void read_frame::begin_read(){impl_->pbo_.begin_read();}\r
+void read_frame::end_read(){impl_->pbo_.end_read();}\r
 \r
 }}
\ No newline at end of file
index 1a3598b6cf534ad21f0e055afaa9e35092e62f27..8d5c659369b6439ba1c31b22c19929fee8c7c839 100644 (file)
 #include <memory>\r
 #include <vector>\r
 \r
+#include "../../common/utility/safe_ptr.h"\r
+\r
 namespace caspar { namespace core {\r
        \r
 class read_frame\r
 {\r
 public:\r
-       explicit read_frame(common::gl::pbo_ptr&& frame, std::vector<short>&& audio_data);\r
+       explicit read_frame(size_t width, size_t height);\r
        \r
        const boost::iterator_range<const unsigned char*> pixel_data() const;\r
        const std::vector<short>& audio_data() const;\r
 \r
 private:\r
+       friend class frame_renderer;\r
+       \r
+       void begin_read();\r
+       void end_read();\r
+       void audio_data(const std::vector<short>& audio_data);\r
+\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
index 3daf497df3c547fe9d1039780188ecf7881427d4..3acf65ee4cb24cda60dffe1013b51c89636e6bb3 100644 (file)
@@ -18,66 +18,72 @@ namespace caspar { namespace core {
                                                                                                                                                                                                                                                                                                                \r
 struct transform_frame::implementation\r
 {\r
-       implementation(const draw_frame& frame) : frame_(frame), audio_volume_(255){}\r
-       implementation(const draw_frame& frame, std::vector<short>&& audio_data) : frame_(frame), audio_volume_(255), override_audio_data_(std::move(audio_data)){}\r
-       implementation(draw_frame&& frame) : frame_(std::move(frame)), audio_volume_(255){}\r
+       implementation(const safe_ptr<draw_frame>& frame) : frame_(frame), audio_volume_(255){}\r
+       implementation(const safe_ptr<draw_frame>& frame, std::vector<short>&& audio_data) : frame_(frame), audio_volume_(255), override_audio_data_(std::move(audio_data)){}\r
+       implementation(safe_ptr<draw_frame>&& frame) : frame_(std::move(frame)), audio_volume_(255){}\r
        \r
-       void begin_write(){detail::draw_frame_access::begin_write(frame_);}\r
-       void end_write(){detail::draw_frame_access::end_write(frame_);}\r
+       void begin_write(){frame_->begin_write();}\r
+       void end_write(){frame_->end_write();}\r
 \r
        void draw(frame_shader& shader)\r
        {\r
                shader.begin(transform_);\r
-               detail::draw_frame_access::draw(frame_, shader);\r
+               frame_->draw(shader);\r
                shader.end();\r
        }\r
 \r
-       void audio_volume(unsigned char volume)\r
+       void audio_volume(const unsigned char volume)\r
        {\r
                if(volume == audio_volume_)\r
                        return;\r
                \r
                audio_volume_ = volume;\r
+\r
+               auto& source = override_audio_data_;\r
                if(override_audio_data_.empty())\r
-                       audio_data_ = frame_.audio_data();\r
+                       source = frame_->audio_data();\r
+\r
+               audio_data_.resize(source.size());\r
                tbb::parallel_for\r
                (\r
                        tbb::blocked_range<size_t>(0, audio_data_.size()),\r
                        [&](const tbb::blocked_range<size_t>& r)\r
                        {\r
                                for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
-                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n])*audio_volume_)>>8);                                               \r
+                                       audio_data_[n] = static_cast<short>((static_cast<int>(source[n])*volume)>>8);                                           \r
                        }\r
                );\r
        }\r
                \r
        const std::vector<short>& audio_data() const \r
        {\r
-               return !audio_data_.empty() ? audio_data_ : (!override_audio_data_.empty() ? override_audio_data_ : frame_.audio_data());\r
+               return !audio_data_.empty() ? audio_data_ : (!override_audio_data_.empty() ? override_audio_data_ : frame_->audio_data());\r
        }\r
                \r
        unsigned char audio_volume_;\r
-       draw_frame frame_;\r
+       safe_ptr<draw_frame> frame_;\r
        std::vector<short> audio_data_;\r
        std::vector<short> override_audio_data_;\r
        shader_transform transform_;    \r
 };\r
        \r
-transform_frame::transform_frame(const draw_frame& frame) : impl_(common::singleton_pool<implementation>::make_shared(frame)){}\r
-transform_frame::transform_frame(const draw_frame& frame, std::vector<short>&& audio_data) : impl_(common::singleton_pool<implementation>::make_shared(frame, std::move(audio_data))){}\r
-transform_frame::transform_frame(draw_frame&& frame) : impl_(common::singleton_pool<implementation>::make_shared(std::move(frame))){}\r
-transform_frame::transform_frame(const transform_frame& other) : impl_(common::singleton_pool<implementation>::make_shared(*other.impl_)){}\r
+transform_frame::transform_frame() : impl_(singleton_pool<implementation>::make_shared(draw_frame::empty())){}\r
+transform_frame::transform_frame(const safe_ptr<draw_frame>& frame) : impl_(singleton_pool<implementation>::make_shared(frame)){}\r
+transform_frame::transform_frame(const safe_ptr<draw_frame>& frame, std::vector<short>&& audio_data) : impl_(singleton_pool<implementation>::make_shared(frame, std::move(audio_data))){}\r
+transform_frame::transform_frame(safe_ptr<draw_frame>&& frame) : impl_(singleton_pool<implementation>::make_shared(std::move(frame))){}\r
+transform_frame::transform_frame(const transform_frame& other) : impl_(singleton_pool<implementation>::make_shared(*other.impl_)){}\r
 void transform_frame::swap(transform_frame& other){impl_.swap(other.impl_);}\r
 transform_frame& transform_frame::operator=(const transform_frame& other)\r
 {\r
        transform_frame temp(other);\r
-       temp.impl_.swap(impl_);\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
 transform_frame::transform_frame(transform_frame&& other) : impl_(std::move(other.impl_)){}\r
 transform_frame& transform_frame::operator=(transform_frame&& other)\r
 {\r
-       impl_ = std::move(other.impl_);\r
+       transform_frame temp(std::move(other));\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
 void transform_frame::begin_write(){impl_->begin_write();}\r
index f197fc5996d9049dcc9801f672b791277fecc9bb..febe647dec57d99e5f76d53d5d45b80a2eb45fc9 100644 (file)
 \r
 namespace caspar { namespace core {\r
                \r
-class transform_frame : public detail::draw_frame_impl\r
+class transform_frame : public draw_frame\r
 {\r
 public:\r
-       transform_frame(const draw_frame& frame);\r
-       transform_frame(const draw_frame& frame, std::vector<short>&& audio_data);\r
-       transform_frame(draw_frame&& frame);\r
+       transform_frame();\r
+       transform_frame(const safe_ptr<draw_frame>& frame);\r
+       transform_frame(const safe_ptr<draw_frame>& frame, std::vector<short>&& audio_data);\r
+       transform_frame(safe_ptr<draw_frame>&& frame);\r
 \r
        void swap(transform_frame& other);\r
        \r
        transform_frame(const transform_frame& other);\r
-       transform_frame& operator=(const transform_frame& other);\r
        transform_frame(transform_frame&& other);\r
+\r
+       transform_frame& operator=(const transform_frame& other);\r
        transform_frame& operator=(transform_frame&& other);\r
        \r
        virtual const std::vector<short>& audio_data() const;\r
index 22f1caa4909cf41d7201227994b67ba05b3c08c9..b3217ef7c2c01c7a46995ae07d7cf9d66cf21433 100644 (file)
@@ -16,16 +16,26 @@ namespace caspar { namespace core {
                                                                                                                                                                                                                                                                                                                        \r
 struct write_frame::implementation : boost::noncopyable\r
 {\r
-       implementation(std::vector<common::gl::pbo_ptr>&& pbos, const pixel_format_desc& desc) : pbos_(std::move(pbos)), desc_(desc){}\r
+       implementation(const pixel_format_desc& desc) : desc_(desc)\r
+       {\r
+               CASPAR_LOG(trace) << "Allocated write_frame.";\r
+\r
+               static GLenum mapping[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
+               std::transform(desc_.planes.begin(), desc_.planes.end(), std::back_inserter(pbos_), [&](const pixel_format_desc::plane& plane)\r
+               {\r
+                       return gl::pbo(plane.width, plane.height, mapping[plane.channels-1]);\r
+               });\r
+               end_write();\r
+       }\r
        \r
        void begin_write()\r
        {\r
-               boost::range::for_each(pbos_, std::mem_fn(&common::gl::pbo::begin_write));\r
+               boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::begin_write));\r
        }\r
 \r
        void end_write()\r
        {\r
-               boost::range::for_each(pbos_, std::mem_fn(&common::gl::pbo::end_write));\r
+               boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::end_write));\r
        }\r
 \r
        void draw(frame_shader& shader)\r
@@ -33,35 +43,47 @@ struct write_frame::implementation : boost::noncopyable
                for(size_t n = 0; n < pbos_.size(); ++n)\r
                {\r
                        glActiveTexture(GL_TEXTURE0+n);\r
-                       pbos_[n]->bind_texture();\r
+                       pbos_[n].bind_texture();\r
                }\r
                shader.render(desc_);\r
        }\r
 \r
        boost::iterator_range<unsigned char*> pixel_data(size_t index)\r
        {\r
-               auto ptr = static_cast<unsigned char*>(pbos_[index]->data());\r
-               return boost::iterator_range<unsigned char*>(ptr, ptr+pbos_[index]->size());\r
+               if(index >= pbos_.size() || !pbos_[index].data())\r
+                       return boost::iterator_range<const unsigned char*>();\r
+               auto ptr = static_cast<unsigned char*>(pbos_[index].data());\r
+               return boost::iterator_range<unsigned char*>(ptr, ptr+pbos_[index].size());\r
        }\r
        const boost::iterator_range<const unsigned char*> pixel_data(size_t index) const\r
        {\r
-               auto ptr = static_cast<const unsigned char*>(pbos_[index]->data());\r
-               return boost::iterator_range<const unsigned char*>(ptr, ptr+pbos_[index]->size());\r
+               if(index >= pbos_.size() || !pbos_[index].data())\r
+                       return boost::iterator_range<const unsigned char*>();\r
+               auto ptr = static_cast<const unsigned char*>(pbos_[index].data());\r
+               return boost::iterator_range<const unsigned char*>(ptr, ptr+pbos_[index].size());\r
+       }\r
+\r
+       void reset()\r
+       {\r
+               end_write();\r
+               audio_data_.clear();\r
        }\r
                        \r
-       std::vector<common::gl::pbo_ptr> pbos_;\r
+       std::vector<gl::pbo> pbos_;\r
        std::vector<short> audio_data_;\r
        const pixel_format_desc desc_;\r
 };\r
        \r
-write_frame::write_frame(std::vector<common::gl::pbo_ptr>&& pbos, const pixel_format_desc& desc) : impl_(common::singleton_pool<implementation>::make_shared(std::move(pbos), desc)){}\r
+write_frame::write_frame(const pixel_format_desc& desc) : impl_(singleton_pool<implementation>::make_shared(desc)){}\r
 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
 write_frame& write_frame::operator=(write_frame&& other)\r
 {\r
-       impl_ = std::move(other.impl_);\r
+       write_frame temp(std::move(other));\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
+void write_frame::reset(){impl_->reset();}\r
 void write_frame::begin_write(){impl_->begin_write();}\r
 void write_frame::end_write(){impl_->end_write();}     \r
 void write_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
index 75ed35d543b72108e2f5946b3e4f9d5bd4f97a0c..6a2b4274af5aeaeca590de81e3b872274e4a641d 100644 (file)
 \r
 namespace caspar { namespace core {\r
                \r
-class write_frame : public detail::draw_frame_impl\r
+class write_frame : public draw_frame\r
 {\r
 public:        \r
-       write_frame(std::vector<common::gl::pbo_ptr>&& pbos, const pixel_format_desc& desc);\r
+       write_frame(const pixel_format_desc& desc);\r
        write_frame(write_frame&& other);\r
        \r
        void swap(write_frame& other);\r
 \r
        write_frame& operator=(write_frame&& other);\r
 \r
+       void reset();\r
+\r
        boost::iterator_range<unsigned char*> pixel_data(size_t index = 0);\r
        const boost::iterator_range<const unsigned char*> pixel_data(size_t index = 0) const;\r
        \r
index ef3c8e593170a615f3b5a12e70840d10447230cd..4ae506d6f0f7659846d72d7cd5af3d5021ebd6b4 100644 (file)
@@ -47,7 +47,7 @@ unsigned int get_pixel_color_value(const std::wstring& parameter)
 \r
        std::wstring color_code;\r
        if(parameter.length() != 9 || parameter[0] != '#')\r
-               BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("parameter") << arg_value_info(common::narrow(parameter)) << msg_info("Invalid color code"));\r
+               BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("parameter") << arg_value_info(narrow(parameter)) << msg_info("Invalid color code"));\r
        \r
        color_code = parameter.substr(1);\r
 \r
@@ -66,17 +66,18 @@ unsigned int get_pixel_color_value(const std::wstring& parameter)
 class color_producer : public frame_producer\r
 {\r
 public:\r
-       explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)){}\r
+       explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)), frame_(draw_frame::empty()){}\r
+       color_producer(color_producer&& other) : frame_(std::move(other.frame_)), color_value_(std::move(other.color_value_)), color_str_(std::move(other.color_str_)){}\r
        \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        { \r
                return frame_;\r
        }\r
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
-               write_frame frame = std::move(frame_processor->create_frame());\r
-               __stosd(reinterpret_cast<unsigned long*>(frame.pixel_data().begin()), color_value_, frame.pixel_data().size() / sizeof(unsigned long));\r
+               auto frame = std::move(frame_processor->create_frame());\r
+               __stosd(reinterpret_cast<unsigned long*>(frame->pixel_data().begin()), color_value_, frame->pixel_data().size() / sizeof(unsigned long));\r
                frame_ = std::move(frame);\r
        }\r
        \r
@@ -85,16 +86,16 @@ public:
                return + L"color_producer. color: " + color_str_;\r
        }\r
 \r
-       draw_frame frame_;\r
+       safe_ptr<draw_frame> frame_;\r
        unsigned int color_value_;\r
        std::wstring color_str_;\r
 };\r
 \r
-frame_producer_ptr create_color_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty() || params[0].at(0) != '#')\r
-               return nullptr;\r
-       return std::make_shared<color_producer>(params[0]);\r
+               return frame_producer::empty();\r
+       return make_safe<color_producer>(params[0]);\r
 }\r
 \r
 }}
\ No newline at end of file
index 65607bbe2f83732cced17826fff457fa308d7c01..228124cf2d03ab3a63d4e68ecbf9f923e73309be 100644 (file)
@@ -26,6 +26,6 @@
 \r
 namespace caspar { namespace core {\r
        \r
-frame_producer_ptr create_color_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params);\r
 \r
 }}\r
index 4e5f338f23d89708070976072a2b75272c576481..e3dc7d66dcd94e8595fb8d04222bcf1ccc1b12f5 100644 (file)
@@ -28,8 +28,7 @@ extern "C"
 #include "video/video_transformer.h"\r
 \r
 #include "../../format/video_format.h"\r
-#include "../../processor/draw_frame.h"\r
-#include "../../processor/transform_Frame.h"\r
+#include "../../processor/transform_frame.h"\r
 #include "../../processor/draw_frame.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 #include "../../server.h"\r
@@ -47,13 +46,13 @@ using namespace boost::assign;
 \r
 namespace caspar { namespace core { namespace ffmpeg{\r
        \r
-struct ffmpeg_producer : public frame_producer\r
+struct ffmpeg_producer_impl\r
 {\r
 public:\r
-       ffmpeg_producer(const std::wstring& filename, const  std::vector<std::wstring>& params) : filename_(filename), underrun_count_(0)\r
+       ffmpeg_producer_impl(const std::wstring& filename, const  std::vector<std::wstring>& params) : filename_(filename), underrun_count_(0), last_frame_(draw_frame::empty())\r
        {\r
                if(!boost::filesystem::exists(filename))\r
-                       BOOST_THROW_EXCEPTION(file_not_found() <<  boost::errinfo_file_name(common::narrow(filename)));\r
+                       BOOST_THROW_EXCEPTION(file_not_found() <<  boost::errinfo_file_name(narrow(filename)));\r
                \r
                static boost::once_flag av_register_all_flag = BOOST_ONCE_INIT;\r
                boost::call_once(av_register_all, av_register_all_flag);        \r
@@ -63,7 +62,7 @@ public:
                                \r
                input_.reset(new input());\r
                input_->set_loop(std::find(params.begin(), params.end(), L"LOOP") != params.end());\r
-               input_->load(common::narrow(filename_));\r
+               input_->load(narrow(filename_));\r
                video_decoder_.reset(new video_decoder(input_->get_video_codec_context().get()));\r
                video_transformer_.reset(new video_transformer(input_->get_video_codec_context().get()));\r
                audio_decoder_.reset(new audio_decoder(input_->get_audio_codec_context().get()));\r
@@ -83,7 +82,7 @@ public:
                video_transformer_->initialize(frame_processor);\r
        }\r
                \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {\r
                while(ouput_channel_.empty() && !input_->is_eof())\r
                {       \r
@@ -95,7 +94,7 @@ public:
                                if(!video_packet.empty())\r
                                {\r
                                        auto decoded_frame = video_decoder_->execute(video_packet);\r
-                                       auto frame = video_transformer_->execute(decoded_frame);\r
+                                       auto frame = make_safe<transform_frame>(video_transformer_->execute(decoded_frame));\r
                                        video_frame_channel_.push_back(std::move(frame));       \r
                                }\r
                        }, \r
@@ -141,11 +140,11 @@ public:
                        }\r
                }\r
 \r
-               draw_frame result = last_frame_;\r
+               auto result = last_frame_;\r
                if(!ouput_channel_.empty())\r
                {\r
                        result = std::move(ouput_channel_.front());\r
-                       last_frame_ = transform_frame(result, std::vector<short>()); // last_frame should not have audio, override it!\r
+                       last_frame_ = make_safe<transform_frame>(result, std::vector<short>()); // last_frame should not have audio, override it!\r
                        ouput_channel_.pop();\r
                }\r
                else if(input_->is_eof())\r
@@ -161,27 +160,39 @@ public:
                        \r
        bool has_audio_;\r
 \r
-       input_uptr                                                      input_;         \r
+       input_uptr                                                              input_;         \r
 \r
-       video_decoder_uptr                                      video_decoder_;\r
-       video_transformer_uptr                          video_transformer_;\r
-       std::deque<draw_frame>                          video_frame_channel_;\r
+       video_decoder_uptr                                              video_decoder_;\r
+       video_transformer_uptr                                  video_transformer_;\r
+       std::deque<safe_ptr<transform_frame>>   video_frame_channel_;\r
        \r
-       audio_decoder_ptr                                       audio_decoder_;\r
-       std::deque<std::vector<short>>          audio_chunk_channel_;\r
+       audio_decoder_ptr                                               audio_decoder_;\r
+       std::deque<std::vector<short>>                  audio_chunk_channel_;\r
 \r
-       std::queue<draw_frame>                          ouput_channel_;\r
+       std::queue<safe_ptr<transform_frame>>   ouput_channel_;\r
        \r
-       std::wstring                                            filename_;\r
+       std::wstring                                                    filename_;\r
+\r
+       long                                                                    underrun_count_;\r
 \r
-       long                                                            underrun_count_;\r
+       safe_ptr<draw_frame>                                    last_frame_;\r
 \r
-       draw_frame                                                      last_frame_;\r
+       video_format_desc                                               format_desc_;\r
+};\r
 \r
-       video_format_desc                                       format_desc_;\r
+class ffmpeg_producer : public frame_producer\r
+{\r
+public:\r
+       ffmpeg_producer(const std::wstring& filename, const  std::vector<std::wstring>& params) : impl_(new ffmpeg_producer_impl(filename, params)){}\r
+       ffmpeg_producer(ffmpeg_producer&& other) : impl_(std::move(other.impl_)){}\r
+       virtual safe_ptr<draw_frame> receive(){return impl_->receive();}\r
+       virtual void initialize(const frame_processor_device_ptr& frame_processor){impl_->initialize(frame_processor);}\r
+       virtual std::wstring print() const{return impl_->print();}\r
+private:\r
+       std::shared_ptr<ffmpeg_producer_impl> impl_;\r
 };\r
 \r
-frame_producer_ptr create_ffmpeg_producer(const  std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_ffmpeg_producer(const  std::vector<std::wstring>& params)\r
 {      \r
        static const std::vector<std::wstring> extensions = list_of(L"mpg")(L"avi")(L"mov")(L"dv")(L"wav")(L"mp3")(L"mp4")(L"f4v")(L"flv");\r
        std::wstring filename = server::media_folder() + L"\\" + params[0];\r
@@ -192,9 +203,9 @@ frame_producer_ptr create_ffmpeg_producer(const  std::vector<std::wstring>& para
                });\r
 \r
        if(ext == extensions.end())\r
-               return nullptr;\r
+               return frame_producer::empty();\r
 \r
-       return std::make_shared<ffmpeg_producer>(filename + L"." + *ext, params);\r
+       return make_safe<ffmpeg_producer>(filename + L"." + *ext, params);\r
 }\r
 \r
 }}}
\ No newline at end of file
index bee1e01b623dbeff118bcd197bf6bfd316f596c2..fb4e444af0c62ed795feb092a92e8b400ee3122b 100644 (file)
@@ -7,6 +7,6 @@
 \r
 namespace caspar { namespace core { namespace ffmpeg {\r
        \r
-frame_producer_ptr create_ffmpeg_producer(const  std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_ffmpeg_producer(const  std::vector<std::wstring>& params);\r
 \r
 }}}
\ No newline at end of file
index fa766fb1f93213a4dddf7f4265481cf91f2a4404..d6fc248ae16822243015614ddcb53a0fba3d8b62 100644 (file)
@@ -146,7 +146,7 @@ struct input::implementation : boost::noncopyable
                        std::shared_ptr<AVPacket> packet(&tmp_packet, av_free_packet);  \r
                        tbb::queuing_mutex::scoped_lock lock(seek_mutex_);      \r
 \r
-                       if (av_read_frame(format_context_.get(), packet.get()) >= 0) // NOTE: Packet is only valid until next call of av_read_frame or av_close_input_file\r
+                       if (av_read_frame(format_context_.get(), packet.get()) >= 0) // NOTE: Packet is only valid until next call of av_safe_ptr<read_frame> or av_close_input_file\r
                        {\r
                                auto buffer = std::make_shared<aligned_buffer>(packet->data, packet->data + packet->size);\r
                                if(packet->stream_index == video_s_index_)                                              \r
index 1b080f653e02485bbc69e8262ca1cb451c6d68bd..acbfb3f5c9f80ec8d14acff39128ae92ca4b81be 100644 (file)
@@ -4,8 +4,6 @@
 \r
 #include "../../../format/video_format.h"\r
 #include "../../../processor/draw_frame.h"\r
-#include "../../../processor/draw_frame.h"\r
-#include "../../../processor/draw_frame.h"\r
 #include "../../../processor/frame_processor_device.h"\r
 \r
 #include <tbb/parallel_for.h>\r
@@ -105,7 +103,7 @@ struct video_transformer::implementation : boost::noncopyable
                }\r
        }\r
        \r
-       draw_frame execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
+       safe_ptr<draw_frame> execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
        {                               \r
                if(decoded_frame == nullptr)\r
                        return draw_frame::eof();\r
@@ -117,7 +115,7 @@ struct video_transformer::implementation : boost::noncopyable
                        tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
                        {\r
                                auto plane            = desc_.planes[n];\r
-                               auto result           = write.pixel_data(n).begin();\r
+                               auto result           = write->pixel_data(n).begin();\r
                                auto decoded          = decoded_frame->data[n];\r
                                auto decoded_linesize = decoded_frame->linesize[n];\r
                                \r
@@ -135,7 +133,7 @@ struct video_transformer::implementation : boost::noncopyable
 \r
                        AVFrame av_frame;       \r
                        avcodec_get_frame_defaults(&av_frame);\r
-                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), write.pixel_data().begin(), PIX_FMT_BGRA, width_, height_);\r
+                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), write->pixel_data().begin(), PIX_FMT_BGRA, width_, height_);\r
                 \r
                        sws_scale(sws_context_.get(), decoded_frame->data, decoded_frame->linesize, 0, height_, av_frame.data, av_frame.linesize);      \r
                        \r
@@ -160,6 +158,6 @@ struct video_transformer::implementation : boost::noncopyable
 };\r
 \r
 video_transformer::video_transformer(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
-draw_frame video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
+safe_ptr<draw_frame> video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
 void video_transformer::initialize(const frame_processor_device_ptr& frame_processor){impl_->initialize(frame_processor); }\r
 }}}
\ No newline at end of file
index f5bcdf1f6ed2592884f08e413753e6a4d05c2bae..372232dee6dce0f602f269a9643e46122c648792 100644 (file)
@@ -13,7 +13,7 @@ class video_transformer : boost::noncopyable
 {\r
 public:\r
        video_transformer(AVCodecContext* codec_context);\r
-       draw_frame execute(const std::shared_ptr<AVFrame>& video_packet);       \r
+       safe_ptr<draw_frame> execute(const std::shared_ptr<AVFrame>& video_packet);     \r
        void initialize(const frame_processor_device_ptr& frame_processor);\r
 private:\r
        struct implementation;\r
index 3fd0f24107c731a97eeacf658e9382fe958f9307..df13fadf65e4368699e198943e871dfe976e26e8 100644 (file)
@@ -30,33 +30,36 @@ struct cg_producer::implementation : boost::noncopyable
 {\r
 public:\r
 \r
-       implementation() : ver_(template_version::invalid)\r
+       implementation() : ver_(template_version::invalid), flash_producer_(create_flash())\r
        {\r
+       \r
+       }\r
+\r
+       safe_ptr<flash_producer> create_flash()\r
+       {               \r
                if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.18")))\r
                {\r
-                       flash_producer_ = std::make_shared<flash_producer>(server::template_folder()+TEXT("cg.fth.18"));\r
                        CASPAR_LOG(info) << L"Running version 1.8 template graphics.";\r
                        ver_ = template_version::_18;\r
+                       return safe_ptr<flash_producer>(flash_producer(server::template_folder()+TEXT("cg.fth.18")));\r
                }\r
                else if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.17")))\r
                {\r
-                       flash_producer_ = std::make_shared<flash_producer>(server::template_folder()+TEXT("cg.fth.17"));\r
                        CASPAR_LOG(info) << L"Running version 1.7 template graphics.";\r
                        ver_ = template_version::_17;\r
+                       return safe_ptr<flash_producer>(flash_producer(server::template_folder()+TEXT("cg.fth.17")));\r
                }\r
                else \r
-                       CASPAR_LOG(info) << L"No templatehost found. Template graphics will be disabled";               \r
+                       BOOST_THROW_EXCEPTION(file_not_found() << msg_info("No templatehost found."));  \r
        }\r
 \r
        void clear()\r
        {\r
-               flash_producer_.reset();\r
+               // TODO\r
        }\r
 \r
        void add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& label, const std::wstring& data)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking add-command";\r
                \r
                std::wstringstream param;\r
@@ -76,8 +79,6 @@ public:
 \r
        void remove(int layer)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking remove-command";\r
                \r
                std::wstringstream param;\r
@@ -88,8 +89,6 @@ public:
 \r
        void play(int layer)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking play-command";\r
                \r
                std::wstringstream param;\r
@@ -100,8 +99,6 @@ public:
 \r
        void stop(int layer, unsigned int mix_out_duration)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking stop-command";\r
                \r
                std::wstringstream param;\r
@@ -112,8 +109,6 @@ public:
 \r
        void next(int layer)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking next-command";\r
                \r
                std::wstringstream param;\r
@@ -124,8 +119,6 @@ public:
 \r
        void update(int layer, const std::wstring& data)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking update-command";\r
                \r
                std::wstringstream param;\r
@@ -136,8 +129,6 @@ public:
 \r
        void invoke(int layer, const std::wstring& label)\r
        {\r
-               if(flash_producer_ == nullptr)\r
-                       return;\r
                CASPAR_LOG(info) << "Invoking invoke-command";\r
                \r
                std::wstringstream param;\r
@@ -146,16 +137,15 @@ public:
                flash_producer_->param(param.str());\r
        }\r
 \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {\r
-               return flash_producer_ ? flash_producer_->receive() : draw_frame::empty();\r
+               return flash_producer_->receive();\r
        }\r
                \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
-               if(flash_producer_ != nullptr)\r
-                       flash_producer_->initialize(frame_processor_);\r
+               flash_producer_->initialize(frame_processor_);\r
        }\r
 \r
        std::wstring print() const\r
@@ -163,28 +153,28 @@ public:
                return L"cg_producer. back-end:" + flash_producer_->print();\r
        }\r
 \r
-       flash_producer_ptr flash_producer_;\r
+       safe_ptr<flash_producer> flash_producer_;\r
        template_version::type ver_;\r
        frame_processor_device_ptr frame_processor_;\r
 };\r
        \r
-cg_producer_ptr get_default_cg_producer(const channel_ptr& channel, int render_layer)\r
+safe_ptr<cg_producer> get_default_cg_producer(const channel_ptr& channel, int render_layer)\r
 {\r
        if(!channel)\r
                BOOST_THROW_EXCEPTION(null_argument() << msg_info("channel"));\r
        \r
-       auto producer = std::dynamic_pointer_cast<cg_producer>(channel->foreground(render_layer).get());\r
+       auto producer = std::dynamic_pointer_cast<cg_producer>(channel->foreground(render_layer).get().get_shared());\r
        if(producer == nullptr)\r
        {\r
                producer = std::make_shared<cg_producer>();             \r
-               channel->load(render_layer, producer, load_option::auto_play); \r
+               channel->load(render_layer, safe_ptr<frame_producer>::from_shared(producer), load_option::auto_play); \r
        }\r
        \r
-       return producer;\r
+       return safe_ptr<cg_producer>::from_shared(producer);\r
 }\r
 \r
 cg_producer::cg_producer() : impl_(new implementation()){}\r
-draw_frame cg_producer::receive(){return impl_->receive();}\r
+safe_ptr<draw_frame> cg_producer::receive(){return impl_->receive();}\r
 void cg_producer::clear(){impl_->clear();}\r
 void cg_producer::add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
 void cg_producer::remove(int layer){impl_->remove(layer);}\r
@@ -194,4 +184,5 @@ 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 frame_processor_device_ptr& frame_processor){impl_->initialize(frame_processor);}\r
+std::wstring cg_producer::print() const{return impl_->print();}\r
 }}}
\ No newline at end of file
index f44186ec396701ee40999e2db0d8d83c9d0e33a0..3cadd526de46f5a3ab36eb00bb6650d7e62c783d 100644 (file)
@@ -12,8 +12,9 @@ public:
        static const unsigned int DEFAULT_LAYER = 5000;\r
 \r
        cg_producer();\r
+       cg_producer(cg_producer&& other) : impl_(std::move(other.impl_)){}\r
        \r
-       virtual draw_frame receive();\r
+       virtual safe_ptr<draw_frame> receive();\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor);\r
 \r
        void clear();\r
@@ -24,13 +25,14 @@ public:
        void next(int layer);\r
        void update(int layer, const std::wstring& data);\r
        void invoke(int layer, const std::wstring& label);\r
+       \r
+       virtual std::wstring print() const;\r
 \r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<cg_producer> cg_producer_ptr;\r
 \r
-cg_producer_ptr get_default_cg_producer(const channel_ptr& channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
+safe_ptr<cg_producer> get_default_cg_producer(const channel_ptr& channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
 \r
 }}}
\ No newline at end of file
index b3a8e8343a54b8e1aeb59694b055b1735a850a56..b089b868624d55eed56ceebaadcb535559d72439 100644 (file)
@@ -35,9 +35,10 @@ namespace caspar { namespace core { namespace flash {
 \r
 struct ct_producer : public cg_producer\r
 {\r
+       ct_producer(ct_producer&& other) : initialized_(std::move(other.initialized_)), filename_(std::move(other.filename_)){}\r
        ct_producer(const std::wstring& filename) : filename_(filename), initialized_(false){}\r
 \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {\r
                if(!initialized_)\r
                {\r
@@ -56,10 +57,10 @@ struct ct_producer : public cg_producer
        std::wstring filename_;\r
 };\r
        \r
-frame_producer_ptr create_ct_producer(const std::vector<std::wstring>& params) \r
+safe_ptr<frame_producer> create_ct_producer(const std::vector<std::wstring>& params) \r
 {\r
        std::wstring filename = server::media_folder() + L"\\" + params[0] + L".ct";\r
-       return boost::filesystem::exists(filename) ? std::make_shared<ct_producer>(filename) : nullptr;\r
+       return boost::filesystem::exists(filename) ? make_safe<ct_producer>(filename) : frame_producer::empty();\r
 }\r
 \r
 }}}
\ No newline at end of file
index 5e54a097c0b2e4dc82bfd7188173676e4f05bec5..cc0a09896e8782d3349b6ae63b7d8e1c59481e0f 100644 (file)
@@ -23,6 +23,6 @@
 \r
 namespace caspar { namespace core { namespace flash{\r
                \r
-frame_producer_ptr create_ct_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_ct_producer(const std::vector<std::wstring>& params);\r
 \r
 }}}
\ No newline at end of file
index 1b15896e176da142f0f42deeb487ba9f3571c2da..ec4de6e10b29ffc97bf28a6018691b3ab41e7ea7 100644 (file)
@@ -60,7 +60,7 @@ struct flash_producer::implementation
                : flashax_container_(nullptr), filename_(filename), self_(self), executor_([=]{run();}), invalid_count_(0)\r
        {       \r
                if(!boost::filesystem::exists(filename))\r
-                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(common::narrow(filename)));\r
+                       BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));\r
 \r
                frame_buffer_.set_capacity(3);          \r
        }\r
@@ -151,7 +151,7 @@ struct flash_producer::implementation
                        {\r
                                CASPAR_LOG(debug) << "Retrying. Count: " << retries;\r
                                if(retries > 3)\r
-                                       BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(common::narrow(param)));\r
+                                       BOOST_THROW_EXCEPTION(operation_failed() << arg_name_info("param") << arg_value_info(narrow(param)));\r
                        }\r
                        is_empty_ = false;      \r
                });\r
@@ -182,7 +182,7 @@ struct flash_producer::implementation
                                stop();\r
 \r
                                frame_buffer_.clear();\r
-                               frame_buffer_.try_push(draw_frame::eof()); // EOF\r
+                               frame_buffer_.try_push(draw_frame::eof().get_shared()); // EOF\r
                \r
                                current_frame_ = nullptr;\r
                        });\r
@@ -225,19 +225,18 @@ struct flash_producer::implementation
                        auto format_desc = frame_processor_->get_video_format_desc();\r
                        bool is_progressive = format_desc.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc.fps/2 == 0);\r
 \r
-                       draw_frame result;\r
-\r
-                       if(is_progressive)                                                      \r
-                               result = do_receive();          \r
+                       std::shared_ptr<draw_frame> frame;\r
+                       if(is_progressive)\r
+                               frame = do_receive().get_shared();\r
                        else\r
-                               result = composite_frame::interlace(do_receive(), do_receive(), format_desc.mode);\r
+                               frame = composite_frame::interlace(do_receive(), do_receive(), format_desc.mode).get_shared();\r
                        \r
-                       frame_buffer_.push(result);\r
+                       frame_buffer_.push(frame);\r
                        is_empty_ = flashax_container_->IsEmpty();\r
                }\r
        }\r
                \r
-       draw_frame do_receive()\r
+       safe_ptr<draw_frame> do_receive()\r
        {\r
                auto format_desc = frame_processor_->get_video_format_desc();\r
 \r
@@ -251,13 +250,13 @@ struct flash_producer::implementation
                }       \r
 \r
                auto frame = frame_processor_->create_frame(format_desc.width, format_desc.height);\r
-               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame.pixel_data().begin());\r
-               return std::move(frame);\r
+               std::copy(current_frame_->data(), current_frame_->data() + current_frame_->size(), frame->pixel_data().begin());\r
+               return frame;\r
        }\r
                \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {               \r
-               return (frame_buffer_.try_pop(last_frame_) || !is_empty_) ? last_frame_ : draw_frame::empty();\r
+               return ((frame_buffer_.try_pop(last_frame_) || !is_empty_) && last_frame_) ? safe_ptr<draw_frame>::from_shared(last_frame_) : draw_frame::empty();\r
        }\r
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
@@ -275,9 +274,9 @@ struct flash_producer::implementation
        \r
        CComObject<flash::FlashAxContainer>* flashax_container_;\r
                \r
-       tbb::concurrent_bounded_queue<draw_frame> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<draw_frame>> frame_buffer_;\r
 \r
-       draw_frame last_frame_;\r
+       std::shared_ptr<draw_frame> last_frame_;\r
 \r
        bitmap_ptr current_frame_;\r
        bitmap_ptr bmp_frame_;\r
@@ -286,14 +285,14 @@ struct flash_producer::implementation
        flash_producer* self_;\r
 \r
        tbb::atomic<bool> is_empty_;\r
-       common::executor executor_;\r
+       executor executor_;\r
        int invalid_count_;\r
 \r
        frame_processor_device_ptr frame_processor_;\r
 };\r
 \r
 flash_producer::flash_producer(const std::wstring& filename) : impl_(new implementation(this, filename)){}\r
-draw_frame flash_producer::receive(){return impl_->receive();}\r
+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 frame_processor_device_ptr& frame_processor) { impl_->initialize(frame_processor);}\r
 std::wstring flash_producer::print() const {return impl_->print();}\r
@@ -309,7 +308,7 @@ std::wstring flash_producer::find_template(const std::wstring& template_name)
        return L"";\r
 }\r
 \r
-flash_producer_ptr create_flash_producer(const std::vector<std::wstring>& params)\r
+safe_ptr<flash_producer> create_flash_producer(const std::vector<std::wstring>& params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L"swf");\r
        std::wstring filename = server::media_folder() + L"\\" + params[0];\r
@@ -320,9 +319,9 @@ flash_producer_ptr create_flash_producer(const std::vector<std::wstring>& params
                });\r
 \r
        if(ext == extensions.end())\r
-               return nullptr;\r
+               BOOST_THROW_EXCEPTION(file_not_found() << msg_info(narrow(filename)));\r
 \r
-       return std::make_shared<flash_producer>(filename + L"." + *ext);\r
+       return make_safe<flash_producer>(filename + L"." + *ext);\r
 }\r
 \r
 }}}
\ No newline at end of file
index e8ac49f151e247da117a8417d7ebf1db60f4408c..ff44621faf92a11d905e559a25a76a991714d1b1 100644 (file)
@@ -37,8 +37,9 @@ class flash_producer : public frame_producer
 public:\r
 \r
        flash_producer(const std::wstring& filename);\r
+       flash_producer(flash_producer&& other) : impl_(std::move(other.impl_)){}\r
 \r
-       virtual draw_frame receive();\r
+       virtual safe_ptr<draw_frame> receive();\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor);\r
        virtual std::wstring print() const;\r
 \r
@@ -54,8 +55,6 @@ private:
 \r
 };\r
 \r
-typedef std::tr1::shared_ptr<flash_producer> flash_producer_ptr;\r
-\r
-flash_producer_ptr create_flash_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<flash_producer> create_flash_producer(const std::vector<std::wstring>& params);\r
 \r
 }}}
\ No newline at end of file
diff --git a/core/producer/frame_producer.cpp b/core/producer/frame_producer.cpp
new file mode 100644 (file)
index 0000000..259e2d6
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
+#include "../stdafx.h"\r
+\r
+#include "frame_producer.h"\r
+\r
+namespace caspar { namespace core {\r
+       \r
+struct empty_frame_producer : public frame_producer\r
+{\r
+       virtual safe_ptr<draw_frame> receive(){return draw_frame::eof();}\r
+       virtual void initialize(const frame_processor_device_ptr&){}\r
+       virtual std::wstring print() const { return L"empty";}\r
+};\r
+\r
+safe_ptr<frame_producer> frame_producer::empty()\r
+{\r
+       static auto empty_producer = std::make_shared<empty_frame_producer>();\r
+       return safe_ptr<frame_producer>::from_shared(empty_producer);\r
+}\r
+\r
+inline std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
+{\r
+       out << producer.print().c_str();\r
+       return out;\r
+}\r
+\r
+}}
\ No newline at end of file
index b841b6088f04748c78b154275a6d4c6817ce6a03..b6aa43b493f290f071bc0f6fd4c16f03feab4fbe 100644 (file)
@@ -21,6 +21,7 @@
 \r
 #include "../processor/draw_frame.h"\r
 #include "../processor/frame_processor_device.h"\r
+#include "../../common/utility/safe_ptr.h"\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
@@ -42,7 +43,7 @@ public:
        ///\r
        /// \return     The frame. \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual draw_frame receive() = 0;\r
+       virtual safe_ptr<draw_frame> receive() = 0;\r
 \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual std::shared_ptr<frame_producer> :::get_following_producer() const\r
@@ -51,8 +52,8 @@ public:
        ///\r
        /// \return     The following producer, or nullptr if there is no following producer. \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual std::shared_ptr<frame_producer> get_following_producer() const { return nullptr; }\r
-\r
+       virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();}\r
+       \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual void :::set_leading_producer(const std::shared_ptr<frame_producer>& producer)\r
        ///\r
@@ -60,7 +61,7 @@ public:
        ///\r
        /// \param      producer        The leading producer.\r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual void set_leading_producer(const std::shared_ptr<frame_producer>& /*producer*/) {}\r
+       virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {}\r
        \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual void :::initialize(const frame_processor_device_ptr& frame_processor) = 0;\r
@@ -71,26 +72,11 @@ public:
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor) = 0;\r
 \r
-       virtual std::wstring print() const { return L"Unknown frame_producer.";}\r
+       static safe_ptr<frame_producer> empty();\r
 \r
-       static const std::shared_ptr<frame_producer>& empty()\r
-       {       \r
-               struct empty_frame_producer : public frame_producer\r
-               {\r
-                       virtual draw_frame receive(){return draw_frame::empty();}\r
-                       virtual std::shared_ptr<frame_producer> get_following_producer() const { return nullptr; }\r
-                       virtual void initialize(const frame_processor_device_ptr&){}\r
-               };\r
-               static std::shared_ptr<frame_producer> empty_producer = std::make_shared<empty_frame_producer>();\r
-               return empty_producer;\r
-       }\r
+       virtual std::wstring print() const = 0;\r
 };\r
-typedef std::shared_ptr<frame_producer> frame_producer_ptr;\r
 \r
-inline std::wostream& operator<<(std::wostream& out, const frame_producer& producer)\r
-{\r
-       out << producer.print().c_str();\r
-       return out;\r
-}\r
+inline std::wostream& operator<<(std::wostream& out, const frame_producer& producer);\r
 \r
-}}
\ No newline at end of file
+}}\r
index 7091578384adc843f321f59b73dc55e8116610d0..d8c225c190537937f8eee7ec0325f0b498aef153 100644 (file)
@@ -22,9 +22,9 @@
        \r
 namespace caspar { namespace core {\r
        \r
-std::vector<draw_frame> receive(std::map<int, layer>& layers)\r
+std::vector<safe_ptr<draw_frame>> receive(std::map<int, layer>& layers)\r
 {      \r
-       std::vector<draw_frame> frames(layers.size(), draw_frame::empty());\r
+       std::vector<safe_ptr<draw_frame>> frames(layers.size(), draw_frame::empty());\r
        tbb::parallel_for(tbb::blocked_range<size_t>(0, frames.size()), \r
        [&](const tbb::blocked_range<size_t>& r)\r
        {\r
@@ -52,7 +52,7 @@ struct frame_producer_device::implementation : boost::noncopyable
                executor_.begin_invoke([=]{tick();});\r
        }\r
 \r
-       void load(int render_layer, const frame_producer_ptr& producer, load_option::type option)\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option)\r
        {\r
                producer->initialize(frame_processor_);\r
                executor_.begin_invoke([=]\r
@@ -86,12 +86,10 @@ struct frame_producer_device::implementation : boost::noncopyable
                executor_.begin_invoke([=]\r
                {\r
                        auto it = layers_.find(render_layer);\r
-                       if(it != layers_.end())\r
-                       {\r
-                               it->second.stop();\r
-                               if(!it->second.background())\r
-                                       layers_.erase(it);\r
-                       }\r
+                       if(it != layers_.end())                 \r
+                               it->second.stop();      \r
+                       if(it->second.empty())\r
+                               layers_.erase(it);\r
                });\r
        }\r
 \r
@@ -116,24 +114,24 @@ struct frame_producer_device::implementation : boost::noncopyable
                });\r
        }               \r
 \r
-       boost::unique_future<frame_producer_ptr> foreground(int render_layer) const\r
+       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const\r
        {\r
-               return executor_.begin_invoke([=]() -> frame_producer_ptr\r
+               return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
                {                       \r
                        auto it = layers_.find(render_layer);\r
-                       return it != layers_.end() ? it->second.foreground() : nullptr;\r
+                       return it != layers_.end() ? it->second.foreground() : frame_producer::empty();\r
                });\r
        }\r
        \r
-       boost::unique_future<frame_producer_ptr> background(int render_layer) const\r
+       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const\r
        {\r
-               return executor_.begin_invoke([=]() -> frame_producer_ptr\r
+               return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
                {\r
                        auto it = layers_.find(render_layer);\r
-                       return it != layers_.end() ? it->second.background() : nullptr;\r
+                       return it != layers_.end() ? it->second.background() : frame_producer::empty();\r
                });\r
        }\r
-       mutable common::executor executor_;\r
+       mutable executor executor_;\r
                                \r
        frame_processor_device_ptr frame_processor_;\r
                                                \r
@@ -141,12 +139,12 @@ struct frame_producer_device::implementation : boost::noncopyable
 };\r
 \r
 frame_producer_device::frame_producer_device(const frame_processor_device_ptr& frame_processor) : impl_(new implementation(frame_processor)){}\r
-void frame_producer_device::load(int render_layer, const frame_producer_ptr& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
+void frame_producer_device::load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
 void frame_producer_device::pause(int render_layer){impl_->pause(render_layer);}\r
 void frame_producer_device::play(int render_layer){impl_->play(render_layer);}\r
 void frame_producer_device::stop(int render_layer){impl_->stop(render_layer);}\r
 void frame_producer_device::clear(int render_layer){impl_->clear(render_layer);}\r
 void frame_producer_device::clear(){impl_->clear();}\r
-boost::unique_future<frame_producer_ptr> frame_producer_device::foreground(int render_layer) const {return impl_->foreground(render_layer);}\r
-boost::unique_future<frame_producer_ptr> frame_producer_device::background(int render_layer) const {return impl_->background(render_layer);}\r
+boost::unique_future<safe_ptr<frame_producer>> frame_producer_device::foreground(int render_layer) const {return impl_->foreground(render_layer);}\r
+boost::unique_future<safe_ptr<frame_producer>> frame_producer_device::background(int render_layer) const {return impl_->background(render_layer);}\r
 }}\r
index 56777ff40e433e58c38c1a649e114349604c1967..7017187e45e184e5f3186fdf4b0f98315d2b6693 100644 (file)
@@ -17,15 +17,15 @@ class frame_producer_device : boost::noncopyable
 public:\r
        frame_producer_device(const frame_processor_device_ptr& frame_processor);\r
        \r
-       void load       (int render_layer, const frame_producer_ptr& producer, load_option::type option = load_option::none);   \r
+       void load       (int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);     \r
        void pause      (int render_layer);\r
        void play       (int render_layer);\r
        void stop       (int render_layer);\r
        void clear      (int render_layer);\r
        void clear      ();\r
        \r
-       boost::unique_future<frame_producer_ptr> foreground(int render_layer) const;\r
-       boost::unique_future<frame_producer_ptr> background(int render_layer) const;\r
+       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const;\r
+       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const;\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index 1c6bdd89f233cb7519a2b5d991518038cbb8d761..ffa5c6b90294f591bd0d1a0f0be203e10bce162e 100644 (file)
@@ -51,7 +51,7 @@ std::shared_ptr<FIBITMAP> load_image(const std::string& filename)
 \r
 std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename)\r
 {\r
-       return load_image(common::narrow(filename));\r
+       return load_image(narrow(filename));\r
 }\r
 \r
 }}}
\ No newline at end of file
index 869246cc1da411c3932760e1faa60a5d53bb6709..a23d06f589c4a054d07895e986f6240bace83407 100644 (file)
@@ -18,9 +18,10 @@ namespace caspar { namespace core { namespace image{
 \r
 struct image_producer : public frame_producer\r
 {\r
-       image_producer(const std::wstring& filename) : filename_(filename)      {}\r
+       image_producer(image_producer&& other) : frame_processor_(std::move(other.frame_processor_)), filename_(std::move(other.filename_)), frame_(draw_frame::empty()){}\r
+       image_producer(const std::wstring& filename) : filename_(filename), frame_(draw_frame::empty()) {}\r
        \r
-       draw_frame receive(){return frame_;}\r
+       safe_ptr<draw_frame> receive(){return frame_;}\r
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
@@ -28,7 +29,7 @@ struct image_producer : public frame_producer
                auto bitmap = load_image(filename_);\r
                FreeImage_FlipVertical(bitmap.get());\r
                auto frame = frame_processor->create_frame(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()));\r
-               std::copy_n(FreeImage_GetBits(bitmap.get()), frame.pixel_data().size(), frame.pixel_data().begin());\r
+               std::copy_n(FreeImage_GetBits(bitmap.get()), frame->pixel_data().size(), frame->pixel_data().begin());\r
                frame_ = std::move(frame);\r
        }\r
 \r
@@ -39,10 +40,10 @@ struct image_producer : public frame_producer
        \r
        frame_processor_device_ptr frame_processor_;\r
        std::wstring filename_;\r
-       draw_frame frame_;\r
+       safe_ptr<draw_frame> frame_;\r
 };\r
 \r
-frame_producer_ptr create_image_producer(const  std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_image_producer(const  std::vector<std::wstring>& params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg");\r
        std::wstring filename = server::media_folder() + L"\\" + params[0];\r
@@ -53,9 +54,9 @@ frame_producer_ptr create_image_producer(const  std::vector<std::wstring>& param
                });\r
 \r
        if(ext == extensions.end())\r
-               return nullptr;\r
+               return frame_producer::empty();\r
 \r
-       return std::make_shared<image_producer>(filename + L"." + *ext);\r
+       return make_safe<image_producer>(filename + L"." + *ext);\r
 }\r
 \r
 }}}
\ No newline at end of file
index 88a913ccbd009e0ffe96565b779ce2b94e7330cd..c173baaa56e3632ad4f232618403752f6beb3561 100644 (file)
@@ -7,6 +7,6 @@
 \r
 namespace caspar { namespace core { namespace image {\r
 \r
-frame_producer_ptr create_image_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_image_producer(const std::vector<std::wstring>& params);\r
 \r
 }}}
\ No newline at end of file
index a6a71c8084c67f77ae15d74f943cb8bcfcac3ba7..5645f4e0ffbfc0cd1f2bf7bb49d0db96aa436e1c 100644 (file)
@@ -41,7 +41,7 @@
 //                     if(pos != std::wstring::npos)\r
 //                     {\r
 //                             speedStr = speedStr.substr(0, pos);             \r
-//                             speed_ = common::lexical_cast_or_default<int>(speedStr, image_scroll_producer::DEFAULT_SCROLL_SPEED);\r
+//                             speed_ = lexical_cast_or_default<int>(speedStr, image_scroll_producer::DEFAULT_SCROLL_SPEED);\r
 //                     }\r
 //             }\r
 //\r
 //             return std::move(frame);\r
 //     }\r
 //             \r
-//     draw_frame receive()\r
+//     safe_ptr<draw_frame> receive()\r
 //     {               \r
 //             if(format_desc_.mode != video_mode::progressive)                                \r
 //             {\r
 //     frame_processor_device_ptr frame_processor_;\r
 //};\r
 //\r
-//frame_producer_ptr create_image_scroll_producer(const std::vector<std::wstring>& params)\r
+//safe_ptr<frame_producer> create_image_scroll_producer(const std::vector<std::wstring>& params)\r
 //{\r
 //     static const std::vector<std::wstring> extensions = list_of(L"spng")(L"stga")(L"sbmp")(L"sjpg")(L"sjpeg");\r
 //     std::wstring filename = server::media_folder() + L"\\" + params[0];\r
index 72da2d5a0a16eb434c036ec57ef3011a4f4fb8a5..108543c649956b3e772368f7144439b604060836 100644 (file)
@@ -7,6 +7,6 @@
 \r
 namespace caspar { namespace core { namespace image {\r
        \r
-frame_producer_ptr create_image_scroll_producer(const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_image_scroll_producer(const std::vector<std::wstring>& params);\r
 \r
 }}}
\ No newline at end of file
index 614442a0668d45d4ac24eeeaa8642379b0cb1682..72952d7232a9f84bf61eadb1f3ac7840e228575e 100644 (file)
@@ -11,14 +11,14 @@ namespace caspar { namespace core {
 \r
 struct layer::implementation\r
 {              \r
-       implementation() : foreground_(nullptr), background_(nullptr), last_frame_(draw_frame::empty()) {}\r
+       implementation() : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()) {}\r
        \r
-       void load(const frame_producer_ptr& frame_producer, load_option::type option)\r
+       void load(const safe_ptr<frame_producer>& frame_producer, load_option::type option)\r
        {                       \r
                background_ = frame_producer;\r
                if(option == load_option::preview)              \r
                {\r
-                       foreground_ = nullptr;  \r
+                       foreground_ = frame_producer::empty();  \r
                        last_frame_ = frame_producer->receive();\r
                }\r
                else if(option == load_option::auto_play)\r
@@ -27,13 +27,11 @@ struct layer::implementation
        \r
        void play()\r
        {                       \r
-               if(background_ != nullptr)\r
-               {\r
-                       background_->set_leading_producer(foreground_);\r
-                       foreground_ = std::move(background_);\r
-               }\r
-\r
+               background_->set_leading_producer(foreground_);\r
+               foreground_ = background_;\r
+               background_ = frame_producer::empty();\r
                is_paused_ = false;\r
+               CASPAR_LOG(info) << L"Started: " << foreground_->print();\r
        }\r
 \r
        void pause()\r
@@ -43,20 +41,20 @@ struct layer::implementation
 \r
        void stop()\r
        {\r
-               foreground_ = nullptr;\r
+               foreground_ = frame_producer::empty();\r
                last_frame_ = draw_frame::empty();\r
        }\r
 \r
        void clear()\r
        {\r
-               foreground_ = nullptr;\r
-               background_ = nullptr;\r
+               foreground_ = frame_producer::empty();\r
+               background_ = frame_producer::empty();\r
                last_frame_ = draw_frame::empty();\r
        }\r
        \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {               \r
-               if(!foreground_ || is_paused_)\r
+               if(foreground_ == frame_producer::empty() || is_paused_)\r
                        return last_frame_;\r
 \r
                try\r
@@ -65,10 +63,9 @@ struct layer::implementation
 \r
                        if(last_frame_ == draw_frame::eof())\r
                        {\r
-                               CASPAR_LOG(info) << L"EOF: " << foreground_->print();\r
+                               CASPAR_LOG(info) << L"Ended: " << foreground_->print();\r
                                auto following = foreground_->get_following_producer();\r
-                               if(following)\r
-                                       following->set_leading_producer(foreground_);\r
+                               following->set_leading_producer(foreground_);\r
                                foreground_ = following;\r
                                last_frame_ = receive();\r
                        }\r
@@ -78,8 +75,8 @@ struct layer::implementation
                        try\r
                        {\r
                                CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               CASPAR_LOG(warning) << L"Removed " << (foreground_ ? foreground_->print() : L"empty") << L" from layer.";\r
-                               foreground_ = nullptr;\r
+                               CASPAR_LOG(warning) << L"Removed " << foreground_->print() << L" from layer.";\r
+                               foreground_ = frame_producer::empty();\r
                                last_frame_ = draw_frame::empty();\r
                        }\r
                        catch(...){}\r
@@ -88,10 +85,10 @@ struct layer::implementation
                return last_frame_;\r
        }       \r
                \r
-       tbb::atomic<bool>       is_paused_;\r
-       draw_frame              last_frame_;\r
-       frame_producer_ptr      foreground_;\r
-       frame_producer_ptr      background_;\r
+       tbb::atomic<bool>                       is_paused_;\r
+       safe_ptr<draw_frame>            last_frame_;\r
+       safe_ptr<frame_producer>        foreground_;\r
+       safe_ptr<frame_producer>        background_;\r
 };\r
 \r
 layer::layer() : impl_(new implementation()){}\r
@@ -102,12 +99,13 @@ layer& layer::operator=(layer&& other)
        other.impl_ = nullptr;\r
        return *this;\r
 }\r
-void layer::load(const frame_producer_ptr& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}      \r
+void layer::load(const safe_ptr<frame_producer>& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}        \r
 void layer::play(){impl_->play();}\r
 void layer::pause(){impl_->pause();}\r
 void layer::stop(){impl_->stop();}\r
 void layer::clear(){impl_->clear();}\r
-draw_frame layer::receive() {return impl_->receive();}\r
-frame_producer_ptr layer::foreground() const { return impl_->foreground_;}\r
-frame_producer_ptr layer::background() const { return impl_->background_;}\r
+bool layer::empty() const { return impl_->foreground_ == frame_producer::empty() && impl_->background_ == frame_producer::empty();}\r
+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
 }}
\ No newline at end of file
index f709629f92ac296edd96c0038a9e3d6bf7f3063f..16e20822ce8d5d8911a5566c72a908bafc6537f6 100644 (file)
@@ -23,16 +23,18 @@ public:
        layer(layer&& other);\r
        layer& operator=(layer&& other);\r
 \r
-       void load(const frame_producer_ptr& producer, load_option::type option = load_option::none);    \r
+       void load(const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);      \r
        void play();\r
        void pause();\r
        void stop();\r
        void clear();\r
+\r
+       bool empty() const;\r
                \r
-       frame_producer_ptr foreground() const;\r
-       frame_producer_ptr background() const;\r
+       safe_ptr<frame_producer> foreground() const;\r
+       safe_ptr<frame_producer> background() const;\r
 \r
-       draw_frame receive();\r
+       safe_ptr<draw_frame> receive();\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index ec3e5bfa12f5609ab638f3ab03e1f9a3912f76fb..90c66e757f1f4f0b34a154c9f32c033b6339b981 100644 (file)
@@ -35,34 +35,29 @@ namespace caspar { namespace core {
 \r
 struct transition_producer::implementation : boost::noncopyable\r
 {\r
-       implementation(const frame_producer_ptr& dest, const transition_info& info) : current_frame_(0), info_(info), dest_producer_(dest), org_dest_producer_(dest)\r
-       {\r
-               if(!dest)\r
-                       BOOST_THROW_EXCEPTION(null_argument() << arg_name_info("dest"));\r
-       }\r
+       implementation(const safe_ptr<frame_producer>& dest, const transition_info& info) : current_frame_(0), info_(info), \r
+               dest_producer_(dest), org_dest_producer_(dest), org_source_producer_(frame_producer::empty()), source_producer_(frame_producer::empty())\r
+       {}\r
                \r
-       frame_producer_ptr get_following_producer() const\r
+       safe_ptr<frame_producer> get_following_producer() const\r
        {\r
                return dest_producer_;\r
        }\r
        \r
-       void set_leading_producer(const frame_producer_ptr& producer)\r
+       void set_leading_producer(const safe_ptr<frame_producer>& producer)\r
        {\r
                org_source_producer_ = source_producer_ = producer;\r
        }\r
                \r
-       draw_frame receive()\r
+       safe_ptr<draw_frame> receive()\r
        {\r
-               if(current_frame_ == 0)\r
-                       CASPAR_LOG(info) << "Transition started.";\r
-\r
-               draw_frame result = [&]() -> draw_frame\r
+               safe_ptr<draw_frame> result = [&]() -> safe_ptr<draw_frame>\r
                {\r
                        if(current_frame_++ >= info_.duration)\r
                                return draw_frame::eof();\r
 \r
-                       draw_frame source;\r
-                       draw_frame dest;\r
+                       safe_ptr<draw_frame> source(draw_frame::empty());\r
+                       safe_ptr<draw_frame> dest(draw_frame::empty());\r
 \r
                        tbb::parallel_invoke\r
                        (\r
@@ -73,18 +68,15 @@ struct transition_producer::implementation : boost::noncopyable
                        return compose(dest, source);\r
                }();\r
 \r
-               if(result == draw_frame::eof())\r
-                       CASPAR_LOG(info) << "Transition ended.";\r
-\r
                return result;\r
        }\r
 \r
-       draw_frame receive(frame_producer_ptr& producer)\r
+       safe_ptr<draw_frame> receive(safe_ptr<frame_producer>& producer)\r
        {\r
-               if(!producer)\r
+               if(producer == frame_producer::empty())\r
                        return draw_frame::eof();\r
 \r
-               draw_frame frame = draw_frame::eof();\r
+               auto frame = draw_frame::eof();\r
                try\r
                {\r
                        frame = producer->receive();\r
@@ -92,15 +84,12 @@ struct transition_producer::implementation : boost::noncopyable
                catch(...)\r
                {\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
-                       producer = nullptr;\r
-                       CASPAR_LOG(warning) << "Removed producer from transition.";\r
+                       producer = frame_producer::empty();\r
+                       CASPAR_LOG(warning) << "Failed to receive frame. Removed producer from transition.";\r
                }\r
 \r
                if(frame == draw_frame::eof())\r
                {\r
-                       if(!producer || !producer->get_following_producer())\r
-                               return draw_frame::eof();\r
-\r
                        try\r
                        {\r
                                auto following = producer->get_following_producer();\r
@@ -110,8 +99,9 @@ struct transition_producer::implementation : boost::noncopyable
                        }\r
                        catch(...)\r
                        {\r
-                               CASPAR_LOG(warning) << "Failed to initialize following producer. Removing it.";\r
-                               producer = nullptr;\r
+                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                               producer = frame_producer::empty();\r
+                               CASPAR_LOG(warning) << "Failed to initialize following producer. Removed producer from transition.";\r
                        }\r
 \r
                        return receive(producer);\r
@@ -119,7 +109,7 @@ struct transition_producer::implementation : boost::noncopyable
                return frame;\r
        }\r
                                        \r
-       draw_frame compose(draw_frame dest_frame, draw_frame src_frame) \r
+       safe_ptr<draw_frame> compose(safe_ptr<draw_frame> dest_frame, safe_ptr<draw_frame> src_frame) \r
        {       \r
                if(dest_frame == draw_frame::eof() && src_frame == draw_frame::eof())\r
                        return draw_frame::eof();\r
@@ -164,14 +154,14 @@ struct transition_producer::implementation : boost::noncopyable
 \r
        std::wstring print() const\r
        {\r
-               return L"transition_producer. dest: " + (org_dest_producer_ ? org_dest_producer_->print() : L"empty") + L" src: " + (org_source_producer_ ? org_source_producer_->print() : L"empty");\r
+               return L"transition_producer. dest: " + (org_dest_producer_->print()) + L" src: " + (org_source_producer_->print());\r
        }\r
        \r
-       frame_producer_ptr                      org_source_producer_;\r
-       frame_producer_ptr                      org_dest_producer_;\r
+       safe_ptr<frame_producer>        org_source_producer_;\r
+       safe_ptr<frame_producer>        org_dest_producer_;\r
 \r
-       frame_producer_ptr                      source_producer_;\r
-       frame_producer_ptr                      dest_producer_;\r
+       safe_ptr<frame_producer>        source_producer_;\r
+       safe_ptr<frame_producer>        dest_producer_;\r
        \r
        unsigned short                          current_frame_;\r
        \r
@@ -179,10 +169,10 @@ struct transition_producer::implementation : boost::noncopyable
        frame_processor_device_ptr      frame_processor_;\r
 };\r
 \r
-transition_producer::transition_producer(const frame_producer_ptr& dest, const transition_info& info) : impl_(new implementation(dest, info)){}\r
-draw_frame transition_producer::receive(){return impl_->receive();}\r
-frame_producer_ptr transition_producer::get_following_producer() const{return impl_->get_following_producer();}\r
-void transition_producer::set_leading_producer(const frame_producer_ptr& producer) { impl_->set_leading_producer(producer); }\r
+transition_producer::transition_producer(const safe_ptr<frame_producer>& dest, const transition_info& info) : impl_(new implementation(dest, info)){}\r
+safe_ptr<draw_frame> transition_producer::receive(){return impl_->receive();}\r
+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 frame_processor_device_ptr& frame_processor) { impl_->initialize(frame_processor);}\r
 std::wstring transition_producer::print() const { return impl_->print();}\r
 \r
index 191623ef98f3a4058a9f149ebd017631abf3f97c..3d53284fe3d968ba211be0914ff21e52b7cf5076 100644 (file)
@@ -60,18 +60,17 @@ struct transition_info
 class transition_producer : public frame_producer\r
 {\r
 public:\r
-       transition_producer(const frame_producer_ptr& destination, const transition_info& info);\r
+       transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
+       transition_producer(transition_producer&& other) : impl_(std::move(other.impl_)){}\r
+       safe_ptr<draw_frame> receive();\r
 \r
-       draw_frame receive();\r
-\r
-       frame_producer_ptr get_following_producer() const;\r
-       void set_leading_producer(const frame_producer_ptr& producer);\r
+       safe_ptr<frame_producer> get_following_producer() const;\r
+       void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor);\r
        virtual std::wstring print() const;\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<transition_producer> transition_producer_ptr;\r
 \r
 }}
\ No newline at end of file
index e4ca1b9ca174f90501f86a66897f572d78f7b8a8..044580497c94bdb37120cfa180bc7434cd818656 100644 (file)
@@ -23,9 +23,7 @@
 #include "AMCPCommandQueue.h"\r
 \r
 namespace caspar { namespace core { namespace amcp {\r
-\r
-using namespace common;\r
-\r
+       \r
 AMCPCommandQueue::AMCPCommandQueue() : newCommandEvent_(FALSE, FALSE) \r
 {}\r
 \r
index d83d3c44270709a01e815e2b7655320e362a27b7..5a4c38719c4e18d5deadff5c91bfa46a1d1c6490 100644 (file)
@@ -27,7 +27,7 @@
 \r
 namespace caspar { namespace core { namespace amcp {\r
 \r
-class AMCPCommandQueue : public common::IRunnable\r
+class AMCPCommandQueue : public IRunnable\r
 {\r
        AMCPCommandQueue(const AMCPCommandQueue&);\r
        AMCPCommandQueue& operator=(const AMCPCommandQueue&);\r
@@ -40,11 +40,11 @@ public:
        void AddCommand(AMCPCommandPtr pCommand);\r
 \r
 private:\r
-       common::Thread                          commandPump_;\r
+       Thread                          commandPump_;\r
        virtual void Run(HANDLE stopEvent);\r
        virtual bool OnUnhandledException(const std::exception& ex) throw();\r
 \r
-       common::Event newCommandEvent_;\r
+       Event newCommandEvent_;\r
 \r
        //Needs synro-protection\r
        std::list<AMCPCommandPtr>       commands_;\r
index ebefa9bafb813a1110d4a864351f25cebff6e99b..eb55d948a87ada18f802154ca6a6f41e1ec12250 100644 (file)
@@ -141,9 +141,7 @@ std::wstring ListTemplates()
 }\r
 \r
 namespace amcp {\r
-\r
-using namespace common;\r
-\r
+       \r
 AMCPCommand::AMCPCommand() : channelIndex_(0), scheduling_(Default), layerIndex_(-1)\r
 {}\r
 \r
@@ -246,10 +244,10 @@ bool LoadbgCommand::DoExecute()
        try\r
        {\r
                auto pFP = load_media(_parameters);\r
-               if(pFP == nullptr)\r
-                       BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? common::narrow(_parameters[0]) : ""));\r
+               if(pFP == frame_producer::empty())\r
+                       BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? narrow(_parameters[0]) : ""));\r
 \r
-               pFP = std::make_shared<transition_producer>(pFP, transitionInfo);\r
+               pFP = safe_ptr<frame_producer>(transition_producer(pFP, transitionInfo));\r
                bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();\r
                GetChannel()->load(GetLayerIndex(), pFP, autoPlay ? load_option::auto_play : load_option::none); // TODO: LOOP\r
        \r
@@ -729,7 +727,7 @@ bool CinfCommand::DoExecute()
 \r
 void GenerateChannelInfo(int index, const channel_ptr& pChannel, std::wstringstream& replyString)\r
 {\r
-       replyString << index << TEXT(" ") << pChannel->get_video_format_desc().name  << TEXT("\r\n") << (pChannel->foreground(0).get() != nullptr ? TEXT(" PLAYING") : TEXT(" STOPPED"));\r
+       replyString << index << TEXT(" ") << pChannel->get_video_format_desc().name  << TEXT("\r\n") << (pChannel->foreground(0).get()->print());\r
 }\r
 \r
 bool InfoCommand::DoExecute()\r
index 3fb1ee4d1b3628864948e6c8d88167af88711fd9..f79fbe2727c01d2f6988e35fa6d9e02a382c798c 100644 (file)
@@ -42,7 +42,6 @@
 \r
 namespace caspar { namespace core { namespace amcp {\r
 \r
-using namespace common;\r
 using IO::ClientInfoPtr;\r
 \r
 const std::wstring AMCPProtocolStrategy::MessageDelimiter = TEXT("\r\n");\r
index 9236a7b0e2af2f9fde8081684576940bae28fada..300033589ee0860a2a91505fc3c94ebf80d6b3db 100644 (file)
@@ -36,9 +36,7 @@
 #endif\r
 \r
 namespace caspar { namespace core { namespace cii {\r
-\r
-using namespace common;\r
-\r
+       \r
 const std::wstring CIIProtocolStrategy::MessageDelimiter = TEXT("\r\n");\r
 const TCHAR CIIProtocolStrategy::TokenDelimiter = TEXT('\\');\r
 \r
@@ -188,19 +186,15 @@ void CIIProtocolStrategy::WriteTemplateData(const std::wstring& templateName, co
        std::vector<std::wstring> params;\r
        params.push_back(server::template_folder()+TEXT("CG.fth"));\r
        auto pFP = flash::create_flash_producer(params);\r
-       if(pFP != 0)\r
-       {\r
-               //TODO: Initialize with valid FrameFactory\r
-//             pFP->Initialize(0, false);\r
 \r
-               std::wstringstream flashParam;\r
-               flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
-               pFP->param(flashParam.str());\r
+       std::wstringstream flashParam;\r
+       flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
+       pFP->param(flashParam.str());\r
 \r
-               CASPAR_LOG(info) << "Saved an instance of " << templateName << TEXT(" as ") << titleName ;\r
+       CASPAR_LOG(info) << "Saved an instance of " << templateName << TEXT(" as ") << titleName ;\r
 \r
-               PutPreparedTemplate(titleName, std::static_pointer_cast<frame_producer>(pFP));\r
-       }\r
+       PutPreparedTemplate(titleName, safe_ptr<frame_producer>(std::move(*pFP)));\r
+       \r
 }\r
 \r
 void CIIProtocolStrategy::DisplayTemplate(const std::wstring& titleName)\r
@@ -225,7 +219,7 @@ void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename)
        transition.duration = 12;\r
 \r
        auto pFP = load_media(boost::assign::list_of(filename));\r
-       auto pTransition = std::make_shared<transition_producer>(pFP, transition);\r
+       auto pTransition = safe_ptr<frame_producer>(transition_producer(pFP, transition));\r
 \r
        try\r
        {\r
@@ -243,9 +237,9 @@ void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename)
        CASPAR_LOG(info) << L"Displayed " << filename;\r
 }\r
 \r
-frame_producer_ptr CIIProtocolStrategy::GetPreparedTemplate(const std::wstring& titleName)\r
+safe_ptr<frame_producer> CIIProtocolStrategy::GetPreparedTemplate(const std::wstring& titleName)\r
 {\r
-       frame_producer_ptr result;\r
+       safe_ptr<frame_producer> result(frame_producer::empty());\r
 \r
        TitleList::iterator it = std::find(titles_.begin(), titles_.end(), titleName);\r
        if(it != titles_.end()) {\r
@@ -258,7 +252,7 @@ frame_producer_ptr CIIProtocolStrategy::GetPreparedTemplate(const std::wstring&
        return result;\r
 }\r
 \r
-void CIIProtocolStrategy::PutPreparedTemplate(const std::wstring& titleName, frame_producer_ptr& pFP)\r
+void CIIProtocolStrategy::PutPreparedTemplate(const std::wstring& titleName, safe_ptr<frame_producer>& pFP)\r
 {\r
        CASPAR_LOG(debug) << L"Saved title with name " << titleName;\r
 \r
index 8c5de41dba7ae3667e4d2e294108ee935dc5a17b..c577c95470b29970bb0f7515fa40b29b69a61842 100644 (file)
@@ -51,8 +51,8 @@ public:
 public:\r
        struct TitleHolder\r
        {\r
-               TitleHolder() : titleName(TEXT(""))     {}\r
-               TitleHolder(const std::wstring& name, frame_producer_ptr pFP) : titleName(name), pframe_producer(pFP) {}\r
+               TitleHolder() : titleName(TEXT("")), pframe_producer(frame_producer::empty())   {}\r
+               TitleHolder(const std::wstring& name, safe_ptr<frame_producer> pFP) : titleName(name), pframe_producer(pFP) {}\r
                TitleHolder(const TitleHolder& th) : titleName(th.titleName), pframe_producer(th.pframe_producer) {}\r
                const TitleHolder& operator=(const TitleHolder& th) \r
                {\r
@@ -65,15 +65,15 @@ public:
                }\r
 \r
                std::wstring titleName;\r
-               frame_producer_ptr pframe_producer;\r
+               safe_ptr<frame_producer> pframe_producer;\r
                friend CIIProtocolStrategy;\r
        };\r
 private:\r
 \r
        typedef std::list<TitleHolder> TitleList;\r
        TitleList titles_;\r
-       frame_producer_ptr GetPreparedTemplate(const std::wstring& name);\r
-       void PutPreparedTemplate(const std::wstring& name, frame_producer_ptr& pframe_producer);\r
+       safe_ptr<frame_producer> GetPreparedTemplate(const std::wstring& name);\r
+       void PutPreparedTemplate(const std::wstring& name, safe_ptr<frame_producer>& pframe_producer);\r
 \r
        static const TCHAR TokenDelimiter;\r
        static const std::wstring MessageDelimiter;\r
@@ -82,7 +82,7 @@ private:
        int TokenizeMessage(const std::wstring& message, std::vector<std::wstring>* pTokenVector);\r
        CIICommandPtr Create(const std::wstring& name);\r
 \r
-       common::executor executor_;\r
+       executor executor_;\r
        std::wstring currentMessage_;\r
 \r
        std::wstring currentProfile_;\r
index 4b56c8bcfe6257ac9c31b0a6580967e2fb9fc379..802c1151d9d1e4f7b6980e34cac4b0075e598ba4 100644 (file)
@@ -30,9 +30,7 @@
 #include <algorithm>\r
 \r
 namespace caspar { namespace core { namespace CLK {\r
-\r
-using namespace common;\r
-\r
+       \r
 CLKProtocolStrategy::CLKProtocolStrategy(const std::vector<channel_ptr>& channels) \r
        : currentState_(ExpectingNewCommand), bClockLoaded_(false) \r
 {      \r
index ca7b7258649724c8a429b0a08957ddc0e91b072a..1e2a21d60d079699ed00d810626677c1a67cdc35 100644 (file)
@@ -18,12 +18,11 @@ using namespace boost::assign;
 \r
 namespace caspar { namespace core { \r
        \r
-frame_producer_ptr load_media(const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> load_media(const std::vector<std::wstring>& params)\r
 {              \r
-       typedef std::function<frame_producer_ptr(const std::vector<std::wstring>&)> producer_factory;\r
+       typedef std::function<safe_ptr<frame_producer>(const std::vector<std::wstring>&)> producer_factory;\r
 \r
        const auto producer_factories = list_of<producer_factory>\r
-               (&flash::create_flash_producer)\r
                (&flash::create_ct_producer)\r
                (&image::create_image_producer)\r
        //      (&image::create_image_scroll_producer)\r
@@ -33,7 +32,7 @@ frame_producer_ptr load_media(const std::vector<std::wstring>& params)
        if(params.empty())\r
                BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));\r
 \r
-       frame_producer_ptr producer;\r
+       safe_ptr<frame_producer> producer(frame_producer::empty());\r
        std::any_of(producer_factories.begin(), producer_factories.end(), [&](const producer_factory& factory) -> bool\r
                {\r
                        try\r
@@ -44,7 +43,7 @@ frame_producer_ptr load_media(const std::vector<std::wstring>& params)
                        {\r
                                CASPAR_LOG_CURRENT_EXCEPTION();\r
                        }\r
-                       return producer != nullptr;\r
+                       return producer != frame_producer::empty();\r
                });\r
 \r
        return producer;\r
index bb7b06afef909d307a84bd100a114471277513c3..2de78c5f6327e3d956d39a90cf23847991447b40 100644 (file)
@@ -7,6 +7,6 @@
 \r
 namespace caspar { namespace core { \r
        \r
-frame_producer_ptr load_media(const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> load_media(const std::vector<std::wstring>& params);\r
 \r
 }}\r
index efa01df2e378a6c00be9a1fb409c02a27d48396f..1e2f17a23d1a86ef28230673b8dce427e1505df1 100644 (file)
@@ -63,10 +63,10 @@ struct server::implementation : boost::noncopyable
                boost::property_tree::read_xml(initialPath + "\\caspar.config", pt);\r
 \r
                auto paths = pt.get_child("configuration.paths");\r
-               media_folder_ = common::widen(paths.get("media-path", initialPath + "\\media\\"));\r
-               log_folder_ = common::widen(paths.get("log-path", initialPath + "\\log\\"));\r
-               template_folder_ = common::widen(paths.get("template-path", initialPath + "\\template\\"));\r
-               data_folder_ = common::widen(paths.get("data-path", initialPath + "\\data\\"));\r
+               media_folder_ = widen(paths.get("media-path", initialPath + "\\media\\"));\r
+               log_folder_ = widen(paths.get("log-path", initialPath + "\\log\\"));\r
+               template_folder_ = widen(paths.get("template-path", initialPath + "\\template\\"));\r
+               data_folder_ = widen(paths.get("data-path", initialPath + "\\data\\"));\r
        }\r
                        \r
        void setup_channels(boost::property_tree::ptree& pt)\r
@@ -74,7 +74,7 @@ struct server::implementation : boost::noncopyable
                using boost::property_tree::ptree;\r
                BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels"))\r
                {               \r
-                       auto format_desc = video_format_desc::get(common::widen(xml_channel.second.get("videomode", "PAL")));           \r
+                       auto format_desc = video_format_desc::get(widen(xml_channel.second.get("videomode", "PAL")));           \r
                        if(format_desc.format == video_format::invalid)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid videomode."));\r
                        std::vector<frame_consumer_ptr> consumers;\r
index ab649b47b2207b2b8aaa919993d9acf8fa7dc3a2..8c4f8871e15a37c250c0ba5f654c88f11f9d5cf5 100644 (file)
@@ -40,7 +40,6 @@
 \r
 using namespace caspar;\r
 using namespace caspar::core;\r
-using namespace caspar::common;\r
 \r
 class win32_handler_tbb_installer : public tbb::task_scheduler_observer\r
 {\r