]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 11 Jan 2011 14:24:38 +0000 (14:24 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 11 Jan 2011 14:24:38 +0000 (14:24 +0000)
51 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/config.h [deleted file]
common/exception/exceptions.h
common/gl/gl_check.h [moved from common/gl/utility.h with 100% similarity]
common/stdafx.h
common/utility/singleton_pool.h [deleted file]
core/channel.cpp
core/channel.h
core/configuration.cpp
core/consumer/bluefish/bluefish_consumer.cpp
core/consumer/bluefish/bluefish_consumer.h
core/consumer/bluefish/memory.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/frame_consumer_device.h
core/consumer/oal/oal_consumer.cpp
core/consumer/oal/oal_consumer.h
core/consumer/ogl/ogl_consumer.cpp
core/consumer/ogl/ogl_consumer.h
core/format/video_format.cpp
core/format/video_format.h
core/processor/audio_processor.cpp
core/processor/device_buffer.cpp
core/processor/draw_frame.cpp
core/processor/frame_processor_device.cpp
core/processor/host_buffer.cpp
core/processor/image_kernel.cpp
core/processor/image_processor.cpp
core/processor/ogl_device.h
core/processor/read_frame.cpp
core/processor/write_frame.cpp
core/producer/color/color_producer.cpp
core/producer/ffmpeg/audio/audio_decoder.cpp
core/producer/ffmpeg/audio/audio_decoder.h
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/input.cpp
core/producer/ffmpeg/input.h
core/producer/ffmpeg/video/video_decoder.cpp
core/producer/ffmpeg/video/video_decoder.h
core/producer/flash/cg_producer.cpp
core/producer/flash/cg_producer.h
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/image/image_producer.cpp
core/producer/layer.cpp
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
shell/caspar.config

index e538775d2d1b106363414073558ea03a17734582..79428d03863ccdd4e47e30df5c68bf50ef564dd0 100644 (file)
     <ClInclude Include="compiler\vs\disable_silly_warnings.h" />\r
     <ClInclude Include="concurrency\executor.h" />\r
     <ClInclude Include="concurrency\Thread.h" />\r
-    <ClInclude Include="config.h" />\r
     <ClInclude Include="exception\exceptions.h" />\r
     <ClInclude Include="exception\win32_exception.h" />\r
-    <ClInclude Include="gl\utility.h" />\r
+    <ClInclude Include="gl\gl_check.h" />\r
     <ClInclude Include="io\AsyncEventServer.h" />\r
     <ClInclude Include="io\ClientInfo.h" />\r
     <ClInclude Include="io\ProtocolStrategy.h" />\r
     <ClInclude Include="log\log.h" />\r
     <ClInclude Include="stdafx.h" />\r
     <ClInclude Include="utility\safe_ptr.h" />\r
-    <ClInclude Include="utility\singleton_pool.h" />\r
     <ClInclude Include="utility\string_convert.h" />\r
     <ClInclude Include="utility\timer.h" />\r
   </ItemGroup>\r
index 2dce8635bf64a58d5f22b6f8b40c2e6ebcf0022f..4ac54811836ad69578b9d9c822fb0a33785716f3 100644 (file)
@@ -34,9 +34,6 @@
     </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="log\log.cpp">\r
-      <Filter>Source\log</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="io\SocketInfo.cpp">\r
       <Filter>Source\io</Filter>\r
     </ClCompile>\r
     <ClCompile Include="stdafx.cpp">\r
       <Filter>Afx</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="log\log.cpp">\r
+      <Filter>Source\log</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="log\log.h">\r
-      <Filter>Source\log</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="io\AsyncEventServer.h">\r
       <Filter>Source\io</Filter>\r
     </ClInclude>\r
     <ClInclude Include="exception\win32_exception.h">\r
       <Filter>Source\exception</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="config.h">\r
-      <Filter>Source</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="gl\utility.h">\r
-      <Filter>Source\gl</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="compiler\vs\disable_silly_warnings.h">\r
       <Filter>Source\compiler\vs</Filter>\r
     </ClInclude>\r
     <ClInclude Include="concurrency\executor.h">\r
       <Filter>Source\concurrency</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="utility\string_convert.h">\r
+    <ClInclude Include="log\log.h">\r
+      <Filter>Source\log</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="utility\timer.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
     <ClInclude Include="utility\safe_ptr.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="utility\singleton_pool.h">\r
+    <ClInclude Include="utility\string_convert.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="utility\timer.h">\r
-      <Filter>Source\utility</Filter>\r
+    <ClInclude Include="gl\gl_check.h">\r
+      <Filter>Source\gl</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/common/config.h b/common/config.h
deleted file mode 100644 (file)
index 5473bcb..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once\r
-\r
-#define TBB_USE_THREADING_TOOLS 1\r
index 929f649089580edba6a27e35e61e2e8578a751c2..9d33450fe7e93a62d51872356aa1d4e93c70e349 100644 (file)
@@ -9,8 +9,6 @@ namespace caspar {
 \r
 typedef boost::error_info<struct tag_arg_name_info, std::string> arg_name_info;\r
 typedef boost::error_info<struct tag_arg_value_info, std::string> arg_value_info;\r
-typedef boost::error_info<struct tag_arg_name_info, std::wstring> warg_name_info;\r
-typedef boost::error_info<struct tag_arg_value_info, std::wstring> warg_value_info;\r
 typedef boost::error_info<struct tag_msg_info, std::string> msg_info;\r
 typedef boost::error_info<struct tag_inner_info, std::exception_ptr> inner_info;\r
 typedef boost::error_info<struct tag_line_info, int> line_info;\r
similarity index 100%
rename from common/gl/utility.h
rename to common/gl/gl_check.h
index c13b506463e6a7694cb3acec3dc21a97df707c24..593184a4831f8e27aa2fc336928dca2b50e02d3e 100644 (file)
@@ -30,7 +30,5 @@
 \r
 #include "compiler\vs\disable_silly_warnings.h"\r
 \r
-#include "config.h"\r
-\r
 #include <string>\r
 #include <cassert>\r
diff --git a/common/utility/singleton_pool.h b/common/utility/singleton_pool.h
deleted file mode 100644 (file)
index d9047e1..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#pragma once\r
-          \r
-#include <tbb/concurrent_queue.h>\r
-#include <tbb/scalable_allocator.h>\r
-\r
-namespace caspar {\r
-\r
-template <typename T>\r
-class singleton_pool\r
-{\r
-public:\r
-       \r
-       static T* allocate()\r
-       {\r
-               T* ptr;\r
-               if(!get_pool().try_pop(ptr))\r
-                       ptr = static_cast<T*>(scalable_malloc(sizeof(T)));\r
-               return ptr;\r
-       }\r
-       \r
-       static void deallocate(T* ptr)\r
-       {\r
-               if(!get_pool().try_push(ptr))\r
-                       scalable_free(ptr);\r
-       }\r
-\r
-       static void destroy(T* ptr)\r
-       {\r
-               ptr->~T();\r
-               deallocate(ptr);\r
-       }\r
-\r
-       static std::shared_ptr<T> make_shared()\r
-       {\r
-               return std::shared_ptr<T>(new(allocate()) T(), destroy);\r
-       }\r
-       \r
-       template<typename P0>\r
-       static std::shared_ptr<T> make_shared(P0 p0)\r
-       {\r
-               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0)), destroy);\r
-       }\r
-       \r
-       template<typename P0, typename P1>\r
-       static std::shared_ptr<T> make_shared(P0 p0, P1 p1)\r
-       {\r
-               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1)), destroy);\r
-       }\r
-       \r
-       template<typename P0, typename P1, typename P2>\r
-       static std::shared_ptr<T> make_shared(P0 p0, P1 p1, P2 p2)\r
-       {\r
-               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)), destroy);\r
-       }\r
-       \r
-       template<typename P0, typename P1, typename P2, typename P3>\r
-       static std::shared_ptr<T> make_shared(P0 p0, P1 p1, P2 p2, P3 p3)\r
-       {\r
-               return std::shared_ptr<T>(new(allocate()) T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)), destroy);\r
-       }\r
-\r
-private:\r
-       struct pool\r
-       {\r
-               ~pool()\r
-               {\r
-                       T* ptr;\r
-                       while(value.try_pop(ptr))\r
-                               scalable_free(ptr);\r
-               }\r
-               tbb::concurrent_bounded_queue<T*> value;\r
-       };\r
-\r
-       static tbb::concurrent_bounded_queue<T*>& get_pool()\r
-       {\r
-               static pool global_pool;\r
-               return global_pool.value;\r
-       }\r
-};\r
-\r
-}
\ No newline at end of file
index 3bf8ab81ffe5bd92390765b04d883c73e4778378..37199e3d7b42f2b0ab85943701e6fb2afaa395fc 100644 (file)
@@ -2,27 +2,40 @@
 \r
 #include "channel.h"\r
 \r
-#include "producer/layer.h"\r
-\r
 #include "consumer/frame_consumer_device.h"\r
 \r
 #include "processor/draw_frame.h"\r
 #include "processor/frame_processor_device.h"\r
 \r
+#include "producer/layer.h"\r
+\r
 #include <common/concurrency/executor.h>\r
 \r
 #include <boost/range/algorithm_ext/erase.hpp>\r
 \r
 #include <tbb/parallel_for.h>\r
 \r
+#include <map>\r
 #include <memory>\r
 \r
 namespace caspar { namespace core {\r
 \r
 struct channel::implementation : boost::noncopyable\r
 {      \r
+       mutable executor executor_;\r
+                               \r
+       safe_ptr<frame_processor_device> processor_device_;\r
+       frame_consumer_device consumer_device_;\r
+                                               \r
+       std::map<int, layer> layers_;           \r
+\r
+       const video_format_desc format_desc_;\r
+\r
+public:\r
        implementation(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers)  \r
-               : format_desc_(format_desc), processor_device_(frame_processor_device(format_desc)), consumer_device_(format_desc, consumers)\r
+               : format_desc_(format_desc)\r
+               , processor_device_(frame_processor_device(format_desc))\r
+               , consumer_device_(format_desc, consumers)\r
        {\r
                executor_.start();\r
                executor_.begin_invoke([=]{tick();});\r
@@ -144,16 +157,7 @@ struct channel::implementation : boost::noncopyable
                        auto it = layers_.find(index);\r
                        return it != layers_.end() ? it->second.background() : frame_producer::empty();\r
                });\r
-       }\r
-\r
-       mutable executor executor_;\r
-                               \r
-       safe_ptr<frame_processor_device> processor_device_;\r
-       frame_consumer_device consumer_device_;\r
-                                               \r
-       std::map<int, layer> layers_;           \r
-\r
-       const video_format_desc format_desc_;\r
+       };\r
 };\r
 \r
 channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
index a5ca2b1b0a59a5f2293bcd8d974fe6e12b66ad96..99a125755fea8a9f3152b1f7e38ed05517d4b3b5 100644 (file)
@@ -23,8 +23,8 @@ namespace caspar { namespace core {
 class channel : boost::noncopyable\r
 {\r
 public:\r
+       explicit channel(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
        channel(channel&& other);\r
-       channel(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
        \r
        void load(int index, const safe_ptr<frame_producer>& producer, bool autoplay = false);\r
        void preview(int index, const safe_ptr<frame_producer>& producer);\r
index 814a34f7a5b08f03a1e628a1de77b5898386e958..e712dcecb509795924e805ba9731e9437eff284e 100644 (file)
@@ -104,7 +104,7 @@ struct configuration::implementation : boost::noncopyable
                                                consumers.push_back(bluefish::consumer(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false)));                                   \r
                                #endif\r
                                        else if(name == "decklink")\r
-                                               consumers.push_back(make_safe<decklink::decklink_consumer>(format_desc, xml_consumer.second.get("internalkey", false)));\r
+                                               consumers.push_back(make_safe<decklink::decklink_consumer>(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("internalkey", false)));\r
                                        else if(name == "audio")\r
                                                consumers.push_back(oal::consumer(format_desc));                        \r
                                }\r
index df7f72470300380245bf88e814c4741d775a920e..73028cb71754c6303ebaa81fe96e405445698efc 100644 (file)
@@ -146,6 +146,7 @@ struct consumer::implementation : boost::noncopyable
                executor_.start();\r
 \r
                CASPAR_LOG(info) << TEXT("BLUECARD INFO: Successfully initialized device ") << device_index_;\r
+               active_ = executor_.begin_invoke([=]{});\r
        }\r
 \r
        ~implementation()\r
@@ -175,7 +176,8 @@ struct consumer::implementation : boost::noncopyable
                static size_t audio_samples = 1920;\r
                static size_t audio_nchannels = 2;\r
                static std::vector<short> silence(audio_samples*audio_nchannels*2, 0);\r
-\r
+               \r
+               active_.get();\r
                active_ = executor_.begin_invoke([=]\r
                {\r
                        try\r
@@ -225,12 +227,6 @@ struct consumer::implementation : boost::noncopyable
                });\r
        }\r
 \r
-       frame_consumer::sync_mode synchronize()\r
-       {\r
-               active_.get();\r
-               return frame_consumer::clock;\r
-       }\r
-\r
        size_t buffer_depth() const\r
        {\r
                return 1;\r
@@ -287,7 +283,6 @@ struct consumer::implementation : boost::noncopyable
 consumer::consumer(consumer&& other) : impl_(std::move(other.impl_)){}\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 safe_ptr<const 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
 \r
index bf0aa4655290ed26b952d9f931ace7ed50db84b7..21f5fdf30222f2ec7221388a796e84acaebd48a0 100644 (file)
@@ -27,11 +27,10 @@ namespace caspar { namespace core { namespace bluefish {
 class consumer : public frame_consumer\r
 {\r
 public:\r
+       explicit consumer(const video_format_desc& format_desc, unsigned int device_index, bool embed_audio = false);\r
        consumer(consumer&& other);\r
-       consumer(const video_format_desc& format_desc, unsigned int deviceIndex, bool embed_audio = false);\r
        \r
        virtual void send(const safe_ptr<const read_frame>&);\r
-       virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
        struct implementation;\r
index af39c7a3a9d56063fb9bff3e49a5cf2c5fc40f43..1d19dfe38275f9414b64a7acf4802781a76bd1ab 100644 (file)
@@ -6,6 +6,8 @@
 #include "../../format/video_format.h"\r
 #include "exception.h"\r
 \r
+#include <tbb/mutex.h>\r
+\r
 namespace caspar { namespace core { namespace bluefish {\r
        \r
 static const size_t MAX_HANC_BUFFER_SIZE = 256*1024;\r
@@ -14,16 +16,19 @@ static const size_t MAX_VBI_BUFFER_SIZE = 36*1920*4;
 struct page_locked_buffer\r
 {\r
 public:\r
-       page_locked_buffer(size_t size) : size_(size), data_(static_cast<unsigned char*>(::VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))\r
+       page_locked_buffer(size_t size) \r
+               : size_(size)\r
+               , data_(static_cast<unsigned char*>(::VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))\r
        {\r
                if(!data_)      \r
                        BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed to allocate memory for paged locked buffer."));  \r
                if(::VirtualLock(data_.get(), size_) == 0)      \r
                        BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed to lock memory for paged locked buffer."));\r
        }\r
-\r
+       \r
        static void reserve_working_size(size_t size)\r
        {\r
+               auto lock = get_lock();\r
                SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0;\r
                if(::GetProcessWorkingSetSize(::GetCurrentProcess(), &workingSetMinSize, &workingSetMaxSize))\r
                {\r
@@ -37,10 +42,32 @@ public:
                }\r
        }\r
 \r
+       static void unreserve_working_size(size_t size)\r
+       {\r
+               auto lock = get_lock();\r
+               SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0;\r
+               if(::GetProcessWorkingSetSize(::GetCurrentProcess(), &workingSetMinSize, &workingSetMaxSize))\r
+               {\r
+                       CASPAR_LOG(debug) << TEXT("WorkingSet size: min = ") << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize;\r
+                       \r
+                       workingSetMinSize += static_cast<SIZE_T>(static_cast<int>(workingSetMinSize) - static_cast<int>(size));\r
+                       workingSetMaxSize += static_cast<SIZE_T>(static_cast<int>(workingSetMaxSize) - static_cast<int>(size));\r
+\r
+                       if(!::SetProcessWorkingSetSize(::GetCurrentProcess(), workingSetMinSize, workingSetMaxSize))            \r
+                               BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed set workingset."));              \r
+               }\r
+       }\r
+\r
        PBYTE data() const { return data_.get(); }\r
        size_t size() const { return size_; }\r
 private:\r
 \r
+       static std::unique_ptr<tbb::mutex::scoped_lock> get_lock()\r
+       {\r
+               static tbb::mutex mutex;\r
+               return std::move(std::unique_ptr<tbb::mutex::scoped_lock>(new tbb::mutex::scoped_lock(mutex)));\r
+       }\r
+       \r
        struct virtual_free\r
        {\r
                void operator()(LPVOID lpAddress)\r
index cc5a2a552be3fc64e6a6b4d3d49ef0daafe3c57c..0d3db69cc27591ea042925c45151654a0c5f4bc2 100644 (file)
  \r
 #include "../../stdafx.h"\r
 \r
-#if defined(_MSC_VER)\r
-#pragma warning (push, 1) // TODO: Legacy code, just disable warnings\r
-#pragma warning (disable : 4244)\r
-#endif\r
-\r
 #include "decklink_consumer.h"\r
 \r
 #include "util.h"\r
 \r
 namespace caspar { namespace core { namespace decklink{\r
 \r
-struct decklink_consumer::Implementation : boost::noncopyable\r
-{\r
-       Implementation(const video_format_desc& format_desc, bool internalKey) : format_desc_(format_desc), currentFormat_(video_format::pal), internalKey_(internalKey)\r
+struct decklink_consumer::implementation : boost::noncopyable\r
+{                      \r
+       boost::unique_future<void> active_;\r
+       executor executor_;\r
+\r
+       std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, 3> reserved_frames_;\r
+\r
+       bool                                            internal_key;\r
+       CComPtr<IDeckLink>                      decklink_;\r
+       CComQIPtr<IDeckLinkOutput>      output_;\r
+       CComQIPtr<IDeckLinkKeyer>       keyer_;\r
+       \r
+       video_format::type current_format_;\r
+       video_format_desc format_desc_;\r
+\r
+public:\r
+       implementation(const video_format_desc& format_desc, size_t device_index, bool internalKey) \r
+               : format_desc_(format_desc)\r
+               , current_format_(video_format::pal)\r
+               , internal_key(internalKey)\r
        {       \r
                executor_.start();\r
                executor_.invoke([=]\r
@@ -66,10 +78,11 @@ struct decklink_consumer::Implementation : boost::noncopyable
                        if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator)))\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: No Decklink drivers installed."));\r
 \r
-                       while(pDecklinkIterator->Next(&decklink_) == S_OK && !decklink_){}      \r
+                       size_t n = 0;\r
+                       while(n < device_index && pDecklinkIterator->Next(&decklink_) == S_OK){++n;}    \r
 \r
-                       if(decklink_ == nullptr)\r
-                               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: No Decklink card found."));\r
+                       if(n != device_index || !decklink_)\r
+                               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: No Decklink card found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index)));\r
 \r
                        output_ = decklink_;\r
                        keyer_ = decklink_;\r
@@ -83,7 +96,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
                        if(decklinkVideoFormat == ULONG_MAX) \r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: Card does not support requested videoformat."));\r
                \r
-                       currentFormat_ = format_desc_.format;\r
+                       current_format_ = format_desc_.format;\r
 \r
                        BMDDisplayModeSupport displayModeSupport;\r
                        if(FAILED(output_->DoesSupportVideoMode((BMDDisplayMode)decklinkVideoFormat, bmdFormat8BitBGRA, &displayModeSupport)))\r
@@ -93,7 +106,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
                        if(FAILED(output_->EnableVideoOutput((BMDDisplayMode)decklinkVideoFormat, bmdVideoOutputFlagDefault))) \r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: Could not enable video output."));\r
 \r
-                       if(internalKey_\r
+                       if(internal_key\r
                        {\r
                                if(FAILED(keyer_->Enable(FALSE)))                       \r
                                        CASPAR_LOG(error) << "DECKLINK: Failed to enable internal keye.r";                      \r
@@ -110,7 +123,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
                                        CASPAR_LOG(info) << "DECKLINK: Successfully configured external keyer.";                        \r
                        }\r
                \r
-                       for(int n = 0; n < reserved_frames_.size(); ++n)\r
+                       for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
                        {\r
                                if(FAILED(output_->CreateVideoFrame(format_desc_.width, format_desc_.height, format_desc_.size/format_desc_.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &reserved_frames_[n].second)))\r
                                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("DECKLINK: Failed to create frame."));\r
@@ -121,13 +134,14 @@ struct decklink_consumer::Implementation : boost::noncopyable
 \r
                        CASPAR_LOG(info) << "DECKLINK: Successfully initialized decklink for " << format_desc_.name;\r
                });\r
+               active_ = executor_.begin_invoke([]{});\r
        }\r
 \r
-       ~Implementation()\r
+       ~implementation()\r
        {                               \r
                executor_.invoke([this]\r
                {\r
-                       if(output_) \r
+                       if(output_ != nullptr\r
                                output_->DisableVideoOutput();\r
 \r
                        for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
@@ -142,6 +156,7 @@ struct decklink_consumer::Implementation : boost::noncopyable
        \r
        void send(const safe_ptr<const read_frame>& frame)\r
        {\r
+               active_.get();\r
                active_ = executor_.begin_invoke([=]\r
                {               \r
                        std::copy(frame->image_data().begin(), frame->image_data().end(), static_cast<char*>(reserved_frames_.front().first));\r
@@ -152,35 +167,16 @@ struct decklink_consumer::Implementation : boost::noncopyable
                        std::rotate(reserved_frames_.begin(), reserved_frames_.begin() + 1, reserved_frames_.end());\r
                });\r
        }\r
-       \r
-       frame_consumer::sync_mode synchronize()\r
-       {\r
-               active_.get();\r
-               return frame_consumer::ready;\r
-       }\r
 \r
        size_t buffer_depth() const\r
        {\r
                return 1;\r
        }\r
-                       \r
-       boost::unique_future<void> active_;\r
-       executor executor_;\r
-\r
-       std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, 3> reserved_frames_;\r
-\r
-       bool                                            internalKey_;\r
-       CComPtr<IDeckLink>                      decklink_;\r
-       CComQIPtr<IDeckLinkOutput>      output_;\r
-       CComQIPtr<IDeckLinkKeyer>       keyer_;\r
-       \r
-       video_format::type currentFormat_;\r
-       video_format_desc format_desc_;\r
 };\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 safe_ptr<const 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
+decklink_consumer::decklink_consumer(const video_format_desc& format_desc, size_t device_index, bool internalKey) : impl_(new implementation(format_desc, device_index, internalKey)){}\r
+decklink_consumer::decklink_consumer(decklink_consumer&& other) : impl_(std::move(other.impl_)){}\r
+void decklink_consumer::send(const safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
+size_t decklink_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
        \r
 }}}    
\ No newline at end of file
index 95b093a6821791285299ad2dc97c94585d466e04..a1070db90bf79ba9bcd1c0f4416e9ae1dc45988e 100644 (file)
@@ -28,14 +28,14 @@ namespace caspar { namespace core { namespace decklink {
 class decklink_consumer : public frame_consumer\r
 {\r
 public:\r
-       explicit decklink_consumer(const video_format_desc& format_desc, bool internalKey = false);\r
+       explicit decklink_consumer(const video_format_desc& format_desc, size_t device_index, bool internal_key = false);\r
+       decklink_consumer(decklink_consumer&& other);\r
        \r
        virtual void send(const safe_ptr<const read_frame>&);\r
-       virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
-       struct Implementation;\r
-       std::tr1::shared_ptr<Implementation> pImpl_;\r
+       struct implementation;\r
+       std::tr1::shared_ptr<implementation> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
index f639b026ba50732e5cd594d249929db435b3970a..8b01c6ffe609c39d29289641e2d09c499e4fe17f 100644 (file)
@@ -29,16 +29,9 @@ class read_frame;
 \r
 struct frame_consumer : boost::noncopyable\r
 {\r
-       enum sync_mode\r
-       {\r
-               ready = 0,\r
-               clock           \r
-       };\r
-\r
        virtual ~frame_consumer() {}\r
 \r
        virtual void send(const safe_ptr<const read_frame>& frame) = 0;\r
-       virtual sync_mode synchronize() = 0;\r
        virtual size_t buffer_depth() const = 0;\r
 };\r
 \r
index b7d194e19f29039c288fa37798edb6f106c3050c..27cf5a2f0fd364b662e76f5baee8fdded54717ac 100644 (file)
-#include "../StdAfx.h"\r
+/*\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
-#ifdef _MSC_VER\r
-#pragma warning (disable : 4244)\r
-#endif\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
\r
+#include "..\..\StdAfx.h"\r
 \r
-#include "frame_consumer_device.h"\r
+#ifndef DISABLE_BLUEFISH\r
 \r
-#include "../format/video_format.h"\r
+#include "fwd.h"\r
+#include "bluefish_consumer.h"\r
+#include "util.h"\r
+#include "exception.h"\r
+#include "memory.h"\r
+\r
+#include "../../processor/read_frame.h"\r
 \r
 #include <common/concurrency/executor.h>\r
-#include <common/utility/timer.h>\r
 \r
-#include <boost/range/algorithm_ext/erase.hpp>\r
-#include <boost/range/algorithm.hpp>\r
+#include <tbb/concurrent_queue.h>\r
+\r
+#include <BlueVelvet4.h>\r
+#include <BlueHancUtils.h>\r
 \r
-namespace caspar { namespace core {\r
+namespace caspar { namespace core { namespace bluefish {\r
        \r
-struct frame_consumer_device::implementation\r
+struct consumer::implementation : boost::noncopyable\r
 {\r
-public:\r
-       implementation(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers) : consumers_(consumers), fmt_(format_desc)\r
-       {               \r
-               std::vector<size_t> depths;\r
-               boost::range::transform(consumers_, std::back_inserter(depths), std::mem_fn(&frame_consumer::buffer_depth));\r
-               max_depth_ = *boost::range::max_element(depths);\r
-               executor_.set_capacity(3);\r
-               executor_.start();\r
-       }\r
+       boost::unique_future<void> active_;\r
+       executor executor_;\r
                        \r
-       void consume(safe_ptr<const read_frame>&& frame)\r
-       {               \r
-               executor_.begin_invoke([=]\r
+       BlueVelvetPtr sdk_;\r
+       \r
+       unsigned int device_index_;\r
+       video_format_desc format_desc_;\r
+               \r
+       unsigned long   mem_fmt_;\r
+       unsigned long   upd_fmt_;\r
+       EVideoMode              vid_fmt_; \r
+       unsigned long   res_fmt_; \r
+       unsigned long   engine_mode_;\r
+\r
+       std::shared_ptr<const read_frame> transferring_frame_;\r
+\r
+       std::array<page_locked_buffer_ptr, 3> hanc_buffers_;\r
+       int current_id_;\r
+       bool embed_audio_;\r
+\r
+public:\r
+       implementation::implementation(const video_format_desc& format_desc, unsigned int device_index, bool embed_audio) \r
+               : sdk_(BlueVelvetFactory4())\r
+               , device_index_(device_index)\r
+               , format_desc_(format_desc)\r
+               , mem_fmt_(MEM_FMT_ARGB_PC)\r
+               , upd_fmt_(UPD_FMT_FRAME)\r
+               , vid_fmt_(VID_FMT_INVALID) \r
+               , res_fmt_(RES_FMT_NORMAL) \r
+               , engine_mode_(VIDEO_ENGINE_FRAMESTORE)         \r
+               , current_id_(0)\r
+               , embed_audio_(embed_audio)\r
+       {\r
+                               \r
+               if(BLUE_FAIL(sdk_->device_attach(device_index_, FALSE))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to attach device."));\r
+       \r
+               int videoCardType = sdk_->has_video_cardtype();\r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Card type: ") << get_card_desc(videoCardType) << TEXT(". (device ") << device_index_ << TEXT(")");\r
+       \r
+               //void* pBlueDevice = blue_attach_to_device(1);\r
+               //EBlueConnectorPropertySetting video_routing[1];\r
+               //auto channel = BLUE_VIDEO_OUTPUT_CHANNEL_A;\r
+               //video_routing[0].channel = channel;   \r
+               //video_routing[0].propType = BLUE_CONNECTOR_PROP_SINGLE_LINK;\r
+               //video_routing[0].connector = channel == BLUE_VIDEO_OUTPUT_CHANNEL_A ? BLUE_CONNECTOR_SDI_OUTPUT_A : BLUE_CONNECTOR_SDI_OUTPUT_B;\r
+               //blue_set_connector_property(pBlueDevice, 1, video_routing);\r
+               //blue_detach_from_device(&pBlueDevice);\r
+               \r
+               auto desiredVideoFormat = vid_fmt_from_video_format(format_desc_.format);\r
+               int videoModeCount = sdk_->count_video_mode();\r
+               for(int videoModeIndex = 1; videoModeIndex <= videoModeCount; ++videoModeIndex) \r
                {\r
-                       buffer_.push_back(frame);\r
+                       EVideoMode videoMode = sdk_->enum_video_mode(videoModeIndex);\r
+                       if(videoMode == desiredVideoFormat) \r
+                               vid_fmt_ = videoMode;                   \r
+               }\r
+               if(vid_fmt_ == VID_FMT_INVALID)\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set videomode."));\r
+               \r
+               // Set default video output channel\r
+               //if(BLUE_FAIL(set_card_property(sdk_, DEFAULT_VIDEO_OUTPUT_CHANNEL, channel)))\r
+               //      CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set default channel. (device ") << device_index_ << TEXT(")");\r
+\r
+               //Setting output Video mode\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_MODE, vid_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set videomode."));\r
+\r
+               //Select Update Mode for output\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_UPDATE_TYPE, upd_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set update type. "));\r
        \r
-                       boost::range::for_each(consumers_, [&](const safe_ptr<frame_consumer>& consumer)\r
-                       {\r
-                               size_t offset = max_depth_ - consumer->buffer_depth();\r
-                               if(offset < buffer_.size())\r
-                                       consumer->send(*(buffer_.begin() + offset));\r
-                       });\r
+               disable_video_output();\r
+\r
+               //Enable dual link output\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_DUAL_LINK_OUTPUT, 1)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to enable dual link."));\r
+\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, Signal_FormatType_4224)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set dual link format type to 4:2:2:4. (device " + boost::lexical_cast<std::string>(device_index_) + ")"));\r
                        \r
-                       frame_consumer::sync_mode sync = frame_consumer::ready;\r
-                       boost::range::for_each(consumers_, [&](const safe_ptr<frame_consumer>& consumer)\r
+               //Select output memory format\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_MEMORY_FORMAT, mem_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set memory format."));\r
+               \r
+               //Select image orientation\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_IMAGE_ORIENTATION, ImageOrientation_Normal)))\r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set image orientation to normal. (device ") << device_index_ << TEXT(")"); \r
+\r
+               // Select data range\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_RGB_DATA_RANGE, CGR_RANGE))) \r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set RGB data range to CGR. (device ") << device_index_ << TEXT(")");       \r
+               \r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_PREDEFINED_COLOR_MATRIX, vid_fmt_ == VID_FMT_PAL ? MATRIX_601_CGR : MATRIX_709_CGR)))\r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set colormatrix to ") << (vid_fmt_ == VID_FMT_PAL ? TEXT("601 CGR") : TEXT("709 CGR")) << TEXT(". (device ") << device_index_ << TEXT(")");\r
+               \r
+               //if(BLUE_FAIL(set_card_property(sdk_, EMBEDDED_AUDIO_OUTPUT, 0)))      \r
+               //      CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to enable embedded audio. (device ") << device_index_ << TEXT(")");   \r
+               //else \r
+               //{\r
+               //      CASPAR_LOG(info) << TEXT("BLUECARD INFO: Enabled embedded audio. (device ") << device_index_ << TEXT(")");\r
+               //      hasEmbeddedAudio_ = true;\r
+               //}\r
+\r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << format_desc_ << TEXT(". (device ") << device_index_ << TEXT(")");\r
+\r
+               if (sdk_->has_output_key()) \r
+               {\r
+                       int dummy = TRUE; int v4444 = FALSE; int invert = FALSE; int white = FALSE;\r
+                       sdk_->set_output_key(dummy, v4444, invert, white);\r
+               }\r
+\r
+               if(sdk_->GetHDCardType(device_index_) != CRD_HD_INVALID) \r
+                       sdk_->Set_DownConverterSignalType(vid_fmt_ == VID_FMT_PAL ? SD_SDI : HD_SDI);   \r
+       \r
+               if(BLUE_FAIL(sdk_->set_video_engine(engine_mode_)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set vido engine."));\r
+\r
+               enable_video_output();\r
+                                               \r
+               page_locked_buffer::reserve_working_size(MAX_HANC_BUFFER_SIZE * hanc_buffers_.size());          \r
+               for(size_t n = 0; n < hanc_buffers_.size(); ++n)\r
+                       hanc_buffers_[n] = std::make_shared<page_locked_buffer>(MAX_HANC_BUFFER_SIZE);\r
+                               \r
+               executor_.start();\r
+\r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Successfully initialized device ") << device_index_;\r
+\r
+               active_ = executor_.begin_invoke([]{});\r
+       }\r
+\r
+       ~implementation()\r
+       {\r
+               page_locked_buffer::unreserve_working_size(MAX_HANC_BUFFER_SIZE * hanc_buffers_.size());                \r
+               disable_video_output();\r
+\r
+               if(sdk_)\r
+                       sdk_->device_detach();          \r
+\r
+               CASPAR_LOG(info) << "BLUECARD INFO: Successfully released device " << device_index_;\r
+       }\r
+       \r
+       void enable_video_output()\r
+       {\r
+               if(!BLUE_PASS(set_card_property(sdk_, VIDEO_BLACKGENERATOR, 0)))\r
+                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");  \r
+       }\r
+\r
+       void disable_video_output()\r
+       {\r
+               if(!BLUE_PASS(set_card_property(sdk_, VIDEO_BLACKGENERATOR, 1)))\r
+                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");          \r
+       }\r
+\r
+       void send(const safe_ptr<const read_frame>& frame)\r
+       {                       \r
+               static size_t audio_samples = static_cast<size_t>(48000.0 / format_desc_.fps);\r
+               static size_t audio_nchannels = 2;\r
+               static std::vector<short> silence(audio_samples*audio_nchannels*2, 0);\r
+               \r
+               active_.get();\r
+               active_ = executor_.begin_invoke([=]\r
+               {\r
+                       try\r
                        {\r
-                               try\r
-                               {\r
-                                       size_t offset = max_depth_ - consumer->buffer_depth();\r
-                                       if(offset < buffer_.size() && consumer->synchronize() == frame_consumer::clock)\r
-                                               sync = frame_consumer::clock;\r
+                               auto hanc = hanc_buffers_.front();              \r
+                               std::rotate(hanc_buffers_.begin(), hanc_buffers_.begin() + 1, hanc_buffers_.end());\r
+\r
+                               unsigned long fieldCount = 0;\r
+                               sdk_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
+                               \r
+                               if(embed_audio_)\r
+                               {               \r
+                                       auto frame_audio_data = frame->audio_data().empty() ? silence.data() : const_cast<short*>(frame->audio_data().begin());\r
+\r
+                                       encode_hanc(reinterpret_cast<BLUE_UINT32*>(hanc->data()), frame_audio_data, audio_samples, audio_nchannels);\r
+                                                               \r
+                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->image_data().begin()), \r
+                                                                                                       frame->image_data().size(), \r
+                                                                                                       nullptr, \r
+                                                                                                       BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
+\r
+                                       sdk_->system_buffer_write_async(hanc->data(),\r
+                                                                                                       hanc->size(), \r
+                                                                                                       nullptr,                 \r
+                                                                                                       BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_HANC));\r
+\r
+                                       if(BLUE_FAIL(sdk_->render_buffer_update(BlueBuffer_Image_HANC(current_id_))))\r
+                                               CASPAR_LOG(trace) << TEXT("BLUEFISH: render_buffer_update failed");\r
                                }\r
-                               catch(...)\r
+                               else\r
                                {\r
-                                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                                       boost::range::remove_erase(consumers_, consumer);\r
-                                       CASPAR_LOG(warning) << "Removed consumer from frame_consumer_device.";\r
+                                       sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->image_data().begin()),\r
+                                                                                                       frame->image_data().size(), \r
+                                                                                                       nullptr,                 \r
+                                                                                                       BlueImage_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
+                       \r
+                                       if(BLUE_FAIL(sdk_->render_buffer_update(BlueBuffer_Image(current_id_))))\r
+                                               CASPAR_LOG(trace) << TEXT("BLUEFISH: render_buffer_update failed");\r
                                }\r
-                       });\r
-       \r
-                       if(sync != frame_consumer::clock)\r
-                               clock_.wait(fmt_.actual_fps);\r
 \r
-                       if(buffer_.size() >= max_depth_)\r
-                               buffer_.pop_front();\r
+                               transferring_frame_ = frame;\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       }\r
                });\r
        }\r
 \r
-       timer clock_;\r
-       executor executor_;     \r
+       size_t buffer_depth() const\r
+       {\r
+               return 1;\r
+       }\r
 \r
-       size_t max_depth_;\r
-       std::deque<safe_ptr<const read_frame>> buffer_;         \r
+       void encode_hanc(BLUE_UINT32* hanc_data, void* audio_data, size_t audio_samples, size_t audio_nchannels)\r
+       {       \r
+               auto card_type = sdk_->has_video_cardtype();\r
+               auto sample_type = (AUDIO_CHANNEL_16BIT | AUDIO_CHANNEL_LITTLEENDIAN);\r
+               \r
+               hanc_stream_info_struct hanc_stream_info;\r
+               memset(&hanc_stream_info, 0, sizeof(hanc_stream_info));\r
 \r
-       std::vector<safe_ptr<frame_consumer>> consumers_;\r
-       \r
-       const video_format_desc fmt_;\r
+               std::fill_n(hanc_stream_info.AudioDBNArray, sizeof(hanc_stream_info.AudioDBNArray)/sizeof(hanc_stream_info.AudioDBNArray[0]), -1);\r
+               hanc_stream_info.hanc_data_ptr = hanc_data;\r
+               hanc_stream_info.video_mode = vid_fmt_;\r
+               \r
+               auto emb_audio_flag = (blue_emb_audio_enable | blue_emb_audio_group1_enable);\r
+\r
+               if (!is_epoch_card(card_type))\r
+               {\r
+                       encode_hanc_frame(&hanc_stream_info, audio_data, audio_nchannels, \r
+                                                               audio_samples, sample_type, emb_audio_flag);    \r
+               }\r
+               else\r
+               {\r
+                       encode_hanc_frame_ex(card_type, &hanc_stream_info, audio_data, audio_nchannels,\r
+                                                                audio_samples, sample_type, emb_audio_flag);\r
+               }                                               \r
+       }\r
 };\r
 \r
-frame_consumer_device::frame_consumer_device(frame_consumer_device&& other) : impl_(std::move(other.impl_)){}\r
-frame_consumer_device::frame_consumer_device(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers) : impl_(new implementation(format_desc, consumers)){}\r
-void frame_consumer_device::consume(safe_ptr<const read_frame>&& future_frame) { impl_->consume(std::move(future_frame)); }\r
-}}
\ No newline at end of file
+consumer::consumer(consumer&& other) : impl_(std::move(other.impl_)){}\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 safe_ptr<const read_frame>& frame){impl_->send(frame);}\r
+size_t consumer::buffer_depth() const{return impl_->buffer_depth();}\r
+}}}\r
+\r
+#endif
\ No newline at end of file
index b5dc8c277b0831343d70aaaebeb8a226ced660f3..27cf597691ebf5672878ac0c7c91b04db8755044 100644 (file)
@@ -16,8 +16,8 @@ struct video_format_desc;
 class frame_consumer_device : boost::noncopyable\r
 {\r
 public:\r
+       explicit frame_consumer_device(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
        frame_consumer_device(frame_consumer_device&& other);\r
-       frame_consumer_device(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
        void consume(safe_ptr<const read_frame>&& future_frame); // nothrow\r
 private:\r
        struct implementation;\r
index f59a0859d5f8e498f91afb865d9b165f91a236fd..4ce4ab6428d0a8699f2ce485af559bca727ae21a 100644 (file)
@@ -34,7 +34,12 @@ namespace caspar { namespace core { namespace oal {
 \r
 struct consumer::implementation : public sf::SoundStream, boost::noncopyable\r
 {\r
-       implementation() : container_(5)\r
+       tbb::concurrent_bounded_queue<std::vector<short>> input_;\r
+       boost::circular_buffer<std::vector<short>> container_;\r
+\r
+public:\r
+       implementation() \r
+               : container_(5)\r
        {\r
                sf::SoundStream::Initialize(2, 48000);\r
                Play();         \r
@@ -48,11 +53,6 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
                input_.push(std::vector<short>(frame->audio_data().begin(), frame->audio_data().end()));        \r
        }\r
 \r
-       frame_consumer::sync_mode synchronize()\r
-       {\r
-               return frame_consumer::ready;\r
-       }\r
-\r
        size_t buffer_depth() const\r
        {\r
                return 3;\r
@@ -75,14 +75,10 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
 \r
                return true;\r
        }\r
-\r
-       tbb::concurrent_bounded_queue<std::vector<short>> input_;\r
-       boost::circular_buffer<std::vector<short>> container_;\r
 };\r
 \r
 consumer::consumer(consumer&& other) : impl_(std::move(other.impl_)){}\r
 consumer::consumer(const video_format_desc&) : impl_(new implementation()){}\r
 void consumer::send(const safe_ptr<const 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 77c9daefa2dab5d7dfe4e16a7b20d733fce85761..9a2875f61db28aef6989638348434a0ff906d6fc 100644 (file)
@@ -27,11 +27,10 @@ namespace caspar { namespace core { namespace oal {
 class consumer : public frame_consumer\r
 {\r
 public:        \r
-       consumer(consumer&& other);\r
        explicit consumer(const video_format_desc& format_desc);\r
+       consumer(consumer&& other);\r
        \r
        virtual void send(const safe_ptr<const read_frame>&);\r
-       virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
        struct implementation;\r
index 19fb879b183373f6e2dfc7e5ba67c641f39342a2..3c28f80772de4b591ea59a8106712acb3a804418 100644 (file)
@@ -25,7 +25,7 @@
 #include "../../format/video_format.h"\r
 #include "../../processor/read_frame.h"\r
 \r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 #include <common/concurrency/executor.h>\r
 #include <common/utility/safe_ptr.h>\r
 \r
 namespace caspar { namespace core { namespace ogl{     \r
 \r
 struct consumer::implementation : boost::noncopyable\r
-{      \r
+{                      \r
+       boost::unique_future<void> active_;\r
+       executor executor_;\r
+       \r
+       float wratio_;\r
+       float hratio_;\r
+       \r
+       float wSize_;\r
+       float hSize_;\r
+\r
+       GLuint                            texture_;\r
+       std::array<GLuint, 2> pbos_;\r
+\r
+       bool windowed_;\r
+       unsigned int screen_width_;\r
+       unsigned int screen_height_;\r
+       unsigned int screen_x_;\r
+       unsigned int screen_y_;\r
+                               \r
+       stretch stretch_;\r
+       const video_format_desc format_desc_;\r
+       \r
+       sf::Window window_;\r
+\r
+public:\r
        implementation(const video_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed) \r
-               : format_desc_(format_desc), stretch_(stretch), screen_width_(0), screen_height_(0), windowed_(windowed), texture_(0)\r
+               : format_desc_(format_desc)\r
+               , stretch_(stretch)\r
+               , windowed_(windowed)\r
+               , texture_(0)\r
+               , screen_width_(format_desc.width)\r
+               , screen_height_(format_desc.height)\r
+               , screen_x_(0)\r
+               , screen_y_(0)\r
        {               \r
 #ifdef _WIN32\r
                DISPLAY_DEVICE d_device;                        \r
@@ -77,11 +108,6 @@ struct consumer::implementation : boost::noncopyable
 \r
                if(screen_index != 0)\r
                        CASPAR_LOG(warning) << "OGLConsumer only supports screen_index=0 for non-Win32";\r
-               \r
-               screen_width_ = format_desc_.width;\r
-               screen_height_ = format_desc_.height;\r
-               screen_x_ = 0;\r
-               screen_y_ = 0;\r
 #endif\r
 \r
                executor_.start();\r
@@ -129,6 +155,7 @@ struct consumer::implementation : boost::noncopyable
                        glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW_ARB);\r
                        glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);\r
                });\r
+               active_ = executor_.begin_invoke([]{});\r
        }\r
        \r
        std::pair<float, float> None()\r
@@ -200,6 +227,7 @@ struct consumer::implementation : boost::noncopyable
                \r
        void send(const safe_ptr<const read_frame>& frame)\r
        {\r
+               active_.get();\r
                active_ = executor_.begin_invoke([=]\r
                {\r
                        sf::Event e;\r
@@ -209,45 +237,15 @@ struct consumer::implementation : boost::noncopyable
                });\r
        }\r
 \r
-       frame_consumer::sync_mode synchronize()\r
-       {\r
-               active_.get();\r
-               return frame_consumer::ready;\r
-       }\r
 \r
        size_t buffer_depth() const\r
        {\r
                return 2;\r
        }\r
-               \r
-       boost::unique_future<void> active_;\r
-       executor executor_;\r
-       \r
-       float wratio_;\r
-       float hratio_;\r
-       \r
-       float wSize_;\r
-       float hSize_;\r
-\r
-       GLuint                            texture_;\r
-       std::array<GLuint, 2> pbos_;\r
-\r
-       bool windowed_;\r
-       unsigned int screen_width_;\r
-       unsigned int screen_height_;\r
-       unsigned int screen_x_;\r
-       unsigned int screen_y_;\r
-                               \r
-       stretch stretch_;\r
-       const video_format_desc format_desc_;\r
-       \r
-       sf::Window window_;\r
 };\r
 \r
 consumer::consumer(consumer&& other) : impl_(std::move(other.impl_)){}\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
+consumer::consumer(const video_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed) : impl_(new implementation(format_desc, screen_index, stretch, windowed)){}\r
 void consumer::send(const safe_ptr<const 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 0111192c90b9d763e712809f472ba4df58bf8623..66d829fa66209f974c7f9894b14cf4cf7530f213 100644 (file)
@@ -37,11 +37,10 @@ enum stretch
 class consumer : public frame_consumer\r
 {\r
 public:        \r
-       consumer(consumer&& other);\r
        explicit consumer(const video_format_desc& format_desc, unsigned int screen_index = 0, stretch stretch = stretch::fill, bool windowed = false);\r
+       consumer(consumer&& other);\r
        \r
        virtual void send(const safe_ptr<const read_frame>&);\r
-       virtual sync_mode synchronize();\r
        virtual size_t buffer_depth() const;\r
 private:\r
        struct implementation;\r
index 3c058f1387e405c4c8f8d4fe8d1f70f2a455b094..8ff8bd03e15d86cdcadd06caa34699606a43d06f 100644 (file)
@@ -26,7 +26,7 @@
 \r
 #include <array>\r
 \r
-#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s, fmt) { (fmt), (w), (h), (m), (f), (m == video_mode::progressive ? f : f/2.0), (1.0/(m == video_mode::progressive ? f : f/2.0)), ((w)*(h)*4), (s) }\r
+#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s, fmt) { (fmt), (w), (h), (m), (m == video_mode::progressive ? f : f/2.0), (1.0/(m == video_mode::progressive ? f : f/2.0)), ((w)*(h)*4), (s) }\r
 \r
 namespace caspar { namespace core {\r
        \r
index 81ce8174fc6137a3ebfd0113fa61b9597b8b43ea..22189ffd96678da7dd6356af4af03dc1405753cd 100644 (file)
@@ -44,16 +44,15 @@ struct video_mode
 \r
 struct video_format_desc\r
 {\r
-       video_format::type              format;\r
+       video_format::type              format;         // video output format\r
 \r
-       size_t                                  width;\r
-       size_t                                  height;\r
-       video_mode::type                mode;\r
-       double                                  fps;\r
-       double                                  actual_fps;\r
-       double                                  actual_interval;\r
-       size_t                                  size;\r
-       std::wstring                    name;\r
+       size_t                                  width;          // output frame width\r
+       size_t                                  height;         // output frame height\r
+       video_mode::type                mode;           // progressive, interlaced upper field first, interlaced lower field first\r
+       double                                  fps;            // actual framerate, e.g. i50 = 25 fps, p50 = 50 fps\r
+       double                                  interval;       // time between frames\r
+       size_t                                  size;           // output frame size in bytes \r
+       std::wstring                    name;           // name of output format\r
 \r
        static const video_format_desc& get(video_format::type format);\r
        static const video_format_desc& get(const std::wstring& name);\r
index 37d73313992914b9202a8ef6226d60ddf3d167ea..94f5f2652b6e16f716ae2024c6ae1630a7892abb 100644 (file)
@@ -17,6 +17,10 @@ const audio_transform audio_transform::operator*(const audio_transform &other) c
 \r
 struct audio_processor::implementation\r
 {\r
+       std::vector<short> audio_data_;\r
+       std::stack<audio_transform> transform_stack_;\r
+\r
+public:\r
        implementation()\r
        {\r
                transform_stack_.push(audio_transform());\r
@@ -56,9 +60,6 @@ struct audio_processor::implementation
        {\r
                return std::move(audio_data_);\r
        }\r
-\r
-       std::vector<short> audio_data_;\r
-       std::stack<audio_transform> transform_stack_;\r
 };\r
 \r
 audio_processor::audio_processor() : impl_(new implementation()){}\r
index f31d5a48b7f4d3ffb423d6dee17f27cad6d5772f..8258766fb05b2a14733712e866c9387fd37fa018 100644 (file)
@@ -2,7 +2,7 @@
 \r
 #include "device_buffer.h"\r
 \r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 \r
 namespace caspar { namespace core {\r
        \r
@@ -11,7 +11,17 @@ GLenum INTERNAL_FORMAT[] = {0, GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_
 \r
 struct device_buffer::implementation : boost::noncopyable\r
 {\r
-       implementation(size_t width, size_t height, size_t stride) : width_(width), height_(height), stride_(stride)\r
+       GLuint id_;\r
+\r
+       const size_t width_;\r
+       const size_t height_;\r
+       const size_t stride_;\r
+\r
+public:\r
+       implementation(size_t width, size_t height, size_t stride) \r
+               : width_(width)\r
+               , height_(height)\r
+               , stride_(stride)\r
        {       \r
                GL(glGenTextures(1, &id_));\r
                GL(glBindTexture(GL_TEXTURE_2D, id_));\r
@@ -62,12 +72,6 @@ struct device_buffer::implementation : boost::noncopyable
        {\r
                GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, GL_TEXTURE_2D, id_, 0));\r
        }\r
-\r
-       GLuint id_;\r
-\r
-       const size_t width_;\r
-       const size_t height_;\r
-       const size_t stride_;\r
 };\r
 \r
 device_buffer::device_buffer(size_t width, size_t height, size_t stride) : impl_(new implementation(width, height, stride)){}\r
index ddc53532f32999dfaba161c14fbb60331d4ff035..a12cfbcfecf79b52ad324b6987e03795c868815b 100644 (file)
@@ -6,16 +6,22 @@
 #include "audio_processor.h"\r
 #include "pixel_format.h"\r
 \r
-#include <common/utility/singleton_pool.h>\r
-\r
 #include <boost/range/algorithm.hpp>\r
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                \r
 struct draw_frame::implementation\r
-{\r
-       implementation(const std::vector<safe_ptr<draw_frame>>& frames) : frames_(frames){}\r
-       implementation(std::vector<safe_ptr<draw_frame>>&& frames) : frames_(std::move(frames)){}\r
+{              \r
+       std::vector<safe_ptr<draw_frame>> frames_;\r
+\r
+       image_transform image_transform_;       \r
+       audio_transform audio_transform_;\r
+\r
+public:\r
+       implementation(const std::vector<safe_ptr<draw_frame>>& frames) \r
+               : frames_(frames){}\r
+       implementation(std::vector<safe_ptr<draw_frame>>&& frames) \r
+               : frames_(std::move(frames)){}\r
        \r
        void process_image(image_processor& processor)\r
        {\r
@@ -29,43 +35,38 @@ struct draw_frame::implementation
                processor.begin(audio_transform_);\r
                boost::range::for_each(frames_, std::bind(&draw_frame::process_audio, std::placeholders::_1, std::ref(processor)));\r
                processor.end();\r
-       }\r
-               \r
-       std::vector<safe_ptr<draw_frame>> frames_;\r
-\r
-       image_transform image_transform_;       \r
-       audio_transform audio_transform_;       \r
+       }       \r
 };\r
        \r
-draw_frame::draw_frame() : impl_(singleton_pool<implementation>::make_shared(std::vector<safe_ptr<draw_frame>>())){}\r
-draw_frame::draw_frame(const std::vector<safe_ptr<draw_frame>>& frames) : impl_(singleton_pool<implementation>::make_shared(frames)){}\r
-draw_frame::draw_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(singleton_pool<implementation>::make_shared(std::move(frames))){}\r
-draw_frame::draw_frame(const draw_frame& other) : impl_(singleton_pool<implementation>::make_shared(*other.impl_)){}\r
+draw_frame::draw_frame() : impl_(new implementation(std::vector<safe_ptr<draw_frame>>())){}\r
+draw_frame::draw_frame(const std::vector<safe_ptr<draw_frame>>& frames) : impl_(new implementation(frames)){}\r
+draw_frame::draw_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(new implementation(std::move(frames))){}\r
+draw_frame::draw_frame(const draw_frame& other) : impl_(new implementation(*other.impl_)){}\r
 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame)\r
 {\r
        std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(frame);\r
-       impl_ = singleton_pool<implementation>::make_shared(std::move(frames));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame)\r
 {\r
        std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(std::move(frame));\r
-       impl_ = singleton_pool<implementation>::make_shared(std::move(frames));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2)\r
 {\r
        std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(frame1);\r
        frames.push_back(frame2);\r
-       impl_ = singleton_pool<implementation>::make_shared(std::move(frames));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2)\r
 {\r
        std::vector<safe_ptr<draw_frame>> frames;\r
        frames.push_back(std::move(frame1));\r
        frames.push_back(std::move(frame2));\r
-       impl_ = singleton_pool<implementation>::make_shared(std::move(frames));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
 \r
 void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
index a195e9521220524fc94aac9b04b0f844bb40aa7d..da319a9f10cebf454c4b7f704570eeaa723e393f 100644 (file)
@@ -12,7 +12,7 @@
 \r
 #include <common/exception/exceptions.h>\r
 #include <common/concurrency/executor.h>\r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 \r
 #include <tbb/concurrent_queue.h>\r
 #include <tbb/concurrent_unordered_map.h>\r
 namespace caspar { namespace core {\r
        \r
 struct frame_processor_device::implementation : boost::noncopyable\r
-{      \r
-       implementation(const video_format_desc& format_desc) : fmt_(format_desc), image_processor_(format_desc){}\r
+{              \r
+       const video_format_desc format_desc_;\r
+\r
+       audio_processor audio_processor_;\r
+       image_processor image_processor_;\r
+\r
+public:\r
+       implementation(const video_format_desc& format_desc) \r
+               : format_desc_(format_desc)\r
+               , image_processor_(format_desc){}\r
                        \r
        safe_ptr<const read_frame> process(safe_ptr<draw_frame>&& frame)\r
        {                       \r
@@ -42,19 +50,12 @@ struct frame_processor_device::implementation : boost::noncopyable
        {\r
                return make_safe<write_frame>(desc, image_processor_.create_buffers(desc));\r
        }\r
-       \r
-       const video_format_desc format_desc_;\r
-               \r
-       audio_processor audio_processor_;\r
-       image_processor image_processor_;\r
-                                                                                       \r
-       const video_format_desc fmt_;\r
 };\r
        \r
 frame_processor_device::frame_processor_device(frame_processor_device&& other) : impl_(std::move(other.impl_)){}\r
 frame_processor_device::frame_processor_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
 safe_ptr<const read_frame> frame_processor_device::process(safe_ptr<draw_frame>&& frame){return impl_->process(std::move(frame));}\r
-const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_; }\r
+const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->format_desc_; }\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, pixel_format::type pix_fmt)\r
 {\r
index e914abf6ebe2a79b89f2019a879edc4f211690a6..c3522563f7022e8f61fe65a6a22115e562bcc9b5 100644 (file)
@@ -2,14 +2,27 @@
 \r
 #include "host_buffer.h"\r
 \r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
 struct host_buffer::implementation : boost::noncopyable\r
-{\r
-       implementation(size_t size, usage_t usage) : size_(size), data_(nullptr), pbo_(0),\r
-               target_(usage == write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER), usage_(usage == write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
+{      \r
+       GLuint pbo_;\r
+\r
+       const size_t size_;\r
+\r
+       void* data_;\r
+       GLenum usage_;\r
+       GLenum target_;\r
+\r
+public:\r
+       implementation(size_t size, usage_t usage) \r
+               : size_(size)\r
+               , data_(nullptr)\r
+               , pbo_(0)\r
+               , target_(usage == write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
+               , usage_(usage == write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
        {\r
                GL(glGenBuffers(1, &pbo_));\r
                GL(glBindBuffer(target_, pbo_));\r
@@ -58,14 +71,6 @@ struct host_buffer::implementation : boost::noncopyable
        {\r
                GL(glBindBuffer(target_, 0));\r
        }\r
-       \r
-       GLuint pbo_;\r
-\r
-       const size_t size_;\r
-\r
-       void* data_;\r
-       GLenum usage_;\r
-       GLenum target_;\r
 };\r
 \r
 host_buffer::host_buffer(size_t size, usage_t usage) : impl_(new implementation(size, usage)){}\r
index 90d28e650729bc5ffe7781ca5a86a98cf6ff27ef..a88f35e8fd0bf4d18cee7cdf8ac48b8f743fcc79 100644 (file)
@@ -3,7 +3,7 @@
 #include "image_kernel.h"\r
 \r
 #include <common/exception/exceptions.h>\r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 \r
 #include <Glee.h>\r
 \r
@@ -15,6 +15,7 @@ namespace caspar { namespace core {
 \r
 class shader_program\r
 {\r
+       GLuint program_;\r
 public:\r
 \r
        shader_program() : program_(0) {}\r
@@ -101,9 +102,6 @@ public:
        {       \r
                GL(glUseProgramObjectARB(program_));            \r
        }\r
-\r
-private:\r
-       GLuint program_;\r
 };\r
 \r
 GLubyte progressive_pattern[] = {\r
@@ -125,7 +123,10 @@ GLubyte lower_pattern[] = {
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
 \r
 struct image_kernel::implementation\r
-{\r
+{      \r
+       std::unordered_map<pixel_format::type, shader_program> shaders_;\r
+\r
+public:\r
        std::unordered_map<pixel_format::type, shader_program>& shaders()\r
        {\r
                GL(glEnable(GL_POLYGON_STIPPLE));\r
@@ -220,8 +221,6 @@ struct image_kernel::implementation
                }\r
                return shaders_;\r
        }\r
-       \r
-       std::unordered_map<pixel_format::type, shader_program> shaders_;\r
 };\r
 \r
 image_kernel::image_kernel() : impl_(new implementation()){}\r
index 6897de5b5a97c38f4fb0acf15774b2574469f78a..79e39f255135288702d3a5813b523f4422613ef8 100644 (file)
@@ -8,7 +8,7 @@
 #include "device_buffer.h"\r
 \r
 #include <common/exception/exceptions.h>\r
-#include <common/gl/utility.h>\r
+#include <common/gl/gl_check.h>\r
 #include <common/concurrency/executor.h>\r
 \r
 #include <Glee.h>\r
@@ -36,7 +36,21 @@ const image_transform image_transform::operator*(const image_transform &other) c
 }\r
 \r
 struct image_processor::implementation : boost::noncopyable\r
-{      \r
+{                      \r
+       ogl_device context_;\r
+\r
+       const video_format_desc format_desc_;\r
+       \r
+       std::stack<image_transform> transform_stack_;\r
+\r
+       GLuint fbo_;\r
+       std::array<std::shared_ptr<device_buffer>, 2> render_targets_;\r
+\r
+       std::shared_ptr<host_buffer> reading_;\r
+\r
+       image_kernel kernel_;\r
+\r
+public:\r
        implementation(const video_format_desc& format_desc) : format_desc_(format_desc)\r
        {\r
                context_.begin_invoke([=]\r
@@ -139,19 +153,6 @@ struct image_processor::implementation : boost::noncopyable
                });\r
                return buffers;\r
        }\r
-               \r
-       ogl_device context_;\r
-\r
-       const video_format_desc format_desc_;\r
-       \r
-       std::stack<image_transform> transform_stack_;\r
-\r
-       GLuint fbo_;\r
-       std::array<std::shared_ptr<device_buffer>, 2> render_targets_;\r
-\r
-       std::shared_ptr<host_buffer> reading_;\r
-\r
-       image_kernel kernel_;\r
 };\r
 \r
 image_processor::image_processor(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
index 87f67e8bd98e9b73f21cd1561703666500ba9a14..35a95dcdc272f0acfa4a033a482ddd17860929f7 100644 (file)
@@ -35,6 +35,7 @@ public:
                \r
        safe_ptr<device_buffer> create_device_buffer(size_t width, size_t height, size_t stride);\r
        safe_ptr<host_buffer> create_host_buffer(size_t size, host_buffer::usage_t usage);\r
+\r
 private:\r
        executor executor_;\r
        std::unique_ptr<sf::Context> context_;\r
index c2ee9d969348b9e8679d3f674dc85dff7e821176..89993bf76be17fcdc6219284e3881a1b656e8f58 100644 (file)
@@ -4,21 +4,23 @@
 \r
 #include "host_buffer.h"\r
 \r
-#include <common/gl/utility.h>\r
-#include <common/utility/singleton_pool.h>\r
+#include <common/gl/gl_check.h>\r
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
 struct read_frame::implementation : boost::noncopyable\r
 {\r
-       implementation(safe_ptr<const host_buffer>&& image_data, std::vector<short>&& audio_data) : image_data_(std::move(image_data)), audio_data_(std::move(audio_data)){}    \r
-\r
        safe_ptr<const host_buffer> image_data_;\r
        std::vector<short> audio_data_;\r
+\r
+public:\r
+       implementation(safe_ptr<const host_buffer>&& image_data, std::vector<short>&& audio_data) \r
+               : image_data_(std::move(image_data))\r
+               , audio_data_(std::move(audio_data)){}  \r
 };\r
 \r
 read_frame::read_frame(){}\r
-read_frame::read_frame(safe_ptr<const host_buffer>&& image_data, std::vector<short>&& audio_data) : impl_(singleton_pool<implementation>::make_shared(image_data, audio_data)){}\r
+read_frame::read_frame(safe_ptr<const host_buffer>&& image_data, std::vector<short>&& audio_data) : impl_(new implementation(std::move(image_data), std::move(audio_data))){}\r
 \r
 const boost::iterator_range<const unsigned char*> read_frame::image_data() const\r
 {\r
index f1c947faf8f024b0e8cdc2c91d2666dc1463456e..76519e6f79027174c5b1e256febd74f6838af9c7 100644 (file)
@@ -9,16 +9,22 @@
 #include "audio_processor.h"\r
 #include "pixel_format.h"\r
 \r
-#include "../../common/gl/utility.h"\r
-#include "../../common/utility/singleton_pool.h"\r
+#include <common/gl/gl_check.h>\r
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
 struct write_frame::implementation : boost::noncopyable\r
-{\r
-       implementation(const pixel_format_desc& desc, std::vector<safe_ptr<host_buffer>> buffers) : desc_(desc), buffers_(buffers){}\r
+{                              \r
+       std::vector<safe_ptr<host_buffer>> buffers_;\r
+       std::vector<short> audio_data_;\r
+       const pixel_format_desc desc_;\r
+\r
+public:\r
+       implementation(const pixel_format_desc& desc, std::vector<safe_ptr<host_buffer>> buffers) \r
+               : desc_(desc)\r
+               , buffers_(buffers){}\r
        \r
        void process_image(image_processor& processor)\r
        {\r
@@ -44,13 +50,9 @@ struct write_frame::implementation : boost::noncopyable
                auto ptr = static_cast<const unsigned char*>(buffers_[index]->data());\r
                return boost::iterator_range<const unsigned char*>(ptr, ptr+buffers_[index]->size());\r
        }\r
-                               \r
-       std::vector<safe_ptr<host_buffer>> buffers_;\r
-       std::vector<short> audio_data_;\r
-       const pixel_format_desc desc_;\r
 };\r
        \r
-write_frame::write_frame(const pixel_format_desc& desc, std::vector<safe_ptr<host_buffer>> buffers) : impl_(singleton_pool<implementation>::make_shared(desc, buffers)){}\r
+write_frame::write_frame(const pixel_format_desc& desc, std::vector<safe_ptr<host_buffer>> buffers) : impl_(new implementation(desc, buffers)){}\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
index f1e199504f4bf3f146c29a0c538ca98b034c3431..c1ad6c2807c989013680aa22f0264e7784d68479 100644 (file)
@@ -30,8 +30,13 @@ namespace caspar { namespace core {
        \r
 class color_producer : public frame_producer\r
 {\r
+       safe_ptr<draw_frame> frame_;\r
+       std::wstring color_str_;\r
+\r
 public:\r
-       color_producer(color_producer&& other) : frame_(std::move(other.frame_)), color_str_(std::move(other.color_str_)){}\r
+       explicit color_producer(color_producer&& other) \r
+               : frame_(std::move(other.frame_))\r
+               , color_str_(std::move(other.color_str_)){}\r
 \r
        explicit color_producer(const std::wstring& color) : color_str_(color), frame_(draw_frame::empty())\r
        {\r
@@ -51,9 +56,6 @@ public:
        }\r
        \r
        virtual std::wstring print() const { return + L"color[" + color_str_ + L"]"; }\r
-\r
-       safe_ptr<draw_frame> frame_;\r
-       std::wstring color_str_;\r
 };\r
 \r
 safe_ptr<frame_producer> create_color_producer(const std::vector<std::wstring>& params)\r
index eff989f24986a39e9c4c675a761fdce98017f0c0..59a3fb5651fc5abd0a059b9365a8e9d9fc6a9cf4 100644 (file)
@@ -21,17 +21,29 @@ namespace caspar { namespace core { namespace ffmpeg{
 \r
 struct audio_decoder::implementation : boost::noncopyable\r
 {\r
+       typedef std::vector<short, tbb::cache_aligned_allocator<short>> buffer;\r
+       \r
+       AVCodecContext* codec_context_;\r
+\r
+       buffer audio_buffer_;   \r
+       buffer current_chunk_;\r
+\r
+       size_t audio_frame_size_;\r
+\r
        static const size_t SAMPLE_RATE = 48000;\r
        static const size_t N_CHANNELS = 2;\r
 \r
-       implementation(AVCodecContext* codec_context, double fps) : current_chunk_(), codec_context_(codec_context), audio_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2)\r
+public:\r
+       explicit implementation(AVCodecContext* codec_context, double fps) \r
+               : codec_context_(codec_context)\r
+               , audio_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2)\r
+               , audio_frame_size_(static_cast<size_t>(static_cast<double>(SAMPLE_RATE) / fps) * N_CHANNELS)\r
        {\r
                if(codec_context_->sample_rate != SAMPLE_RATE)\r
                        BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid sample rate. Expected 48000."));\r
 \r
                if(codec_context_->channels != 2)\r
                        BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid channel count. Expected 2."));\r
-               audio_frame_size_ = static_cast<size_t>(static_cast<double>(SAMPLE_RATE) / fps) * N_CHANNELS;\r
        }\r
                \r
        std::vector<std::vector<short>> execute(const aligned_buffer& audio_packet)\r
@@ -55,16 +67,6 @@ struct audio_decoder::implementation : boost::noncopyable
                \r
                return chunks_;\r
        }\r
-\r
-       size_t audio_frame_size_;\r
-\r
-       typedef std::vector<short, tbb::cache_aligned_allocator<short>> buffer;\r
-\r
-       buffer audio_buffer_;   \r
-\r
-       std::vector<short, tbb::cache_aligned_allocator<short>> current_chunk_;\r
-\r
-       AVCodecContext* codec_context_;\r
 };\r
 \r
 audio_decoder::audio_decoder(AVCodecContext* codec_context, double fps) : impl_(new implementation(codec_context, fps)){}\r
index 66b57b6be281fe6ceb3f3504b92bce0dfb389a5d..fb3d4d7c76dbd5ce6049e46251ba4ec71f72b4f6 100644 (file)
@@ -16,7 +16,7 @@ typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>>
 class audio_decoder : boost::noncopyable\r
 {\r
 public:\r
-       audio_decoder(AVCodecContext* codec_context, double fps);\r
+       explicit audio_decoder(AVCodecContext* codec_context, double fps);\r
        std::vector<std::vector<short>> execute(const aligned_buffer& audio_packet);\r
 private:\r
        struct implementation;\r
index 08227867e741efa7b3e6e2332067b38233474f58..a2cb23183014a47892051bb759f873c9aa82c9a8 100644 (file)
@@ -19,9 +19,28 @@ namespace caspar { namespace core { namespace ffmpeg{
        \r
 struct ffmpeg_producer : public frame_producer\r
 {\r
+       input                                                           input_;                 \r
+       audio_decoder                                           audio_decoder_;\r
+       video_decoder                                           video_decoder_;\r
+\r
+       std::deque<safe_ptr<write_frame>>       video_frame_channel_;   \r
+       std::deque<std::vector<short>>          audio_chunk_channel_;\r
+\r
+       std::queue<safe_ptr<draw_frame>>        ouput_channel_;\r
+       \r
+       const std::wstring                                      filename_;\r
+       \r
+       safe_ptr<draw_frame>                            last_frame_;\r
+\r
+       video_format_desc                                       format_desc_;\r
+\r
 public:\r
-       ffmpeg_producer(const std::wstring& filename, const  std::vector<std::wstring>& params) : filename_(filename), last_frame_(draw_frame(draw_frame::empty())),\r
-               input_(filename), video_decoder_(input_.get_video_codec_context().get()), audio_decoder_(input_.get_audio_codec_context().get(), input_.fps())\r
+       explicit ffmpeg_producer(const std::wstring& filename, const  std::vector<std::wstring>& params) \r
+               : filename_(filename)\r
+               , last_frame_(draw_frame(draw_frame::empty()))\r
+               , input_(filename)\r
+               , video_decoder_(input_.get_video_codec_context().get())\r
+               , audio_decoder_(input_.get_audio_codec_context().get(), input_.fps())\r
        {                               \r
                input_.set_loop(std::find(params.begin(), params.end(), L"LOOP") != params.end());\r
 \r
@@ -103,21 +122,6 @@ public:
        {\r
                return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
        }\r
-\r
-       input                                                           input_;                 \r
-       audio_decoder                                           audio_decoder_;\r
-       video_decoder                                           video_decoder_;\r
-\r
-       std::deque<safe_ptr<write_frame>>       video_frame_channel_;   \r
-       std::deque<std::vector<short>>          audio_chunk_channel_;\r
-\r
-       std::queue<safe_ptr<draw_frame>>        ouput_channel_;\r
-       \r
-       const std::wstring                                      filename_;\r
-       \r
-       safe_ptr<draw_frame>                            last_frame_;\r
-\r
-       video_format_desc                                       format_desc_;\r
 };\r
 \r
 safe_ptr<frame_producer> create_ffmpeg_producer(const std::vector<std::wstring>& params)\r
index 25725288f6e6359523bde1a942d6b5214caa6bbd..1e69e9a61aad00d23c69638beec648804a9fc148 100644 (file)
@@ -30,10 +30,34 @@ extern "C"
 namespace caspar { namespace core { namespace ffmpeg{\r
                \r
 struct input::implementation : boost::noncopyable\r
-{\r
+{                              \r
+       std::shared_ptr<AVFormatContext>        format_context_;        // Destroy this last\r
+\r
+       std::shared_ptr<AVCodecContext>         video_codec_context_;\r
+       std::shared_ptr<AVCodecContext>         audio_codex_context_;\r
+\r
+       tbb::queuing_mutex                                      seek_mutex_;\r
+\r
+       const std::wstring                                      filename_;\r
+\r
+       tbb::atomic<bool>                                       loop_;\r
+       int                                                                     video_s_index_;\r
+       int                                                                     audio_s_index_;\r
+\r
+       tbb::atomic<size_t>     buffer_size_;\r
+       \r
+       tbb::concurrent_bounded_queue<std::shared_ptr<aligned_buffer>> video_packet_buffer_;\r
+       tbb::concurrent_bounded_queue<std::shared_ptr<aligned_buffer>> audio_packet_buffer_;\r
+       \r
+       executor executor_;\r
+\r
        static const size_t BUFFER_SIZE = 2 << 25;\r
 \r
-       implementation(const std::wstring& filename) : video_s_index_(-1), audio_s_index_(-1), filename_(filename)\r
+public:\r
+       explicit implementation(const std::wstring& filename) \r
+               : video_s_index_(-1)\r
+               , audio_s_index_(-1)\r
+               , filename_(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
@@ -178,27 +202,6 @@ struct input::implementation : boost::noncopyable
        {\r
                return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"] Buffer thread";\r
        }\r
-                               \r
-       std::shared_ptr<AVFormatContext>        format_context_;        // Destroy this last\r
-\r
-       tbb::queuing_mutex                                      seek_mutex_;\r
-\r
-       const std::wstring                                      filename_;\r
-\r
-       std::shared_ptr<AVCodecContext>         video_codec_context_;\r
-\r
-       std::shared_ptr<AVCodecContext>         audio_codex_context_;\r
-\r
-       tbb::atomic<bool>                                       loop_;\r
-       int                                                                     video_s_index_;\r
-       int                                                                     audio_s_index_;\r
-       \r
-       tbb::concurrent_bounded_queue<std::shared_ptr<aligned_buffer>> video_packet_buffer_;\r
-       tbb::concurrent_bounded_queue<std::shared_ptr<aligned_buffer>> audio_packet_buffer_;\r
-       \r
-       tbb::atomic<size_t>                     buffer_size_;\r
-\r
-       executor executor_;\r
 };\r
 \r
 input::input(const std::wstring& filename) : impl_(new implementation(filename)){}\r
index 4f39be633ce9f2e87602deba312eb9726bae6795..a2d833dc80c8f0de9392ca6c2d01843b3805455b 100644 (file)
@@ -14,7 +14,7 @@ typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>>
 class input : boost::noncopyable\r
 {\r
 public:\r
-       input(const std::wstring& filename);\r
+       explicit input(const std::wstring& filename);\r
        const std::shared_ptr<AVCodecContext>& get_video_codec_context() const;\r
        const std::shared_ptr<AVCodecContext>& get_audio_codec_context() const;\r
 \r
index 6ca4edf57a3e9a9d9b6c673286d5417ed7521c57..84716f5ac154cfb67b1a1f281fe061b60a9ddd4c 100644 (file)
@@ -88,9 +88,24 @@ pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, size_t width, size_
 }\r
 \r
 struct video_decoder::implementation : boost::noncopyable\r
-{\r
-       implementation(AVCodecContext* codec_context) : codec_context_(codec_context), width_(codec_context_->width), height_(codec_context_->height), \r
-               pix_fmt_(codec_context_->pix_fmt), desc_(get_pixel_format_desc(pix_fmt_, width_, height_))\r
+{      \r
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+       std::shared_ptr<SwsContext> sws_context_;\r
+\r
+       AVCodecContext* codec_context_;\r
+\r
+       int width_;\r
+       int height_;\r
+       PixelFormat pix_fmt_;\r
+       pixel_format_desc desc_;\r
+\r
+public:\r
+       explicit implementation(AVCodecContext* codec_context) \r
+               : codec_context_(codec_context)\r
+               , width_(codec_context_->width)\r
+               , height_(codec_context_->height)\r
+               , pix_fmt_(codec_context_->pix_fmt)\r
+               , desc_(get_pixel_format_desc(pix_fmt_, width_, height_))\r
        {\r
                if(desc_.pix_fmt == pixel_format::invalid)\r
                {\r
@@ -158,19 +173,9 @@ struct video_decoder::implementation : boost::noncopyable
        {\r
                frame_processor_ = frame_processor;             \r
                double frame_rate = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
-               if(abs(frame_rate - frame_processor->get_video_format_desc().actual_fps) > std::numeric_limits<double>::min())\r
+               if(abs(frame_rate - frame_processor->get_video_format_desc().fps) > std::numeric_limits<double>::min())\r
                        BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid video framerate."));\r
        }\r
-       \r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-       std::shared_ptr<SwsContext> sws_context_;\r
-\r
-       AVCodecContext* codec_context_;\r
-\r
-       int width_;\r
-       int height_;\r
-       PixelFormat pix_fmt_;\r
-       pixel_format_desc desc_;\r
 };\r
 \r
 video_decoder::video_decoder(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
index b2c9505eed0064d5bd532eb4fa2a147a085ef1c2..b4278f1e31b91fb86e4e529eb1a82e186607ce5b 100644 (file)
@@ -13,7 +13,7 @@ typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>>
 class video_decoder : boost::noncopyable\r
 {\r
 public:\r
-       video_decoder(AVCodecContext* codec_context);\r
+       explicit video_decoder(AVCodecContext* codec_context);\r
        safe_ptr<write_frame> execute(const aligned_buffer& video_packet);      \r
        void initialize(const safe_ptr<frame_processor_device>& frame_processor);\r
 private:\r
index dbe2156b7bdae03b82fa76885857b878a541a518..32dd3fe1ed5d4ebca67c8fd89c5c7e070997c05e 100644 (file)
@@ -17,7 +17,8 @@ namespace caspar { namespace core { namespace flash {
 struct cg_producer::implementation : boost::noncopyable\r
 {\r
 public:\r
-       implementation() : flash_producer_(flash_producer(configuration::template_folder()+TEXT("cg.fth.18"))){}\r
+       implementation() \r
+               : flash_producer_(flash_producer(configuration::template_folder()+TEXT("cg.fth.18"))){}\r
 \r
        void clear()\r
        {\r
index 8f67cfab9b478beef1c6ab73be4ccf65e4d7bb02..cc8d65fc7d07e9d18408ed0c9ba09c58b9ad2d86 100644 (file)
@@ -11,7 +11,7 @@ class cg_producer : public frame_producer
 public:\r
        static const unsigned int DEFAULT_LAYER = 5000;\r
 \r
-       cg_producer();\r
+       explicit cg_producer();\r
        cg_producer(cg_producer&& other);\r
        \r
        virtual safe_ptr<draw_frame> receive();\r
index 523b5f329b90fad033155867ec5d431217081c83..f7fc268ae5cd69780e2c54101fbe6273692e0e68 100644 (file)
@@ -46,10 +46,26 @@ extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule;
 \r
 class flash_renderer\r
 {\r
+       std::wstring filename_;\r
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+       video_format_desc format_desc_;\r
+       \r
+       BYTE* bmp_data_;        \r
+       std::shared_ptr<void> hdc_;\r
+       std::shared_ptr<void> bmp_;\r
+\r
+       CComObject<caspar::flash::FlashAxContainer>* ax_;\r
+       safe_ptr<draw_frame> head_;\r
+\r
 public:\r
        flash_renderer(const std::shared_ptr<frame_processor_device>& frame_processor, const std::wstring& filename) \r
-               : head_(draw_frame::empty()), bmp_data_(nullptr), ax_(nullptr), filename_(filename), hdc_(CreateCompatibleDC(0), DeleteDC), frame_processor_(frame_processor), \r
-                       format_desc_(frame_processor->get_video_format_desc())\r
+               : head_(draw_frame::empty())\r
+               , bmp_data_(nullptr)\r
+               , ax_(nullptr)\r
+               , filename_(filename)\r
+               , hdc_(CreateCompatibleDC(0), DeleteDC)\r
+               , frame_processor_(frame_processor)\r
+               , format_desc_(frame_processor->get_video_format_desc())\r
        {\r
                CASPAR_LOG(info) << print() << L" Started";\r
                \r
@@ -109,7 +125,7 @@ public:
                        return draw_frame::empty();\r
 \r
                auto frame = render_simple_frame();\r
-               if(ax_->GetFPS()/2.0 - format_desc_.actual_fps >= 0.0)\r
+               if(format_desc_.mode != video_mode::progressive && ax_->GetFPS()/2.0 - format_desc_.fps >= 0.0)\r
                        frame = draw_frame::interlace(frame, render_simple_frame(), format_desc_.mode);\r
                return frame;\r
        }\r
@@ -138,23 +154,23 @@ private:
 \r
                return head_;\r
        }\r
-\r
-       std::wstring filename_;\r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-       video_format_desc format_desc_;\r
-       \r
-       BYTE* bmp_data_;\r
-       \r
-       std::shared_ptr<void> hdc_;\r
-       std::shared_ptr<void> bmp_;\r
-\r
-       CComObject<caspar::flash::FlashAxContainer>* ax_;\r
-       safe_ptr<draw_frame> head_;\r
 };\r
 \r
 struct flash_producer::implementation\r
 {      \r
-       implementation(const std::wstring& filename) : filename_(filename), tail_(draw_frame::empty())\r
+       safe_ptr<draw_frame> tail_;\r
+       tbb::concurrent_bounded_queue<safe_ptr<draw_frame>> frame_buffer_;\r
+       executor executor_;\r
+\r
+       std::shared_ptr<flash_renderer> renderer_;\r
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+       \r
+       std::wstring print() const{ return L"flash[" + boost::filesystem::wpath(filename_).filename() + L"]"; } \r
+       std::wstring filename_;\r
+\r
+       implementation(const std::wstring& filename) \r
+               : filename_(filename)\r
+               , tail_(draw_frame::empty())\r
        {       \r
                if(!boost::filesystem::exists(filename))\r
                        BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename)));\r
@@ -205,7 +221,7 @@ struct flash_producer::implementation
        virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
-               frame_buffer_.set_capacity(static_cast<size_t>(frame_processor->get_video_format_desc().actual_fps/2.0));\r
+               frame_buffer_.set_capacity(static_cast<size_t>(frame_processor->get_video_format_desc().fps/2.0));\r
                while(frame_buffer_.try_push(draw_frame::empty())){}\r
                executor_.start();\r
        }\r
@@ -228,16 +244,6 @@ struct flash_producer::implementation
                        }\r
                });\r
        }\r
-\r
-       safe_ptr<draw_frame> tail_;\r
-       tbb::concurrent_bounded_queue<safe_ptr<draw_frame>> frame_buffer_;\r
-       executor executor_;\r
-\r
-       std::shared_ptr<flash_renderer> renderer_;\r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-       \r
-       std::wstring print() const{ return L"flash[" + boost::filesystem::wpath(filename_).filename() + L"]"; } \r
-       std::wstring filename_;\r
 };\r
 \r
 flash_producer::flash_producer(flash_producer&& other) : impl_(std::move(other.impl_)){}\r
index 5d226fe7157ce40fd6c4c0f14545ff00ca02fdac..25574b0f4eb1081a0746aca084bc404167cc0ebd 100644 (file)
@@ -28,10 +28,9 @@ namespace caspar { namespace core { namespace flash {
 class flash_producer : public frame_producer\r
 {\r
 public:\r
+       explicit flash_producer(const std::wstring& filename);\r
        flash_producer(flash_producer&& other);\r
 \r
-       flash_producer(const std::wstring& filename);\r
-\r
        virtual safe_ptr<draw_frame> receive();\r
        virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor);\r
        virtual std::wstring print() const;\r
index 3749ff13a8f52c87642ed47b52e370ddc0285a85..943be5ffbb68e8b75fa8ecca6d8c6011eab32d80 100644 (file)
@@ -16,9 +16,18 @@ using namespace boost::assign;
 namespace caspar { namespace core { namespace image{\r
 \r
 struct image_producer : public frame_producer\r
-{\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
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+       std::wstring filename_;\r
+       safe_ptr<draw_frame> frame_;\r
+\r
+       image_producer(image_producer&& other) \r
+               : frame_processor_(std::move(other.frame_processor_))\r
+               , filename_(std::move(other.filename_))\r
+               , frame_(draw_frame::empty()){}\r
+\r
+       image_producer(const std::wstring& filename) \r
+               : filename_(filename), frame_(draw_frame::empty())      {}\r
        \r
        virtual safe_ptr<draw_frame> receive(){return frame_;}\r
 \r
@@ -36,10 +45,6 @@ struct image_producer : public frame_producer
        {\r
                return L"image_producer. filename: " + filename_;\r
        }\r
-       \r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-       std::wstring filename_;\r
-       safe_ptr<draw_frame> frame_;\r
 };\r
 \r
 safe_ptr<frame_producer> create_image_producer(const  std::vector<std::wstring>& params)\r
index 72cd0726bcfbda8cbee0a1b25832c7597fc954f4..b32cdc568873be8070443b46c93f37c277cee36f 100644 (file)
 namespace caspar { namespace core {\r
 \r
 struct layer::implementation : boost::noncopyable\r
-{              \r
-       implementation(size_t index) : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()), index_(index) {}\r
+{      \r
+       std::wstring print() const { return L"layer[" + boost::lexical_cast<std::wstring>(index_) + L"]"; }\r
+                               \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
+       const size_t                            index_;\r
+\r
+public:\r
+       implementation(size_t index) \r
+               : foreground_(frame_producer::empty())\r
+               , background_(frame_producer::empty())\r
+               , last_frame_(draw_frame::empty())\r
+               , index_(index) {}\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, bool autoplay)\r
        {                       \r
@@ -94,14 +107,6 @@ struct layer::implementation : boost::noncopyable
 \r
                return last_frame_;\r
        }\r
-\r
-       std::wstring print() const { return L"layer[" + boost::lexical_cast<std::wstring>(index_) + L"]"; }\r
-                               \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
-       const size_t                            index_;\r
 };\r
 \r
 layer::layer(size_t index) : impl_(new implementation(index)){}\r
index b6c6b1aeb1f24d1bcb65326c2aab73cfd336b417..a71cd15404096db4acc63041d87cefc8e601ffa1 100644 (file)
 namespace caspar { namespace core {    \r
 \r
 struct transition_producer::implementation : boost::noncopyable\r
-{\r
-       implementation(const safe_ptr<frame_producer>& dest, const transition_info& info) : current_frame_(0), info_(info), \r
-               dest_producer_(dest), source_producer_(frame_producer::empty())\r
+{      \r
+       unsigned short                          current_frame_;\r
+       \r
+       const transition_info           info_;\r
+       \r
+       safe_ptr<frame_producer>        dest_producer_;\r
+       safe_ptr<frame_producer>        source_producer_;\r
+\r
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+\r
+       implementation(const safe_ptr<frame_producer>& dest, const transition_info& info) \r
+               : current_frame_(0)\r
+               , info_(info)\r
+               , dest_producer_(dest)\r
+               , source_producer_(frame_producer::empty())\r
        {}\r
                \r
        safe_ptr<frame_producer> get_following_producer() const\r
@@ -47,11 +59,6 @@ struct transition_producer::implementation : boost::noncopyable
        }\r
                \r
        safe_ptr<draw_frame> receive()\r
-       {\r
-               return render_frame();\r
-       }\r
-\r
-       safe_ptr<draw_frame> render_frame()\r
        {\r
                if(current_frame_++ >= info_.duration)\r
                        return draw_frame::eof();\r
@@ -67,7 +74,7 @@ struct transition_producer::implementation : boost::noncopyable
 \r
                return compose(dest, source);\r
        }\r
-\r
+       \r
        safe_ptr<draw_frame> render_sub_frame(safe_ptr<frame_producer>& producer)\r
        {\r
                if(producer == frame_producer::empty())\r
@@ -150,14 +157,6 @@ struct transition_producer::implementation : boost::noncopyable
        {\r
                return L"transition[" + (source_producer_->print()) + L" -> " + (dest_producer_->print()) + L"]";\r
        }\r
-       \r
-       safe_ptr<frame_producer>        source_producer_;\r
-       safe_ptr<frame_producer>        dest_producer_;\r
-       \r
-       unsigned short                          current_frame_;\r
-       \r
-       const transition_info           info_;\r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
 };\r
 \r
 transition_producer::transition_producer(transition_producer&& other) : impl_(std::move(other.impl_)){}\r
index a5640841d4c5e6404a1e35255ce1bbbeb221392a..4a0c972e84c51feb2ce9d28e068067c23f6782e2 100644 (file)
@@ -60,10 +60,9 @@ struct transition_info
 class transition_producer : public frame_producer\r
 {\r
 public:\r
+       explicit transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
        transition_producer(transition_producer&& other);\r
 \r
-       transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
-\r
        virtual safe_ptr<draw_frame> receive();\r
 \r
        virtual safe_ptr<frame_producer> get_following_producer() const;\r
index 39777c64a58b23393fafb766ec7f36b55ae66716..15848687db7e634cc9fdd25c317ff35ef33b2394 100644 (file)
@@ -8,20 +8,21 @@
   </paths>\r
   <channels>\r
     <channel>\r
-      <videomode>720p2500</videomode>\r
+      <videomode>PAL</videomode>\r
       <consumers>\r
-        <ogl>\r
+        <!--ogl>\r
           <device>0</device>\r
           <stretch>uniform</stretch>\r
           <windowed>true</windowed>\r
         </ogl>\r
-        <audio/>\r
-        <!--decklink>          \r
-        </decklink>\r
+        <audio/-->\r
+        <!--decklink>\r
+          <device>1</device>\r
+        </decklink-->\r
         <bluefish>\r
           <device>1</device> \r
           <embedded-audio>true</embedded-audio>\r
-        </bluefish-->\r
+        </bluefish>\r
       </consumers>\r
     </channel>\r
   </channels>\r