]> git.sesse.net Git - casparcg/commitdiff
com_context: Removed.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 31 Jan 2012 23:33:31 +0000 (23:33 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 31 Jan 2012 23:33:31 +0000 (23:33 +0000)
defer: Added to emulate std::async with launch::sync.
read_frame: Removed.
mixer: Simplified.

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

16 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/concurrency/com_context.h [deleted file]
common/concurrency/defer.h [new file with mode: 0644]
core/core.vcxproj
core/core.vcxproj.filters
core/mixer/gpu/device_buffer.cpp
core/mixer/gpu/image/image_mixer.cpp
core/mixer/gpu/image/image_mixer.h
core/mixer/gpu/read_frame.cpp [deleted file]
core/mixer/gpu/read_frame.h [deleted file]
core/mixer/gpu/write_frame.cpp
core/mixer/image/image_mixer.h
core/mixer/mixer.cpp
modules/decklink/producer/decklink_producer.cpp
shell/casparcg.config

index 55ea0db59b338404ff1259505479388f5f964036..98c0af8e17f8c9e4dd26e88b0199cf4543b213b5 100644 (file)
   <ItemGroup>\r
     <ClInclude Include="assert.h" />\r
     <ClInclude Include="compiler\vs\disable_silly_warnings.h" />\r
-    <ClInclude Include="concurrency\com_context.h" />\r
+    <ClInclude Include="concurrency\defer.h" />\r
     <ClInclude Include="concurrency\executor.h" />\r
     <ClInclude Include="concurrency\lock.h" />\r
     <ClInclude Include="diagnostics\graph.h" />\r
index 8cc31b2e08298878c730750448ec954e739db48d..03c630d7c7e7317bb476cad4b4a4dc0ac4ace342 100644 (file)
@@ -97,9 +97,6 @@
     <ClInclude Include="os\windows\system_info.h">\r
       <Filter>source\os\windows</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="concurrency\com_context.h">\r
-      <Filter>source\concurrency</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="memory\memshfl.h">\r
       <Filter>source\memory</Filter>\r
     </ClInclude>\r
     <ClInclude Include="reactive.h">\r
       <Filter>source</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="concurrency\defer.h">\r
+      <Filter>source\concurrency</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/common/concurrency/com_context.h b/common/concurrency/com_context.h
deleted file mode 100644 (file)
index 7303af3..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "executor.h"\r
-\r
-#include "../log.h"\r
-#include "../exception/exceptions.h"\r
-\r
-#define NOMINMAX\r
-#define WIN32_LEAN_AND_MEAN\r
-\r
-#include <Windows.h>\r
-\r
-#include <boost/noncopyable.hpp>\r
-#include <boost/thread/future.hpp>\r
-\r
-#include <functional>\r
-\r
-namespace caspar {\r
-\r
-template<typename T>\r
-class com_context : public executor\r
-{\r
-       std::unique_ptr<T> instance_;\r
-public:\r
-       com_context(const std::wstring& name) : executor(name)\r
-       {\r
-               executor::begin_invoke([]\r
-               {\r
-                       ::CoInitialize(nullptr);\r
-               });\r
-       }\r
-\r
-       ~com_context()\r
-       {\r
-               if(!executor::begin_invoke([&]\r
-               {\r
-                       instance_.reset(nullptr);\r
-                       ::CoUninitialize();\r
-               }).timed_wait(boost::posix_time::milliseconds(500)))\r
-               {\r
-                       CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources.";\r
-               }\r
-       }\r
-       \r
-       void reset(const std::function<T*()>& factory = nullptr)\r
-       {\r
-               executor::invoke([&]\r
-               {\r
-                       instance_.reset();\r
-                       if(factory)\r
-                               instance_.reset(factory());\r
-               });\r
-       }\r
-\r
-       T& operator*() const \r
-       {\r
-               if(instance_ == nullptr)\r
-                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
-\r
-               return *instance_.get();\r
-       }  // noexcept\r
-\r
-       T* operator->() const \r
-       {\r
-               if(instance_ == nullptr)\r
-                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
-               return instance_.get();\r
-       }  // noexcept\r
-\r
-       T* get() const\r
-       {\r
-               return instance_.get();\r
-       }  // noexcept\r
-\r
-       operator bool() const {return get() != nullptr;}\r
-};\r
-\r
-}
\ No newline at end of file
diff --git a/common/concurrency/defer.h b/common/concurrency/defer.h
new file mode 100644 (file)
index 0000000..6c8d0e2
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once\r
+\r
+#include <functional>\r
+#include <memory>\r
+\r
+#include <boost/thread/future.hpp>\r
+\r
+namespace caspar {\r
+               \r
+template<typename F>\r
+auto defer(F&& f) -> boost::unique_future<decltype(f())>\r
+{      \r
+       typedef boost::promise<decltype(f())> promise_t;\r
+       auto p = new promise_t();\r
+\r
+       auto func = [=](promise_t&) mutable\r
+       {\r
+               std::unique_ptr<promise_t> guard(p);\r
+               p->set_value(f());\r
+       };\r
+\r
+       p->set_wait_callback(std::function<void(promise_t&)>(func));\r
+\r
+       return p->get_future();\r
+}\r
+\r
+\r
+}
\ No newline at end of file
index be615ac6bc1136508c91a8776ca7c248835d1c82..5f7989747e01d50d426dd11a28c57b3174d8153b 100644 (file)
     <ClInclude Include="mixer\gpu\image\image_mixer.h" />\r
     <ClInclude Include="mixer\gpu\image\image_shader.h" />\r
     <ClInclude Include="mixer\gpu\accelerator.h" />\r
-    <ClInclude Include="mixer\gpu\read_frame.h" />\r
     <ClInclude Include="mixer\gpu\shader.h" />\r
     <ClInclude Include="mixer\gpu\write_frame.h" />\r
     <ClInclude Include="mixer\image\blend_modes.h" />\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="mixer\gpu\read_frame.cpp">\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
-    </ClCompile>\r
     <ClCompile Include="mixer\gpu\shader.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
index d880d0e2a1a7dc0ba5899d71ad49a6dfc6abdae4..c9a26903a85060cb048b3480da32af5cec11dc31 100644 (file)
     <ClInclude Include="frame\draw_frame.h">\r
       <Filter>source\frame</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="mixer\gpu\read_frame.h">\r
-      <Filter>source\mixer\gpu</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="mixer\gpu\write_frame.h">\r
       <Filter>source\mixer\gpu</Filter>\r
     </ClInclude>\r
     <ClCompile Include="frame\data_frame.cpp">\r
       <Filter>source\frame</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="mixer\gpu\read_frame.cpp">\r
-      <Filter>source\mixer\gpu</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="mixer\gpu\write_frame.cpp">\r
       <Filter>source\mixer\gpu</Filter>\r
     </ClCompile>\r
index 1db0f1b40082afd71888d197166a0fee5698581c..7f2748ae518d26e495c4f7ed5f9120306abd1c27 100644 (file)
@@ -133,6 +133,7 @@ public:
                        GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], TYPE[stride_], NULL));\r
                        GL(glBindTexture(GL_TEXTURE_2D, 0));\r
                        dest->unbind();\r
+                       GL(glFlush());\r
                }, high_priority);\r
        }\r
 };\r
index 017ff70860a2972216e7b4dc87f89829d875ccf6..0d1de2d68d5d9e4e524b2a3bc40461e383366b97 100644 (file)
@@ -31,6 +31,7 @@
 #include "../device_buffer.h"\r
 \r
 #include <common/gl/gl_check.h>\r
+#include <common/concurrency/defer.h>\r
 \r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/pixel_format.h>\r
@@ -74,9 +75,9 @@ public:
        {\r
        }\r
        \r
-       boost::unique_future<safe_ptr<host_buffer>> operator()(std::vector<layer> layers, const video_format_desc& format_desc)\r
+       boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>> operator()(std::vector<layer> layers, const video_format_desc& format_desc)\r
        {       \r
-               return ogl_->begin_invoke([=]() mutable -> safe_ptr<host_buffer>\r
+               boost::shared_future<safe_ptr<host_buffer>> buffer = ogl_->begin_invoke([=]() mutable -> safe_ptr<host_buffer>\r
                {\r
                        auto draw_buffer = create_mixer_buffer(4, format_desc);\r
 \r
@@ -109,6 +110,12 @@ public:
                        draw_buffer->copy_to(result);                                                   \r
                        return result;\r
                });\r
+\r
+               return defer([=]() mutable -> safe_ptr<boost::iterator_range<const uint8_t*>>\r
+               {\r
+                       auto ptr = reinterpret_cast<const uint8_t*>(buffer.get()->data()); // ->data() can block OpenGL thread, defer it as long as possible.\r
+                       return make_safe<boost::iterator_range<const uint8_t*>>(ptr, ptr + buffer.get()->size());\r
+               });\r
        }\r
 \r
 private:\r
@@ -278,7 +285,7 @@ public:
        {               \r
        }\r
        \r
-       boost::unique_future<safe_ptr<host_buffer>> render(const video_format_desc& format_desc)\r
+       boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>> render(const video_format_desc& format_desc)\r
        {\r
                return renderer_(std::move(layers_), format_desc);\r
        }\r
@@ -288,7 +295,7 @@ image_mixer::image_mixer(const safe_ptr<accelerator>& ogl) : impl_(new impl(ogl)
 void image_mixer::begin(draw_frame& frame){impl_->begin(frame);}\r
 void image_mixer::visit(write_frame& frame){impl_->visit(frame);}\r
 void image_mixer::end(){impl_->end();}\r
-boost::unique_future<safe_ptr<host_buffer>> image_mixer::operator()(const video_format_desc& format_desc){return impl_->render(format_desc);}\r
+boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>> image_mixer::operator()(const video_format_desc& format_desc){return impl_->render(format_desc);}\r
 void image_mixer::begin_layer(blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
 void image_mixer::end_layer(){impl_->end_layer();}\r
 \r
index 14f4d786c4982c123f4f48a6ee469ee6e9d124fd..2c57b21586ca3d5b4d7903583b72ea733b0998e9 100644 (file)
@@ -45,7 +45,7 @@ public:
        void begin_layer(blend_mode blend_mode);\r
        void end_layer();\r
                \r
-       virtual boost::unique_future<safe_ptr<class host_buffer>> operator()(const struct video_format_desc& format_desc) override;\r
+       virtual boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>> operator()(const struct video_format_desc& format_desc) override;\r
                \r
 private:\r
        struct impl;\r
diff --git a/core/mixer/gpu/read_frame.cpp b/core/mixer/gpu/read_frame.cpp
deleted file mode 100644 (file)
index 7522944..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#include "../../stdafx.h"\r
-\r
-#include "read_frame.h"\r
-\r
-#include "host_buffer.h"\r
-\r
-#include "../../video_format.h"\r
-#include "../../frame/pixel_format.h"\r
-       \r
-namespace caspar { namespace core {\r
-                                                                                                                                                                                                                                                                                                                       \r
-struct read_frame::impl : boost::noncopyable\r
-{\r
-       boost::unique_future<safe_ptr<gpu::host_buffer>>        image_data_;\r
-       const audio_buffer                                                                      audio_data_;\r
-       const video_format_desc                                                         video_desc_;\r
-       pixel_format_desc                                                                       pixel_desc_;\r
-       const void*                                                                                     tag_;\r
-\r
-public:\r
-       impl(const void* tag, boost::unique_future<safe_ptr<gpu::host_buffer>>&& image_data, audio_buffer&& audio_data, const video_format_desc& format_desc) \r
-               : tag_(tag)\r
-               , image_data_(std::move(image_data))\r
-               , audio_data_(std::move(audio_data))\r
-               , video_desc_(format_desc)\r
-               , pixel_desc_(core::pixel_format::bgra)\r
-       {\r
-               pixel_desc_.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4));\r
-       }       \r
-       \r
-       const boost::iterator_range<const uint8_t*> image_data(int)\r
-       {\r
-               auto ptr = static_cast<const uint8_t*>(image_data_.get()->data());\r
-               return boost::iterator_range<const uint8_t*>(ptr, ptr + image_data_.get()->size());\r
-       }\r
-};\r
-\r
-read_frame::read_frame(const void* tag, boost::unique_future<safe_ptr<gpu::host_buffer>>&& image_data, audio_buffer&& audio_data, const video_format_desc& format_desc) \r
-       : impl_(new impl(tag, std::move(image_data), std::move(audio_data), format_desc)){}\r
-const boost::iterator_range<const uint8_t*> read_frame::image_data(int index) const{   return impl_->image_data(index);}\r
-const audio_buffer& read_frame::audio_data() const{    return impl_->audio_data_;}\r
-const pixel_format_desc& read_frame::get_pixel_format_desc() const{    return impl_->pixel_desc_;}\r
-double read_frame::get_frame_rate() const {return impl_->video_desc_.fps;}\r
-int read_frame::width() const {return impl_->video_desc_.width;}\r
-int read_frame::height() const {return impl_->video_desc_.height;}\r
-const void* read_frame::tag() const{return impl_->tag_;}\r
-\r
-//#include <tbb/scalable_allocator.h>\r
-//#include <tbb/parallel_for.h>\r
-//#include <tbb/enumerable_thread_specific.h>\r
-//#define              CACHED_BUFFER_SIZE      4096    \r
-//typedef              unsigned int            UINT;\r
-//\r
-//struct cache_buffer\r
-//{\r
-//     cache_buffer() : data(scalable_aligned_malloc(CACHED_BUFFER_SIZE, 64)){}\r
-//     ~cache_buffer() {scalable_aligned_free(data);}\r
-//     void* data;\r
-//};\r
-//\r
-//void CopyFrame( void * pSrc, void * pDest, UINT width, UINT height, UINT pitch );\r
-//\r
-//void* copy_frame(void* dest, const safe_ptr<const data_frame>& frame)\r
-//{\r
-//     auto src                = frame->image_data().begin();\r
-//     auto height             = 720;\r
-//     auto width4             = frame->image_data().size()/height;\r
-//\r
-//     CASPAR_ASSERT(frame->image_data().size() % height == 0);\r
-//                     \r
-//     tbb::affinity_partitioner ap;\r
-//     tbb::parallel_for(tbb::blocked_range<int>(0, height), [&](tbb::blocked_range<int>& r)\r
-//     {\r
-//             CopyFrame(const_cast<uint8_t*>(src)+r.begin()*width4, reinterpret_cast<uint8_t*>(dest)+r.begin()*width4, width4, r.size(), width4);\r
-//     }, ap);\r
-//\r
-//     return dest;\r
-//}\r
-//\r
-////  CopyFrame( )\r
-////\r
-////  COPIES VIDEO FRAMES FROM USWC MEMORY TO WB SYSTEM MEMORY VIA CACHED BUFFER\r
-////    ASSUMES PITCH IS A MULTIPLE OF 64B CACHE LINE SIZE, WIDTH MAY NOT BE\r
-//// http://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers/\r
-//void CopyFrame( void * pSrc, void * pDest, UINT width, UINT height, UINT pitch )\r
-//{\r
-//     tbb::enumerable_thread_specific<cache_buffer> cache_buffers;\r
-//\r
-//     void *          pCacheBlock = cache_buffers.local().data;\r
-//\r
-//     __m128i         x0, x1, x2, x3;\r
-//     __m128i         *pLoad;\r
-//     __m128i         *pStore;\r
-//     __m128i         *pCache;\r
-//     UINT            x, y, yLoad, yStore;\r
-//     UINT            rowsPerBlock;\r
-//     UINT            width64;\r
-//     UINT            extraPitch;     \r
-//\r
-//     rowsPerBlock = CACHED_BUFFER_SIZE / pitch;\r
-//     width64 = (width + 63) & ~0x03f;\r
-//     extraPitch = (pitch - width64) / 16;\r
-//\r
-//     pLoad  = (__m128i *)pSrc;\r
-//     pStore = (__m128i *)pDest;\r
-//\r
-//     //  COPY THROUGH 4KB CACHED BUFFER\r
-//     for( y = 0; y < height; y += rowsPerBlock  )\r
-//     {\r
-//             //  ROWS LEFT TO COPY AT END\r
-//             if( y + rowsPerBlock > height )\r
-//                     rowsPerBlock = height - y;\r
-//\r
-//             pCache = (__m128i *)pCacheBlock;\r
-//\r
-//             _mm_mfence();                           \r
-//             \r
-//             // LOAD ROWS OF PITCH WIDTH INTO CACHED BLOCK\r
-//             for( yLoad = 0; yLoad < rowsPerBlock; yLoad++ )\r
-//             {\r
-//                     // COPY A ROW, CACHE LINE AT A TIME\r
-//                     for( x = 0; x < pitch; x +=64 )\r
-//                     {\r
-//                             x0 = _mm_stream_load_si128( pLoad +0 );\r
-//                             x1 = _mm_stream_load_si128( pLoad +1 );\r
-//                             x2 = _mm_stream_load_si128( pLoad +2 );\r
-//                             x3 = _mm_stream_load_si128( pLoad +3 );\r
-//\r
-//                             _mm_store_si128( pCache +0,     x0 );\r
-//                             _mm_store_si128( pCache +1, x1 );\r
-//                             _mm_store_si128( pCache +2, x2 );\r
-//                             _mm_store_si128( pCache +3, x3 );\r
-//\r
-//                             pCache += 4;\r
-//                             pLoad += 4;\r
-//                     }\r
-//             }\r
-//\r
-//             _mm_mfence();\r
-//\r
-//             pCache = (__m128i *)pCacheBlock;\r
-//\r
-//             // STORE ROWS OF FRAME WIDTH FROM CACHED BLOCK\r
-//             for( yStore = 0; yStore < rowsPerBlock; yStore++ )\r
-//             {\r
-//                     // copy a row, cache line at a time\r
-//                     for( x = 0; x < width64; x +=64 )\r
-//                     {\r
-//                             x0 = _mm_load_si128( pCache );\r
-//                             x1 = _mm_load_si128( pCache +1 );\r
-//                             x2 = _mm_load_si128( pCache +2 );\r
-//                             x3 = _mm_load_si128( pCache +3 );\r
-//\r
-//                             _mm_stream_si128( pStore,       x0 );\r
-//                             _mm_stream_si128( pStore +1, x1 );\r
-//                             _mm_stream_si128( pStore +2, x2 );\r
-//                             _mm_stream_si128( pStore +3, x3 );\r
-//\r
-//                             pCache += 4;\r
-//                             pStore += 4;\r
-//                     }\r
-//\r
-//                     pCache += extraPitch;\r
-//                     pStore += extraPitch;\r
-//             }\r
-//     }\r
-//}\r
-\r
-}}
\ No newline at end of file
diff --git a/core/mixer/gpu/read_frame.h b/core/mixer/gpu/read_frame.h
deleted file mode 100644 (file)
index a263ca8..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "../../frame/data_frame.h"\r
-\r
-#include <common/memory/safe_ptr.h>\r
-#include <common/forward.h>\r
-#include <common/exception/exceptions.h>\r
-\r
-#include <core/mixer/audio/audio_mixer.h>\r
-\r
-#include <boost/noncopyable.hpp>\r
-#include <boost/range/iterator_range.hpp>\r
-\r
-#include <stdint.h>\r
-#include <memory>\r
-#include <vector>\r
-\r
-FORWARD1(boost, template<typename> class unique_future);\r
-FORWARD3(caspar, core, gpu, class host_buffer);\r
-\r
-namespace caspar { namespace core {\r
-       \r
-class read_frame sealed : public data_frame\r
-{\r
-public:\r
-       read_frame(const void* tag, boost::unique_future<safe_ptr<gpu::host_buffer>>&& image_data, audio_buffer&& audio_data, const struct video_format_desc& format_desc);\r
-       \r
-       // data_frame\r
-\r
-       virtual const struct  pixel_format_desc& get_pixel_format_desc() const override;\r
-\r
-       virtual const boost::iterator_range<const uint8_t*> image_data(int index) const override;\r
-       virtual const audio_buffer& audio_data() const override;\r
-       \r
-       virtual double     get_frame_rate() const override;\r
-\r
-       virtual int width() const override;\r
-       virtual int height() const override;\r
-\r
-       virtual const boost::iterator_range<uint8_t*> image_data(int index) override\r
-       {\r
-               BOOST_THROW_EXCEPTION(invalid_operation());\r
-       }\r
-       virtual audio_buffer& audio_data() override\r
-       {\r
-               BOOST_THROW_EXCEPTION(invalid_operation());\r
-       }\r
-               \r
-       virtual const void* tag() const override;       \r
-private:\r
-       struct impl;\r
-       std::shared_ptr<impl> impl_;\r
-};\r
-\r
-}}
\ No newline at end of file
index 6519e74dfeb0d64c8e80a2377614767bf22659ac..68241feecf762fc5acbb70fed6272251beca757e 100644 (file)
@@ -82,14 +82,11 @@ write_frame::write_frame(const safe_ptr<gpu::accelerator>& ogl, const void* tag,
 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
 write_frame& write_frame::operator=(write_frame&& other)\r
 {\r
-       write_frame temp(std::move(other));\r
-       temp.swap(*this);\r
+       impl_ = std::move(other.impl_);\r
        return *this;\r
 }\r
 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
-\r
 void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
-\r
 const  pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
 const boost::iterator_range<const uint8_t*> write_frame::image_data(int index) const{return impl_->image_data(index);}\r
 const audio_buffer& write_frame::audio_data() const{return impl_->audio_data_;}\r
index c9c43520d30f174f15cc2dde8dced2bfcaedf3f2..5b006ea521fd67753c17910920d7124515085045 100644 (file)
@@ -29,7 +29,6 @@
 #include <core/frame/frame_visitor.h>\r
 \r
 FORWARD1(boost, template<typename> class unique_future);\r
-FORWARD3(caspar, core, gpu, class host_buffer);\r
 \r
 namespace caspar { namespace core {\r
        \r
@@ -44,7 +43,7 @@ struct image_mixer : public frame_visitor
        virtual void begin_layer(blend_mode blend_mode) = 0;\r
        virtual void end_layer() = 0;\r
                \r
-       virtual boost::unique_future<safe_ptr<gpu::host_buffer>> operator()(const struct video_format_desc& format_desc) = 0;\r
+       virtual boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>> operator()(const struct video_format_desc& format_desc) = 0;\r
 };\r
 \r
 }}
\ No newline at end of file
index c3f012990b49bc55fdcd1520a2665d6c42801ada..3c2bb2f15d38e72d7338f35f3ca246b5ac4c7f16 100644 (file)
@@ -30,7 +30,6 @@
 \r
 #include "gpu/image/image_mixer.h"\r
 #include "gpu/accelerator.h"\r
-#include "gpu/read_frame.h"\r
 #include "gpu/write_frame.h"\r
 \r
 #include <common/env.h>\r
 #include <vector>\r
 \r
 namespace caspar { namespace core {\r
+\r
+struct mixed_frame : public data_frame\r
+{\r
+       mutable boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>>   image_data_;\r
+       const audio_buffer                                                                                                                              audio_data_;\r
+       const video_format_desc                                                                                                                 video_desc_;\r
+       pixel_format_desc                                                                                                                               pixel_desc_;\r
+       const void*                                                                                                                                             tag_;\r
+\r
+public:\r
+       mixed_frame(const void* tag, boost::unique_future<safe_ptr<boost::iterator_range<const uint8_t*>>>&& image_data, audio_buffer&& audio_data, const video_format_desc& format_desc) \r
+               : tag_(tag)\r
+               , image_data_(std::move(image_data))\r
+               , audio_data_(std::move(audio_data))\r
+               , video_desc_(format_desc)\r
+               , pixel_desc_(core::pixel_format::bgra)\r
+       {\r
+               pixel_desc_.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4));\r
+       }       \r
+       \r
+       const boost::iterator_range<const uint8_t*> image_data(int index = 0) const override\r
+       {\r
+               return *image_data_.get();\r
+       }\r
+               \r
+       const boost::iterator_range<uint8_t*> image_data(int) override\r
+       {\r
+               BOOST_THROW_EXCEPTION(invalid_operation());\r
+       }\r
+       \r
+       virtual const struct pixel_format_desc& get_pixel_format_desc() const override\r
+       {\r
+               return pixel_desc_;\r
+       }\r
+\r
+       virtual const audio_buffer& audio_data() const override\r
+       {\r
+               return audio_data_;\r
+       }\r
+\r
+       virtual audio_buffer& audio_data() override\r
+       {\r
+               BOOST_THROW_EXCEPTION(invalid_operation());\r
+       }\r
+\r
+       virtual double get_frame_rate() const override\r
+       {\r
+               return video_desc_.fps;\r
+       }\r
+\r
+       virtual int width() const override\r
+       {\r
+               return video_desc_.width;\r
+       }\r
+\r
+       virtual int height() const override\r
+       {\r
+               return video_desc_.height;\r
+       }\r
+\r
+       virtual const void* tag() const override\r
+       {\r
+               return tag_;\r
+       }\r
+};\r
                \r
 struct mixer::impl : boost::noncopyable\r
 {                      \r
@@ -99,7 +163,7 @@ public:
                                auto image = (*image_mixer_)(format_desc);\r
                                auto audio = audio_mixer_(format_desc);\r
 \r
-                               return make_safe<read_frame>(this, std::move(image), std::move(audio), format_desc);    \r
+                               return make_safe<mixed_frame>(this, std::move(image), std::move(audio), format_desc);   \r
                        }\r
                        catch(...)\r
                        {\r
index 7b5cfb2dd1cdcd9f29c59207cecb0ea6793cb470..3d27c60d15713ace67039fcff8af3af3b0db63ff 100644 (file)
@@ -31,7 +31,7 @@
 #include "../../ffmpeg/producer/muxer/frame_muxer.h"\r
 #include "../../ffmpeg/producer/muxer/display_mode.h"\r
 \r
-#include <common/concurrency/com_context.h>\r
+#include <common/concurrency/executor.h>\r
 #include <common/diagnostics/graph.h>\r
 #include <common/exception/exceptions.h>\r
 #include <common/log.h>\r
@@ -265,24 +265,37 @@ public:
        \r
 class decklink_producer_proxy : public core::frame_producer\r
 {              \r
-       safe_ptr<core::draw_frame>              last_frame_;\r
-       com_context<decklink_producer>  context_;\r
-       const uint32_t                                  length_;\r
+       safe_ptr<core::draw_frame>                      last_frame_;\r
+       std::unique_ptr<decklink_producer>      producer_;\r
+       const uint32_t                                          length_;\r
+       executor                                                        executor_;\r
 public:\r
-\r
        explicit decklink_producer_proxy(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str, uint32_t length)\r
-               : context_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
+               : executor_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
                , last_frame_(core::draw_frame::empty())\r
                , length_(length)\r
        {\r
-               context_.reset([&]{return new decklink_producer(format_desc, device_index, frame_factory, filter_str);}); \r
+               executor_.invoke([=]\r
+               {\r
+                       CoInitialize(nullptr);\r
+                       producer_.reset(new decklink_producer(format_desc, device_index, frame_factory, filter_str));\r
+               });\r
+       }\r
+\r
+       ~decklink_producer_proxy()\r
+       {               \r
+               executor_.invoke([=]\r
+               {\r
+                       producer_.reset();\r
+                       CoUninitialize();\r
+               });\r
        }\r
        \r
        // frame_producer\r
                                \r
        virtual safe_ptr<core::draw_frame> receive(int flags) override\r
        {\r
-               auto frame = context_->get_frame(flags);\r
+               auto frame = producer_->get_frame(flags);\r
                if(frame != core::draw_frame::late())\r
                        last_frame_ = frame;\r
                return frame;\r
@@ -300,7 +313,7 @@ public:
        \r
        std::wstring print() const override\r
        {\r
-               return context_->print();\r
+               return producer_->print();\r
        }\r
 \r
        virtual boost::property_tree::wptree info() const override\r
index 110a6316a11f54ff2dd58d80b9eeaa15eb0ca8ac..cf078b25c58073ef767bdd2637b01a7d8506c143 100644 (file)
@@ -6,7 +6,7 @@
     <data-path>D:\casparcg\_data\</data-path>\r
     <template-path>D:\casparcg\_templates\</template-path>\r
   </paths>\r
-  <blend-modes>false</blend-modes>\r
+  <blend-modes>true</blend-modes>\r
   <log-level>trace</log-level>\r
   <channels>\r
     <channel>\r