]> git.sesse.net Git - casparcg/commitdiff
### Mayor refactoring. Simplified frame handling and image_mixer. Separated video...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 17 Feb 2012 22:46:40 +0000 (22:46 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 17 Feb 2012 22:46:40 +0000 (22:46 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2442 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

90 files changed:
accelerator/accelerator.cpp
accelerator/accelerator.h
accelerator/accelerator.vcxproj
accelerator/accelerator.vcxproj.filters
accelerator/cpu/image/image_mixer.cpp
accelerator/cpu/image/image_mixer.h
accelerator/cpu/util/data_frame.cpp [deleted file]
accelerator/cpu/util/data_frame.h [deleted file]
accelerator/ogl/image/image_kernel.cpp
accelerator/ogl/image/image_kernel.h
accelerator/ogl/image/image_mixer.cpp
accelerator/ogl/image/image_mixer.h
accelerator/ogl/util/buffer.cpp [moved from accelerator/ogl/util/host_buffer.cpp with 62% similarity]
accelerator/ogl/util/buffer.h [moved from accelerator/ogl/util/host_buffer.h with 75% similarity]
accelerator/ogl/util/data_frame.cpp [deleted file]
accelerator/ogl/util/data_frame.h [deleted file]
accelerator/ogl/util/device.cpp
accelerator/ogl/util/device.h
accelerator/ogl/util/shader.cpp
accelerator/ogl/util/shader.h
accelerator/ogl/util/texture.cpp [moved from accelerator/ogl/util/device_buffer.cpp with 73% similarity]
accelerator/ogl/util/texture.h [moved from accelerator/ogl/util/device_buffer.h with 75% similarity]
common/compiler/vs/disable_silly_warnings.h
common/concurrency/async.h
common/concurrency/executor.h
common/gl/gl_check.cpp
common/gl/gl_check.h
core/consumer/frame_consumer.cpp
core/consumer/frame_consumer.h
core/consumer/output.cpp
core/consumer/output.h
core/core.vcxproj
core/core.vcxproj.filters
core/frame/data_frame.cpp [deleted file]
core/frame/data_frame.h [deleted file]
core/frame/draw_frame.cpp
core/frame/draw_frame.h
core/frame/frame.cpp [new file with mode: 0644]
core/frame/frame.h [new file with mode: 0644]
core/frame/frame_factory.h
core/frame/frame_visitor.h
core/frame/pixel_format.h
core/mixer/audio/audio_mixer.cpp
core/mixer/audio/audio_mixer.h
core/mixer/image/image_mixer.h
core/mixer/mixer.cpp
core/mixer/mixer.h
core/monitor/monitor.h
core/producer/color/color_producer.cpp
core/producer/frame_producer.cpp
core/producer/frame_producer.h
core/producer/layer.h
core/producer/stage.h
core/video_channel.cpp
core/video_channel.h
core/video_format.h
modules/bluefish/consumer/bluefish_consumer.cpp
modules/decklink/consumer/decklink_consumer.cpp
modules/decklink/producer/decklink_producer.cpp
modules/decklink/producer/decklink_producer.h
modules/ffmpeg/consumer/ffmpeg_consumer.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/ffmpeg_producer.h
modules/ffmpeg/producer/muxer/frame_muxer.cpp
modules/ffmpeg/producer/muxer/frame_muxer.h
modules/ffmpeg/producer/util/util.cpp
modules/ffmpeg/producer/util/util.h
modules/flash/producer/FlashAxContainer.cpp
modules/flash/producer/cg_proxy.cpp
modules/flash/producer/cg_proxy.h
modules/flash/producer/flash_producer.cpp
modules/flash/producer/flash_producer.h
modules/image/consumer/image_consumer.cpp
modules/image/producer/image_producer.cpp
modules/image/producer/image_producer.h
modules/image/producer/image_scroll_producer.cpp
modules/image/producer/image_scroll_producer.h
modules/oal/consumer/oal_consumer.cpp
modules/reroute/producer/reroute_producer.cpp
modules/reroute/producer/reroute_producer.h
modules/screen/consumer/screen_consumer.cpp
protocol/amcp/AMCPCommandsImpl.cpp
protocol/cii/CIICommandsImpl.cpp
protocol/cii/CIIProtocolStrategy.cpp
protocol/osc/oscpack/OscHostEndianness.h
protocol/util/AsyncEventServer.cpp
protocol/util/AsyncEventServer.h
shell/casparcg.config
shell/main.cpp
shell/shell.rc

index 9291c82f0c75573ea0c5978fd6f94d7a1ffebba1..ef5aaba36e6230bae9951e1815a122bd8e7b2300 100644 (file)
@@ -22,7 +22,7 @@ struct accelerator::impl
        {\r
        }\r
 \r
-       spl::unique_ptr<core::image_mixer> create_image_mixer()\r
+       std::unique_ptr<core::image_mixer> create_image_mixer()\r
        {\r
                try\r
                {\r
@@ -33,7 +33,7 @@ struct accelerator::impl
                                if(!ogl_device_)\r
                                        ogl_device_.reset(new ogl::device());\r
 \r
-                               return spl::make_unique<ogl::image_mixer>(spl::make_shared_ptr(ogl_device_));\r
+                               return std::unique_ptr<core::image_mixer>(new ogl::image_mixer(spl::make_shared_ptr(ogl_device_)));\r
                        }\r
                }\r
                catch(...)\r
@@ -42,7 +42,7 @@ struct accelerator::impl
                                CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
 \r
-               return spl::make_unique<cpu::image_mixer>();\r
+               return std::unique_ptr<core::image_mixer>(new cpu::image_mixer());\r
        }\r
 };\r
 \r
@@ -55,7 +55,7 @@ accelerator::~accelerator()
 {\r
 }\r
 \r
-spl::unique_ptr<core::image_mixer> accelerator::create_image_mixer()\r
+std::unique_ptr<core::image_mixer> accelerator::create_image_mixer()\r
 {\r
        return impl_->create_image_mixer();\r
 }\r
index 5bdad25cd03316cd33413a4878ad26dcd462ab87..74a6fb593bf44f88423bd7f1b370401bd2b206f5 100644 (file)
@@ -15,7 +15,7 @@ public:
        accelerator(const std::wstring& path);\r
        ~accelerator();\r
 \r
-       spl::unique_ptr<core::image_mixer> create_image_mixer();\r
+       std::unique_ptr<core::image_mixer> create_image_mixer();\r
 private:\r
        struct impl;\r
        spl::unique_ptr<impl> impl_;\r
index 713c9f82bbf3d60764a7e6ccad8df508fbe17e7d..190972e6b0bc3af72cee34ef370d1f23c9b8c980 100644 (file)
   <ItemGroup>\r
     <ClInclude Include="cpu\image\image_mixer.h" />\r
     <ClInclude Include="cpu\util\xmm.h" />\r
-    <ClInclude Include="cpu\util\data_frame.h" />\r
     <ClInclude Include="accelerator.h" />\r
     <ClInclude Include="ogl\image\blending_glsl.h" />\r
     <ClInclude Include="ogl\image\image_kernel.h" />\r
     <ClInclude Include="ogl\image\image_mixer.h" />\r
     <ClInclude Include="ogl\image\image_shader.h" />\r
+    <ClInclude Include="ogl\util\buffer.h" />\r
     <ClInclude Include="ogl\util\device.h" />\r
-    <ClInclude Include="ogl\util\device_buffer.h" />\r
-    <ClInclude Include="ogl\util\host_buffer.h" />\r
+    <ClInclude Include="ogl\util\texture.h" />\r
     <ClInclude Include="ogl\util\shader.h" />\r
-    <ClInclude Include="ogl\util\data_frame.h" />\r
     <ClInclude Include="StdAfx.h" />\r
   </ItemGroup>\r
   <ItemGroup>\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="cpu\util\data_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="ogl\image\image_kernel.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\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="ogl\util\device.cpp">\r
+    <ClCompile Include="ogl\util\buffer.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="ogl\util\device_buffer.cpp">\r
+    <ClCompile Include="ogl\util\device.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="ogl\util\host_buffer.cpp">\r
+    <ClCompile Include="ogl\util\texture.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\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="ogl\util\data_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="StdAfx.cpp">\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>\r
index 4f852f9f3ecd47a6cd698afb09398a47dc87d3be..c5dd0891769e47e8a120fc6998c6535283285c68 100644 (file)
     <ClInclude Include="ogl\image\image_kernel.h">\r
       <Filter>source\ogl\image</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="ogl\util\device_buffer.h">\r
-      <Filter>source\ogl\util</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="ogl\util\host_buffer.h">\r
-      <Filter>source\ogl\util</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="ogl\util\shader.h">\r
       <Filter>source\ogl\util</Filter>\r
     </ClInclude>\r
     <ClInclude Include="accelerator.h">\r
       <Filter>source</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="cpu\util\data_frame.h">\r
-      <Filter>source\cpu\util</Filter>\r
+    <ClInclude Include="ogl\util\device.h">\r
+      <Filter>source\ogl\util</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="ogl\util\data_frame.h">\r
+    <ClInclude Include="ogl\util\texture.h">\r
       <Filter>source\ogl\util</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="ogl\util\device.h">\r
+    <ClInclude Include="ogl\util\buffer.h">\r
       <Filter>source\ogl\util</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
     <ClCompile Include="ogl\image\image_kernel.cpp">\r
       <Filter>source\ogl\image</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="ogl\util\device_buffer.cpp">\r
-      <Filter>source\ogl\util</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="ogl\util\host_buffer.cpp">\r
-      <Filter>source\ogl\util</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="ogl\util\shader.cpp">\r
       <Filter>source\ogl\util</Filter>\r
     </ClCompile>\r
     <ClCompile Include="accelerator.cpp">\r
       <Filter>source</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="cpu\util\data_frame.cpp">\r
-      <Filter>source\cpu\util</Filter>\r
+    <ClCompile Include="ogl\util\device.cpp">\r
+      <Filter>source\ogl\util</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="ogl\util\data_frame.cpp">\r
+    <ClCompile Include="ogl\util\texture.cpp">\r
       <Filter>source\ogl\util</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="ogl\util\device.cpp">\r
+    <ClCompile Include="ogl\util\buffer.cpp">\r
       <Filter>source\ogl\util</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
index b11d0accc80a807522b699d1b9f65fcacdf771d5..73b91a5f84c7f470d7bd744dab322fa6d3d2320f 100644 (file)
@@ -23,7 +23,6 @@
 \r
 #include "image_mixer.h"\r
 \r
-#include "../util/data_frame.h"\r
 #include "../util/xmm.h"\r
 \r
 #include <common/assert.h>\r
@@ -31,7 +30,7 @@
 #include <common/concurrency/async.h>\r
 #include <common/memory/memcpy.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/pixel_format.h>\r
 #include <core/video_format.h>\r
@@ -95,20 +94,22 @@ bool operator!=(const item& lhs, const item& rhs)
        return !(lhs == rhs);\r
 }\r
        \r
+// 100% accurate blending with correct rounding.\r
 inline xmm::s8_x blend(xmm::s8_x d, xmm::s8_x s)\r
 {      \r
        using namespace xmm;\r
                \r
+       // C(S, D) = S + D - (((T >> 8) + T) >> 8);\r
        // T(S, D) = S * D[A] + 0x80\r
+\r
        auto aaaa   = s8_x::shuffle(d, s8_x(15, 15, 15, 15, 11, 11, 11, 11, 7, 7, 7, 7, 3, 3, 3, 3));\r
-       d                       = s8_x(u8_x::min(u8_x(d), u8_x(aaaa))); // overflow guard\r
+       d                       = s8_x(u8_x::min(u8_x(d), u8_x(aaaa))); // Overflow guard. Some source files have color values which incorrectly exceed pre-multiplied alpha values, e.g. red(255) > alpha(254).\r
 \r
        auto xaxa       = s16_x(aaaa) >> 8;             \r
                              \r
        auto t1         = s16_x::multiply_low(s16_x(s) & 0x00FF, xaxa) + 0x80;    \r
        auto t2         = s16_x::multiply_low(s16_x(s) >> 8    , xaxa) + 0x80;\r
                \r
-       // C(S, D) = S + D - (((T >> 8) + T) >> 8);\r
        auto xyxy       = s8_x(((t1 >> 8) + t1) >> 8);      \r
        auto yxyx       = s8_x((t2 >> 8) + t2);    \r
        auto argb   = s8_x::blend(xyxy, yxyx, s8_x(-1, 0, -1, 0));\r
@@ -150,26 +151,14 @@ static void kernel(uint8_t* dest, const uint8_t* source, size_t count)
 \r
 class image_renderer\r
 {\r
-       std::pair<std::vector<item>, boost::shared_future<boost::iterator_range<const uint8_t*>>>               last_image_;\r
        tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<SwsContext>>>  sws_devices_;\r
-       tbb::concurrent_bounded_queue<spl::shared_ptr<host_buffer>>                                                                             temp_buffers_;\r
+       tbb::concurrent_bounded_queue<spl::shared_ptr<buffer>>                                                                                  temp_buffers_;\r
 public:        \r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> operator()(std::vector<item> items, const core::video_format_desc& format_desc)\r
+       boost::unique_future<core::const_array> operator()(std::vector<item> items, const core::video_format_desc& format_desc)\r
        {       \r
-               if(last_image_.first == items && last_image_.second.has_value())\r
-                       return last_image_.second;\r
-\r
-               auto image      = render(items, format_desc);\r
-               last_image_ = std::make_pair(std::move(items), image);\r
-               return image;\r
-       }\r
-\r
-private:\r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> render(std::vector<item> items, const core::video_format_desc& format_desc)\r
-       {\r
                convert(items, format_desc.width, format_desc.height);          \r
                \r
-               auto result = spl::make_shared<host_buffer>(format_desc.size, 0);\r
+               auto result = spl::make_shared<buffer>(format_desc.size, 0);\r
                if(format_desc.field_mode != core::field_mode::progressive)\r
                {                       \r
                        draw(items, result->data(), format_desc.width, format_desc.height, core::field_mode::upper);\r
@@ -184,11 +173,13 @@ private:
                \r
                return async(launch_policy::deferred, [=]\r
                {\r
-                       return boost::iterator_range<const uint8_t*>(result->data(), result->data() + format_desc.size);\r
-               });             \r
+                       return core::const_array(result->data(), format_desc.size, result);\r
+               });     \r
        }\r
 \r
-       void draw(std::vector<item> items, uint8_t* dest, int width, int height, core::field_mode field_mode)\r
+private:\r
+\r
+       void draw(std::vector<item> items, uint8_t* dest, std::size_t width, std::size_t height, core::field_mode field_mode)\r
        {               \r
                BOOST_FOREACH(auto& item, items)\r
                        item.transform.field_mode &= field_mode;\r
@@ -218,7 +209,7 @@ private:
                // TODO: Add support for push transition.\r
                // TODO: Add support for wipe transition.\r
                // TODO: Add support for slide transition.\r
-               tbb::parallel_for(tbb::blocked_range<int>(0, height/step), [&](const tbb::blocked_range<int>& r)\r
+               tbb::parallel_for(tbb::blocked_range<std::size_t>(0, height/step), [&](const tbb::blocked_range<std::size_t>& r)\r
                {\r
                        for(auto i = r.begin(); i != r.end(); ++i)\r
                        {\r
@@ -273,7 +264,7 @@ private:
                        if(!sws_device)                         \r
                                BOOST_THROW_EXCEPTION(operation_failed() << msg_info("Could not create software scaling device.") << boost::errinfo_api_function("sws_getContext"));                            \r
                \r
-                       auto dest_frame = spl::make_shared<host_buffer>(width*height*4);\r
+                       auto dest_frame = spl::make_shared<buffer>(width*height*4);\r
                        temp_buffers_.push(dest_frame);\r
 \r
                        {\r
@@ -323,7 +314,7 @@ public:
                transform_stack_.push_back(transform_stack_.back()*transform.image_transform);\r
        }\r
                \r
-       void visit(const core::data_frame& frame)\r
+       void visit(const core::mutable_frame& frame)\r
        {                       \r
                if(frame.pixel_format_desc().format == core::pixel_format::invalid)\r
                        return;\r
@@ -355,24 +346,31 @@ public:
        {               \r
        }\r
        \r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> render(const core::video_format_desc& format_desc)\r
+       boost::unique_future<core::const_array> render(const core::video_format_desc& format_desc)\r
        {\r
                return renderer_(std::move(items_), format_desc);\r
        }\r
        \r
-       virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
+       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
        {\r
-               return spl::make_unique<cpu::data_frame>(tag, desc, frame_rate, field_mode);\r
+               std::vector<core::mutable_array> buffers;\r
+               BOOST_FOREACH(auto& plane, desc.planes)\r
+               {\r
+                       auto buf = spl::make_shared<buffer>(plane.size);\r
+                       buffers.push_back(core::mutable_array(buf->data(), plane.size, buf));\r
+               }\r
+               return core::mutable_frame(std::move(buffers), core::audio_buffer(), tag, desc, frame_rate, field_mode);\r
        }\r
 };\r
 \r
 image_mixer::image_mixer() : impl_(new impl()){}\r
+image_mixer::~image_mixer(){}\r
 void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
-void image_mixer::visit(const core::data_frame& frame){impl_->visit(frame);}\r
+void image_mixer::visit(const core::mutable_frame& frame){impl_->visit(frame);}\r
 void image_mixer::pop(){impl_->pop();}\r
-boost::shared_future<boost::iterator_range<const uint8_t*>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
+boost::unique_future<core::const_array> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
 void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
 void image_mixer::end_layer(){impl_->end_layer();}\r
-spl::unique_ptr<core::data_frame> image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
+core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
 \r
 }}}
\ No newline at end of file
index b98c1f8f4632f7c8e66e1bb5fb3ed368ff6a521b..e62c6a9092519bd37ea2aeec8a049b9ac0da302c 100644 (file)
@@ -6,38 +6,51 @@
 #include <core/mixer/image/blend_modes.h>\r
 #include <core/mixer/image/image_mixer.h>\r
 \r
+#include <core/frame/frame.h>\r
 #include <core/frame/frame_visitor.h>\r
 #include <core/video_format.h>\r
 \r
 FORWARD1(boost, template<typename> class shared_future);\r
 FORWARD1(boost, template<typename> class iterator_range);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class frame);\r
 FORWARD2(caspar, core, struct pixel_format_desc);\r
 FORWARD2(caspar, core, struct video_format_desc);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class mutable_frame);\r
 FORWARD2(caspar, core, struct frame_transform);\r
 \r
 namespace caspar { namespace accelerator { namespace cpu {\r
        \r
+typedef std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> buffer;\r
+\r
 class image_mixer sealed : public core::image_mixer\r
 {\r
 public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
        image_mixer();\r
-       \r
+       ~image_mixer();\r
+\r
+       // Methods      \r
+\r
+       virtual void begin_layer(core::blend_mode blend_mode);\r
+       virtual void end_layer();\r
+\r
        virtual void push(const core::frame_transform& frame);\r
-       virtual void visit(const core::data_frame& frame);\r
+       virtual void visit(const core::mutable_frame& frame);\r
        virtual void pop();\r
-\r
-       void begin_layer(core::blend_mode blend_mode);\r
-       void end_layer();\r
                \r
-       // NOTE: Content of return future is only valid while future is valid.\r
-       virtual ::boost::shared_future<::boost::iterator_range<const uint8_t*>> operator()(const core::video_format_desc& format_desc) override;\r
+       virtual boost::unique_future<core::const_array> operator()(const core::video_format_desc& format_desc) override;\r
                \r
-       virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
+       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
+\r
+       // Properties\r
+\r
 private:\r
        struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
diff --git a/accelerator/cpu/util/data_frame.cpp b/accelerator/cpu/util/data_frame.cpp
deleted file mode 100644 (file)
index 1e7d4e1..0000000
+++ /dev/null
@@ -1,93 +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 "data_frame.h"\r
-\r
-#include <common/except.h>\r
-#include <core/frame/frame_visitor.h>\r
-#include <core/frame/pixel_format.h>\r
-\r
-#include <boost/lexical_cast.hpp>\r
-\r
-namespace caspar { namespace accelerator { namespace cpu {\r
-                       \r
-struct data_frame::impl : boost::noncopyable\r
-{                      \r
-       std::vector<spl::shared_ptr<host_buffer>>       buffers_;\r
-       core::audio_buffer                                                      audio_data_;\r
-       const core::pixel_format_desc                           desc_;\r
-       const void*                                                                     tag_;\r
-       double                                                                          frame_rate_;\r
-       core::field_mode                                                        field_mode_;\r
-\r
-       impl(const void* tag)\r
-               : desc_(core::pixel_format::invalid)\r
-               , tag_(tag)             \r
-               , field_mode_(core::field_mode::empty)\r
-       {\r
-       }\r
-\r
-       impl(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
-               : desc_(desc)\r
-               , tag_(tag)\r
-               , frame_rate_(frame_rate)\r
-               , field_mode_(field_mode)\r
-       {\r
-               std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
-               {\r
-                       return spl::make_shared<host_buffer>(plane.size);\r
-               });\r
-       }\r
-\r
-       boost::iterator_range<uint8_t*> image_data(int index)\r
-       {\r
-               if(index >= buffers_.size() || !buffers_[index]->data())\r
-                       BOOST_THROW_EXCEPTION(out_of_range());\r
-               auto ptr = buffers_[index]->data();\r
-               return boost::iterator_range<uint8_t*>(ptr, ptr+buffers_[index]->size());\r
-       }\r
-};\r
-       \r
-data_frame::data_frame(const void* tag) : impl_(new impl(tag)){}\r
-data_frame::data_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
-       : impl_(new impl(tag, desc, frame_rate, field_mode)){}\r
-data_frame::data_frame(data_frame&& other) : impl_(std::move(other.impl_)){}\r
-data_frame& data_frame::operator=(data_frame&& other)\r
-{\r
-       impl_ = std::move(other.impl_);\r
-       return *this;\r
-}\r
-void data_frame::swap(data_frame& other){impl_.swap(other.impl_);}\r
-const core::pixel_format_desc& data_frame::pixel_format_desc() const{return impl_->desc_;}\r
-const boost::iterator_range<const uint8_t*> data_frame::image_data(int index) const{return impl_->image_data(index);}\r
-const core::audio_buffer& data_frame::audio_data() const{return impl_->audio_data_;}\r
-const boost::iterator_range<uint8_t*> data_frame::image_data(int index){return impl_->image_data(index);}\r
-core::audio_buffer& data_frame::audio_data(){return impl_->audio_data_;}\r
-double data_frame::frame_rate() const{return impl_->frame_rate_;}\r
-core::field_mode data_frame::field_mode()const{return impl_->field_mode_;}\r
-int data_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
-int data_frame::height() const{return impl_->desc_.planes.at(0).height;}                                               \r
-const void* data_frame::tag() const{return impl_->tag_;}       \r
-std::vector<spl::shared_ptr<host_buffer>> data_frame::buffers() const{return impl_->buffers_;}\r
-\r
-}}}
\ No newline at end of file
diff --git a/accelerator/cpu/util/data_frame.h b/accelerator/cpu/util/data_frame.h
deleted file mode 100644 (file)
index 7838c47..0000000
+++ /dev/null
@@ -1,82 +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 <common/spl/memory.h>\r
-#include <common/forward.h>\r
-\r
-#include <core/video_format.h>\r
-#include <core/frame/data_frame.h>\r
-#include <core/mixer/audio/audio_mixer.h>\r
-\r
-#include <boost/range/iterator_range.hpp>\r
-\r
-#include <stdint.h>\r
-#include <vector>\r
-\r
-FORWARD2(caspar, core, class frame_visitor);\r
-FORWARD2(caspar, core, struct pixel_format_desc);\r
-\r
-namespace caspar { namespace accelerator { namespace cpu {\r
-       \r
-typedef std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> host_buffer;\r
-\r
-class data_frame sealed : public core::data_frame\r
-{\r
-       data_frame(const data_frame&);\r
-       data_frame& operator=(const data_frame);\r
-public:        \r
-       explicit data_frame(const void* tag);\r
-       explicit data_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
-\r
-       data_frame(data_frame&& other);\r
-       data_frame& operator=(data_frame&& other);\r
-\r
-       void swap(data_frame& other);\r
-                               \r
-       // data_frame\r
-               \r
-       virtual const core::pixel_format_desc& pixel_format_desc() const override;\r
-\r
-       virtual const boost::iterator_range<const uint8_t*> image_data(int index) const override;\r
-       virtual const core::audio_buffer& audio_data() const override;\r
-\r
-       virtual const boost::iterator_range<uint8_t*> image_data(int index) override;\r
-       virtual core::audio_buffer& audio_data() override;\r
-       \r
-       virtual double frame_rate() const override;\r
-       virtual core::field_mode field_mode() const override;\r
-\r
-       virtual int width() const override;\r
-       virtual int height() const override;\r
-                                                               \r
-       virtual const void* tag() const override;       \r
-\r
-       // data_frames\r
-\r
-       std::vector<spl::shared_ptr<host_buffer>> buffers() const;              \r
-private:\r
-       struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
-};\r
-\r
-}}}
\ No newline at end of file
index 2c55183f76aaf516dbc5d5af97537d758ce94462..1919a75e8927034a7f9104f2e66acaeff4688ba8 100644 (file)
@@ -27,7 +27,7 @@
 #include "blending_glsl.h"\r
 \r
 #include "../util/shader.h"\r
-#include "../util/device_buffer.h"\r
+#include "../util/texture.h"\r
 #include "../util/device.h"\r
 \r
 #include <common/except.h>\r
index 000739a4868095e0e4812bc5d3688ea0ee046120..aaef959f4717d4065d1c52fd5e800453e0df475e 100644 (file)
@@ -46,13 +46,13 @@ typedef enum_class<keyer_def> keyer;
 struct draw_params sealed\r
 {\r
        core::pixel_format_desc                                                         pix_desc;\r
-       std::vector<spl::shared_ptr<class device_buffer>>       textures;\r
+       std::vector<spl::shared_ptr<class texture>>     textures;\r
        core::image_transform                                                           transform;\r
        core::blend_mode                                                                        blend_mode;\r
        keyer                                                                                           keyer;\r
-       std::shared_ptr<class device_buffer>                            background;\r
-       std::shared_ptr<class device_buffer>                            local_key;\r
-       std::shared_ptr<class device_buffer>                            layer_key;\r
+       std::shared_ptr<class texture>                          background;\r
+       std::shared_ptr<class texture>                          local_key;\r
+       std::shared_ptr<class texture>                          layer_key;\r
 \r
        draw_params() \r
                : pix_desc(core::pixel_format::invalid)\r
@@ -65,8 +65,19 @@ struct draw_params sealed
 class image_kernel sealed : boost::noncopyable\r
 {\r
 public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
        image_kernel(const spl::shared_ptr<class device>& ogl);\r
+\r
+       // Methods\r
+\r
        void draw(draw_params&& params);\r
+       \r
+       // Properties\r
+\r
        bool has_blend_modes() const;\r
 private:\r
        struct impl;\r
index 0688fe6154efae8e3d4bd8a5d11eaa865c8a56fd..b3e98d68cfb4c2c22474924c56857edb14b118a4 100644 (file)
 *\r
 * Author: Robert Nagy, ronag89@gmail.com\r
 */\r
-\r
 #include "../../stdafx.h"\r
 \r
 #include "image_mixer.h"\r
 \r
 #include "image_kernel.h"\r
 \r
-#include "../util/data_frame.h"\r
 #include "../util/device.h"\r
-#include "../util/host_buffer.h"\r
-#include "../util/device_buffer.h"\r
+#include "../util/buffer.h"\r
+#include "../util/texture.h"\r
 \r
 #include <common/gl/gl_check.h>\r
 #include <common/concurrency/async.h>\r
 #include <common/memory/memcpy.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/pixel_format.h>\r
 #include <core/video_format.h>\r
@@ -54,15 +52,14 @@ using namespace boost::assign;
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
                \r
-typedef boost::shared_future<spl::shared_ptr<device_buffer>> future_texture;\r
+typedef boost::shared_future<spl::shared_ptr<texture>> future_texture;\r
 \r
 struct item\r
 {\r
-       core::pixel_format_desc                                         pix_desc;\r
-       core::field_mode                                                        field_mode;\r
-       std::vector<spl::shared_ptr<host_buffer>>       buffers;\r
-       std::vector<future_texture>                                     textures;\r
-       core::image_transform                                           transform;\r
+       core::pixel_format_desc                                                         pix_desc;\r
+       core::field_mode                                                                        field_mode;\r
+       std::vector<future_texture>                                                     textures;\r
+       core::image_transform                                                           transform;\r
 \r
        item()\r
                : pix_desc(core::pixel_format::invalid)\r
@@ -71,16 +68,6 @@ struct item
        }\r
 };\r
 \r
-bool operator==(const item& lhs, const item& rhs)\r
-{\r
-       return lhs.buffers == rhs.buffers && lhs.transform == rhs.transform;\r
-}\r
-\r
-bool operator!=(const item& lhs, const item& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
-\r
 struct layer\r
 {\r
        std::vector<item>       items;\r
@@ -98,21 +85,10 @@ struct layer
        }\r
 };\r
 \r
-bool operator==(const layer& lhs, const layer& rhs)\r
-{\r
-       return lhs.items == rhs.items && lhs.blend_mode == rhs.blend_mode;\r
-}\r
-\r
-bool operator!=(const layer& lhs, const layer& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
-\r
 class image_renderer\r
 {\r
-       spl::shared_ptr<device>                                                                                                                                                 ogl_;\r
-       image_kernel                                                                                                                                                                    kernel_;\r
-       std::pair<std::vector<layer>, boost::shared_future<boost::iterator_range<const uint8_t*>>>              last_image_;    \r
+       spl::shared_ptr<device> ogl_;\r
+       image_kernel                    kernel_;\r
 public:\r
        image_renderer(const spl::shared_ptr<device>& ogl)\r
                : ogl_(ogl)\r
@@ -120,130 +96,72 @@ public:
        {\r
        }\r
        \r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc)\r
+       boost::unique_future<core::const_array> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc)\r
        {       \r
-               if(last_image_.first == layers && last_image_.second.has_value())\r
-                       return last_image_.second;\r
-\r
-               auto image      = render(layers, format_desc);\r
-               last_image_ = std::make_pair(std::move(layers), image);\r
-               return image;\r
-       }\r
-\r
-private:       \r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> render(std::vector<layer> layers, const core::video_format_desc& format_desc)\r
-       {                       \r
                if(layers.empty())\r
                { // Bypass GPU with empty frame.\r
                        auto buffer = spl::make_shared<const std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>>>(format_desc.size, 0);\r
                        return async(launch_policy::deferred, [=]\r
                        {\r
-                               return boost::iterator_range<const uint8_t*>(buffer->data(), buffer->data() + format_desc.size);\r
+                               return core::const_array(buffer->data(), static_cast<std::size_t>(format_desc.size), buffer);\r
                        });\r
-               }\r
-               else if(has_uswc_memcpy() &&                            \r
-                               layers.size()                           == 1 &&\r
-                           layers.at(0).items.size()   == 1 &&\r
-                          (kernel_.has_blend_modes() && layers.at(0).blend_mode != core::blend_mode::normal) == false &&\r
-                           layers.at(0).items.at(0).pix_desc.format            == core::pixel_format::bgra &&\r
-                           layers.at(0).items.at(0).buffers.at(0)->size() == format_desc.size &&\r
-                           layers.at(0).items.at(0).transform                          == core::image_transform())\r
-               { // Bypass GPU using streaming loads to cachable memory.\r
-                       auto uswc_buffer = layers.at(0).items.at(0).buffers.at(0);\r
-                       auto buffer              = std::make_shared<std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>>>(uswc_buffer->size());\r
-\r
-                       uswc_memcpy(buffer->data(), uswc_buffer->data(), uswc_buffer->size());\r
+               }               \r
 \r
-                       return async(launch_policy::deferred, [=]\r
-                       {\r
-                               return boost::iterator_range<const uint8_t*>(buffer->data(), buffer->data() + buffer->size());\r
-                       });\r
-               }\r
-               else\r
-               {       \r
-                       // Start host->device transfers.\r
-                       \r
-                       BOOST_FOREACH(auto& layer, layers)\r
-                       {\r
-                               BOOST_FOREACH(auto& item, layer.items)\r
-                               {\r
-                                       auto host_buffers = boost::get<std::vector<spl::shared_ptr<host_buffer>>>(item.buffers);\r
-                                       auto textures     = std::vector<future_texture>();\r
-\r
-                                       for(size_t n = 0; n < host_buffers.size(); ++n) \r
-                                       {\r
-                                               auto buffer     = host_buffers[n];\r
-                                               auto plane                      = item.pix_desc.planes[n];\r
-                                               auto future_texture     = ogl_->copy_async(buffer, plane.width, plane.height, plane.channels);          \r
-                                               item.textures.push_back(std::move(future_texture));\r
-                                       }       \r
-                                       item.buffers.clear();\r
-                               }\r
-                       }       \r
-                       \r
-                       // Draw\r
-                       boost::shared_future<spl::shared_ptr<host_buffer>> buffer = ogl_->begin_invoke([=]() mutable -> spl::shared_ptr<host_buffer>\r
-                       {\r
-                               auto draw_buffer = create_mixer_buffer(4, format_desc);\r
-\r
-                               if(format_desc.field_mode != core::field_mode::progressive)\r
-                               {\r
-                                       auto upper = layers;\r
-                                       auto lower = std::move(layers);\r
-\r
-                                       BOOST_FOREACH(auto& layer, upper)\r
-                                       {\r
-                                               BOOST_FOREACH(auto& item, layer.items)\r
-                                                       item.transform.field_mode &= core::field_mode::upper;\r
-                                       }\r
-\r
-                                       BOOST_FOREACH(auto& layer, lower)\r
-                                       {\r
-                                               BOOST_FOREACH(auto& item, layer.items)\r
-                                                       item.transform.field_mode &= core::field_mode::lower;\r
-                                       }\r
-\r
-                                       draw(std::move(upper), draw_buffer, format_desc);\r
-                                       draw(std::move(lower), draw_buffer, format_desc);\r
-                               }\r
-                               else\r
-                               {\r
-                                       draw(std::move(layers), draw_buffer, format_desc);\r
-                               }\r
-                       \r
-                               auto result = ogl_->create_host_buffer(static_cast<int>(format_desc.size), host_buffer::usage::read_only); \r
-                               draw_buffer->copy_to(*result);                                                  \r
-                               return result;\r
-                       });\r
-               \r
-                       // Defer memory mapping.\r
-                       return async(launch_policy::deferred, [=]() mutable -> boost::iterator_range<const uint8_t*>\r
-                       {\r
-                               const auto& buf = buffer.get();\r
-                               if(!buf->data())\r
-                                       ogl_->invoke(std::bind(&host_buffer::map, std::ref(buf)), task_priority::high_priority);\r
+               return fold(ogl_->begin_invoke([=]() mutable -> boost::shared_future<core::const_array>\r
+               {\r
+                       auto draw_buffer = create_mixer_buffer(format_desc.width, format_desc.height, 4);\r
 \r
-                               auto ptr = reinterpret_cast<const uint8_t*>(buf->data()); // .get() and ->data() can block calling thread, ->data() can also block OpenGL thread, defer it as long as possible.\r
-                               return boost::iterator_range<const uint8_t*>(ptr, ptr + buffer.get()->size());\r
-                       });\r
-               }\r
+                       if(format_desc.field_mode != core::field_mode::progressive)\r
+                       {\r
+                               draw(layers,                    draw_buffer, format_desc, core::field_mode::upper);\r
+                               draw(std::move(layers), draw_buffer, format_desc, core::field_mode::lower);\r
+                       }\r
+                       else                    \r
+                               draw(std::move(layers), draw_buffer, format_desc, core::field_mode::progressive);\r
+                                                               \r
+                       return make_shared(ogl_->copy_async(draw_buffer));\r
+               }));\r
        }\r
+\r
+private:       \r
        \r
-       void draw(std::vector<layer>&&                          layers, \r
-                         spl::shared_ptr<device_buffer>&       draw_buffer, \r
-                         const core::video_format_desc&        format_desc)\r
+       void draw(std::vector<layer>                            layers, \r
+                         spl::shared_ptr<texture>&                     draw_buffer, \r
+                         const core::video_format_desc&        format_desc,\r
+                         core::field_mode                                      field_mode)\r
        {\r
-               std::shared_ptr<device_buffer> layer_key_buffer;\r
+               std::shared_ptr<texture> layer_key_buffer;\r
 \r
                BOOST_FOREACH(auto& layer, layers)\r
-                       draw_layer(std::move(layer), draw_buffer, layer_key_buffer, format_desc);\r
+                       draw_layer(std::move(layer), draw_buffer, layer_key_buffer, format_desc, field_mode);\r
        }\r
 \r
-       void draw_layer(layer&&                                                         layer, \r
-                                       spl::shared_ptr<device_buffer>&         draw_buffer,\r
-                                       std::shared_ptr<device_buffer>&         layer_key_buffer,\r
-                                       const core::video_format_desc&          format_desc)\r
+       void draw_layer(layer                                                   layer, \r
+                                       spl::shared_ptr<texture>&               draw_buffer,\r
+                                       std::shared_ptr<texture>&               layer_key_buffer,\r
+                                       const core::video_format_desc&  format_desc,\r
+                                       core::field_mode                                field_mode)\r
        {               \r
+               // Fix frames           \r
+               BOOST_FOREACH(auto& item, layer.items)          \r
+               {\r
+                       if(item.pix_desc.planes.at(0).height == 480) // NTSC DV\r
+                       {\r
+                               item.transform.fill_translation[1] += 2.0/static_cast<double>(format_desc.height);\r
+                               item.transform.fill_scale[1] = 1.0 - 6.0*1.0/static_cast<double>(format_desc.height);\r
+                       }\r
+       \r
+                       // Fix field-order if needed\r
+                       if(item.field_mode == core::field_mode::lower && format_desc.field_mode == core::field_mode::upper)\r
+                               item.transform.fill_translation[1] += 1.0/static_cast<double>(format_desc.height);\r
+                       else if(item.field_mode == core::field_mode::upper && format_desc.field_mode == core::field_mode::lower)\r
+                               item.transform.fill_translation[1] -= 1.0/static_cast<double>(format_desc.height);\r
+               }\r
+\r
+               // Mask out fields\r
+               BOOST_FOREACH(auto& item, layer.items)                          \r
+                       item.transform.field_mode &= field_mode;\r
+               \r
                // Remove empty items.\r
                boost::range::remove_erase_if(layer.items, [&](const item& item)\r
                {\r
@@ -253,21 +171,21 @@ private:
                // Remove first field stills.\r
                boost::range::remove_erase_if(layer.items, [&](const item& item)\r
                {\r
-                       return item.transform.is_still && item.transform.field_mode == format_desc.field_mode; // only us last field for stills.\r
+                       return item.transform.is_still && item.transform.field_mode == format_desc.field_mode; // only use last field for stills.\r
                });\r
 \r
                if(layer.items.empty())\r
                        return;\r
 \r
-               std::shared_ptr<device_buffer> local_key_buffer;\r
-               std::shared_ptr<device_buffer> local_mix_buffer;\r
+               std::shared_ptr<texture> local_key_buffer;\r
+               std::shared_ptr<texture> local_mix_buffer;\r
                                \r
                if(layer.blend_mode != core::blend_mode::normal)\r
                {\r
-                       auto layer_draw_buffer = create_mixer_buffer(4, format_desc);\r
+                       auto layer_draw_buffer = create_mixer_buffer(draw_buffer->width(), draw_buffer->height(), 4);\r
 \r
                        BOOST_FOREACH(auto& item, layer.items)\r
-                               draw_item(std::move(item), layer_draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer, format_desc);       \r
+                               draw_item(std::move(item), layer_draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer);    \r
                \r
                        draw_mixer_buffer(layer_draw_buffer, std::move(local_mix_buffer), core::blend_mode::normal);                                                    \r
                        draw_mixer_buffer(draw_buffer, std::move(layer_draw_buffer), layer.blend_mode);\r
@@ -275,7 +193,7 @@ private:
                else // fast path\r
                {\r
                        BOOST_FOREACH(auto& item, layer.items)          \r
-                               draw_item(std::move(item), draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer, format_desc);             \r
+                               draw_item(std::move(item), draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer);          \r
                                        \r
                        draw_mixer_buffer(draw_buffer, std::move(local_mix_buffer), core::blend_mode::normal);\r
                }                                       \r
@@ -283,25 +201,12 @@ private:
                layer_key_buffer = std::move(local_key_buffer);\r
        }\r
 \r
-       void draw_item(item&&                                                   item, \r
-                                  spl::shared_ptr<device_buffer>&      draw_buffer, \r
-                                  std::shared_ptr<device_buffer>&      layer_key_buffer, \r
-                                  std::shared_ptr<device_buffer>&      local_key_buffer, \r
-                                  std::shared_ptr<device_buffer>&      local_mix_buffer,\r
-                                  const core::video_format_desc&       format_desc)\r
-       {                                                                       \r
-               if(item.pix_desc.planes.at(0).height == 480) // NTSC DV\r
-               {\r
-                       item.transform.fill_translation[1] += 2.0/static_cast<double>(format_desc.height);\r
-                       item.transform.fill_scale[1] = 1.0 - 6.0*1.0/static_cast<double>(format_desc.height);\r
-               }\r
-       \r
-               // Fix field-order if needed\r
-               if(item.field_mode == core::field_mode::lower && format_desc.field_mode == core::field_mode::upper)\r
-                       item.transform.fill_translation[1] += 1.0/static_cast<double>(format_desc.height);\r
-               else if(item.field_mode == core::field_mode::upper && format_desc.field_mode == core::field_mode::lower)\r
-                       item.transform.fill_translation[1] -= 1.0/static_cast<double>(format_desc.height);\r
-               \r
+       void draw_item(item                                                     item, \r
+                                  spl::shared_ptr<texture>&    draw_buffer, \r
+                                  std::shared_ptr<texture>&    layer_key_buffer, \r
+                                  std::shared_ptr<texture>&    local_key_buffer, \r
+                                  std::shared_ptr<texture>&    local_mix_buffer)\r
+       {                                       \r
                draw_params draw_params;\r
                draw_params.pix_desc    = std::move(item.pix_desc);\r
                draw_params.transform   = std::move(item.transform);\r
@@ -310,7 +215,7 @@ private:
 \r
                if(item.transform.is_key)\r
                {\r
-                       local_key_buffer = local_key_buffer ? local_key_buffer : create_mixer_buffer(1, format_desc);\r
+                       local_key_buffer = local_key_buffer ? local_key_buffer : create_mixer_buffer(draw_buffer->width(), draw_buffer->height(), 1);\r
 \r
                        draw_params.background                  = local_key_buffer;\r
                        draw_params.local_key                   = nullptr;\r
@@ -320,7 +225,7 @@ private:
                }\r
                else if(item.transform.is_mix)\r
                {\r
-                       local_mix_buffer = local_mix_buffer ? local_mix_buffer : create_mixer_buffer(4, format_desc);\r
+                       local_mix_buffer = local_mix_buffer ? local_mix_buffer : create_mixer_buffer(draw_buffer->width(), draw_buffer->height(), 4);\r
 \r
                        draw_params.background                  = local_mix_buffer;\r
                        draw_params.local_key                   = std::move(local_key_buffer);\r
@@ -342,9 +247,9 @@ private:
                }       \r
        }\r
 \r
-       void draw_mixer_buffer(spl::shared_ptr<device_buffer>&  draw_buffer, \r
-                                                  std::shared_ptr<device_buffer>&& source_buffer, \r
-                                                  core::blend_mode                                     blend_mode = core::blend_mode::normal)\r
+       void draw_mixer_buffer(spl::shared_ptr<texture>&        draw_buffer, \r
+                                                  std::shared_ptr<texture>&&   source_buffer, \r
+                                                  core::blend_mode                             blend_mode = core::blend_mode::normal)\r
        {\r
                if(!source_buffer)\r
                        return;\r
@@ -360,9 +265,9 @@ private:
                kernel_.draw(std::move(draw_params));\r
        }\r
                        \r
-       spl::shared_ptr<device_buffer> create_mixer_buffer(int stride, const core::video_format_desc& format_desc)\r
+       spl::shared_ptr<texture> create_mixer_buffer(int width, int height, int stride)\r
        {\r
-               auto buffer = ogl_->create_device_buffer(format_desc.width, format_desc.height, stride);\r
+               auto buffer = ogl_->create_texture(width, height, stride);\r
                buffer->clear();\r
                return buffer;\r
        }\r
@@ -393,27 +298,24 @@ public:
                transform_stack_.push_back(transform_stack_.back()*transform.image_transform);\r
        }\r
                \r
-       void visit(const core::data_frame& frame2)\r
+       void visit(const core::mutable_frame& frame)\r
        {                       \r
-               auto frame = dynamic_cast<const ogl::data_frame*>(&frame2);\r
-               if(frame == nullptr)\r
-                       return;\r
-\r
-               if(frame->pixel_format_desc().format == core::pixel_format::invalid)\r
+               if(frame.pixel_format_desc().format == core::pixel_format::invalid)\r
                        return;\r
 \r
-               if(frame->buffers().empty())\r
+               if(frame.pixel_format_desc().planes.empty())\r
                        return;\r
 \r
                if(transform_stack_.back().field_mode == core::field_mode::empty)\r
                        return;\r
 \r
                item item;\r
-               item.pix_desc                   = frame->pixel_format_desc();\r
-               item.field_mode                 = frame->field_mode();\r
-               item.buffers                    = frame->buffers();                             \r
-               item.transform                  = transform_stack_.back();\r
-\r
+               item.pix_desc   = frame.pixel_format_desc();\r
+               item.field_mode = frame.field_mode();\r
+               item.transform  = transform_stack_.back();\r
+               for(int n = 0; n < static_cast<int>(item.pix_desc.planes.size()); ++n)\r
+                       item.textures.push_back(ogl_->copy_async(frame.image_data(n), item.pix_desc.planes[n].width, item.pix_desc.planes[n].height, item.pix_desc.planes[n].stride));\r
+               \r
                layers_.back().items.push_back(item);\r
        }\r
 \r
@@ -426,30 +328,29 @@ public:
        {               \r
        }\r
        \r
-       boost::shared_future<boost::iterator_range<const uint8_t*>> render(const core::video_format_desc& format_desc)\r
+       boost::unique_future<core::const_array> render(const core::video_format_desc& format_desc)\r
        {\r
-               // Remove empty layers.\r
-               boost::range::remove_erase_if(layers_, [](const layer& layer)\r
-               {\r
-                       return layer.items.empty();\r
-               });\r
-\r
                return renderer_(std::move(layers_), format_desc);\r
        }\r
        \r
-       virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
+       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
        {\r
-               return spl::make_unique<ogl::data_frame>(ogl_, tag, desc, frame_rate, field_mode);\r
+               std::vector<core::mutable_array> buffers;\r
+               BOOST_FOREACH(auto& plane, desc.planes)         \r
+                       buffers.push_back(ogl_->create_array(plane.size));              \r
+\r
+               return core::mutable_frame(std::move(buffers), core::audio_buffer(), tag, desc, frame_rate, field_mode);\r
        }\r
 };\r
 \r
 image_mixer::image_mixer(const spl::shared_ptr<device>& ogl) : impl_(new impl(ogl)){}\r
+image_mixer::~image_mixer(){}\r
 void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
-void image_mixer::visit(const core::data_frame& frame){impl_->visit(frame);}\r
+void image_mixer::visit(const core::mutable_frame& frame){impl_->visit(frame);}\r
 void image_mixer::pop(){impl_->pop();}\r
-boost::shared_future<boost::iterator_range<const uint8_t*>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
+boost::unique_future<core::const_array> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
 void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
 void image_mixer::end_layer(){impl_->end_layer();}\r
-spl::unique_ptr<core::data_frame> image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
+core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
 \r
 }}}
\ No newline at end of file
index 49414136ad165b9a227e78be2ddfabe2d2265eac..949a3f34b83f024f943f7085ad2e1f01253775be 100644 (file)
 #include <core/video_format.h>\r
 \r
 FORWARD1(boost, template<typename> class unique_future);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class frame);\r
 FORWARD2(caspar, core, struct pixel_format_desc);\r
 FORWARD2(caspar, core, struct video_format_desc);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class mutable_frame);\r
 FORWARD2(caspar, core, struct frame_transform);\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
        \r
 class image_mixer sealed : public core::image_mixer\r
 {\r
+       image_mixer(const image_mixer&);\r
+       image_mixer& operator=(const image_mixer&);\r
 public:\r
+\r
+       // Static Members\r
+       \r
+       // Constructors\r
+\r
        image_mixer(const spl::shared_ptr<class device>& ogl);\r
+       ~image_mixer();\r
+\r
+       // Methods\r
+                       \r
+       virtual boost::unique_future<core::const_array> operator()(const core::video_format_desc& format_desc) override;                \r
+       virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
+\r
+       // core::image_mixer\r
        \r
-       virtual void push(const core::frame_transform& frame);\r
-       virtual void visit(const core::data_frame& frame);\r
-       virtual void pop();\r
-\r
-       void begin_layer(core::blend_mode blend_mode);\r
-       void end_layer();\r
-               \r
-       // NOTE: Content of return future is only valid while future is valid.\r
-       virtual boost::shared_future<boost::iterator_range<const uint8_t*>> operator()(const core::video_format_desc& format_desc) override;\r
-               \r
-       virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
+       virtual void begin_layer(core::blend_mode blend_mode) override;\r
+       virtual void end_layer() override;\r
+\r
+       virtual void push(const core::frame_transform& frame) override;\r
+       virtual void visit(const core::mutable_frame& frame) override;\r
+       virtual void pop() override;\r
+                       \r
+       // Properties\r
+\r
 private:\r
        struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
similarity index 62%
rename from accelerator/ogl/util/host_buffer.cpp
rename to accelerator/ogl/util/buffer.cpp
index b866b0aaf9b150e60576431c4a7a42eb1e87c34a..367283cbd0613bd4dffabc4280628ec292cf5536 100644 (file)
@@ -21,9 +21,9 @@
 \r
 #include "../../stdafx.h"\r
 \r
-#include "host_buffer.h"\r
+#include "buffer.h"\r
 \r
-#include "device_buffer.h"\r
+#include "texture.h"\r
 #include "device.h"\r
 \r
 #include <common/except.h>\r
@@ -38,32 +38,32 @@ namespace caspar { namespace accelerator { namespace ogl {
 static tbb::atomic<int> g_w_total_count;\r
 static tbb::atomic<int> g_r_total_count;\r
                                                                                                                                                                                                                                                                                                                                \r
-struct host_buffer::impl : boost::noncopyable\r
+struct buffer::impl : boost::noncopyable\r
 {      \r
        GLuint                                          pbo_;\r
-       const int                                       size_;\r
-       tbb::atomic<void*>                      data_;\r
+       const std::size_t                       size_;\r
+       tbb::atomic<uint8_t*>           data_;\r
        GLenum                                          usage_;\r
        GLenum                                          target_;\r
 \r
 public:\r
-       impl(int size, host_buffer::usage usage) \r
+       impl(std::size_t size, buffer::usage usage) \r
                : size_(size)\r
-               , pbo_(0)\r
-               , target_(usage == host_buffer::usage::write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
-               , usage_(usage == host_buffer::usage::write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
+               , target_(usage == buffer::usage::write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
+               , usage_(usage == buffer::usage::write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
        {\r
                data_ = nullptr;\r
                GL(glGenBuffers(1, &pbo_));\r
-               bind();\r
-               if(usage_ != GL_STREAM_DRAW)    \r
-                       GL(glBufferData(target_, size_, NULL, usage_)); \r
+               bind(); \r
+               GL(glBufferData(target_, size_, NULL, usage_));         \r
+               if(usage_ == GL_STREAM_DRAW)    \r
+                       data_ = (uint8_t*)GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY));  \r
                unbind();\r
 \r
                if(!pbo_)\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to allocate buffer."));\r
 \r
-               CASPAR_LOG(trace) << "[host_buffer] [" << ++(usage_ == host_buffer::usage::write_only ? g_w_total_count : g_r_total_count) << L"] allocated size:" << size_ << " usage: " << (usage == host_buffer::usage::write_only ? "write_only" : "read_only");\r
+               //CASPAR_LOG(trace) << "[buffer] [" << ++(usage_ == buffer::usage::write_only ? g_w_total_count : g_r_total_count) << L"] allocated size:" << size_ << " usage: " << (usage == buffer::usage::write_only ? "write_only" : "read_only");\r
        }       \r
 \r
        ~impl()\r
@@ -80,7 +80,7 @@ public:
                if(usage_ == GL_STREAM_DRAW)                    \r
                        GL(glBufferData(target_, size_, NULL, usage_)); // Notify OpenGL that we don't care about previous data.\r
                \r
-               data_ = GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY));  \r
+               data_ = (uint8_t*)GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY));  \r
                GL(glBindBuffer(target_, 0));\r
                if(!data_)\r
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target OpenGL Pixel Buffer Object."));\r
@@ -112,12 +112,13 @@ public:
        }\r
 };\r
 \r
-host_buffer::host_buffer(int size, usage usage) : impl_(new impl(size, usage)){}\r
-void* host_buffer::data(){return impl_->data_;}\r
-void host_buffer::map(){impl_->map();}\r
-void host_buffer::unmap(){impl_->unmap();}\r
-void host_buffer::bind() const{impl_->bind();}\r
-void host_buffer::unbind() const{impl_->unbind();}\r
-int host_buffer::size() const { return impl_->size_; }\r
+buffer::buffer(std::size_t size, usage usage) : impl_(new impl(size, usage)){}\r
+buffer::~buffer(){}\r
+uint8_t* buffer::data(){return impl_->data_;}\r
+void buffer::map(){impl_->map();}\r
+void buffer::unmap(){impl_->unmap();}\r
+void buffer::bind() const{impl_->bind();}\r
+void buffer::unbind() const{impl_->unbind();}\r
+std::size_t buffer::size() const { return impl_->size_; }\r
 \r
 }}}
\ No newline at end of file
similarity index 75%
rename from accelerator/ogl/util/host_buffer.h
rename to accelerator/ogl/util/buffer.h
index 72477b7d1e2bf360509670f7be6080f5c1c8ba47..53159127f1f5fb4b62f29a8f1491e3ab5c5bc258 100644 (file)
 #include <common/spl/memory.h>\r
 #include <common/enum_class.h>\r
 \r
-#include <boost/noncopyable.hpp>\r
+#include <stdint.h>\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
                        \r
-class host_buffer : boost::noncopyable\r
+class buffer sealed\r
 {\r
+       buffer(const buffer&);\r
+       buffer& operator=(const buffer&);\r
 public:\r
+\r
+       // Static Members\r
+\r
        struct usage_def\r
        {\r
                enum type\r
@@ -41,20 +46,26 @@ public:
        };\r
        typedef enum_class<usage_def> usage;\r
        \r
-       host_buffer(int size, usage usage);\r
+       // Constructors\r
+\r
+       buffer(std::size_t size, usage usage);\r
+       ~buffer();\r
 \r
-       const void* data() const;\r
-       void* data();\r
-       int size() const;       \r
+       // Methods\r
        \r
        void map();\r
        void unmap();\r
 \r
        void bind() const;\r
        void unbind() const;\r
+\r
+       // Properties\r
+\r
+       uint8_t* data();\r
+       std::size_t size() const;       \r
 private:\r
        struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
diff --git a/accelerator/ogl/util/data_frame.cpp b/accelerator/ogl/util/data_frame.cpp
deleted file mode 100644 (file)
index 2bd6c6a..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
-#include "../../stdafx.h"\r
-\r
-#include "data_frame.h"\r
-\r
-#include "device.h"\r
-#include "host_buffer.h"\r
-#include "device_buffer.h"\r
-\r
-#include <common/except.h>\r
-#include <core/frame/frame_visitor.h>\r
-#include <core/frame/pixel_format.h>\r
-\r
-#include <boost/lexical_cast.hpp>\r
-\r
-namespace caspar { namespace accelerator { namespace ogl {\r
-                                                                                                                                                                                                                                                                                                                       \r
-struct data_frame::impl : boost::noncopyable\r
-{                      \r
-       std::shared_ptr<device>                                         ogl_;\r
-       std::vector<spl::shared_ptr<ogl::host_buffer>>  buffers_;\r
-       core::audio_buffer                                                              audio_data_;\r
-       const core::pixel_format_desc                                   desc_;\r
-       const void*                                                                             tag_;\r
-       double                                                                                  frame_rate_;\r
-       core::field_mode                                                                field_mode_;\r
-\r
-       impl(const void* tag)\r
-               : desc_(core::pixel_format::invalid)\r
-               , tag_(tag)             \r
-               , field_mode_(core::field_mode::empty)\r
-       {\r
-       }\r
-\r
-       impl(const spl::shared_ptr<ogl::device>& ogl, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
-               : ogl_(ogl)\r
-               , desc_(desc)\r
-               , tag_(tag)\r
-               , frame_rate_(frame_rate)\r
-               , field_mode_(field_mode)\r
-       {\r
-               std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
-               {\r
-                       return ogl_->create_host_buffer(plane.size, ogl::host_buffer::usage::write_only);\r
-               });\r
-       }\r
-                       \r
-       boost::iterator_range<uint8_t*> image_data(int index)\r
-       {\r
-               if(index >= buffers_.size() || !buffers_[index]->data())\r
-                       BOOST_THROW_EXCEPTION(out_of_range());\r
-               auto ptr = static_cast<uint8_t*>(buffers_[index]->data());\r
-               return boost::iterator_range<uint8_t*>(ptr, ptr+buffers_[index]->size());\r
-       }\r
-};\r
-       \r
-data_frame::data_frame(const void* tag) : impl_(new impl(tag)){}\r
-data_frame::data_frame(const spl::shared_ptr<ogl::device>& ogl, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
-       : impl_(new impl(ogl, tag, desc, frame_rate, field_mode)){}\r
-data_frame::data_frame(data_frame&& other) : impl_(std::move(other.impl_)){}\r
-data_frame& data_frame::operator=(data_frame&& other)\r
-{\r
-       impl_ = std::move(other.impl_);\r
-       return *this;\r
-}\r
-void data_frame::swap(data_frame& other){impl_.swap(other.impl_);}\r
-const core::pixel_format_desc& data_frame::pixel_format_desc() const{return impl_->desc_;}\r
-const boost::iterator_range<const uint8_t*> data_frame::image_data(int index) const{return impl_->image_data(index);}\r
-const core::audio_buffer& data_frame::audio_data() const{return impl_->audio_data_;}\r
-const boost::iterator_range<uint8_t*> data_frame::image_data(int index){return impl_->image_data(index);}\r
-core::audio_buffer& data_frame::audio_data(){return impl_->audio_data_;}\r
-double data_frame::frame_rate() const{return impl_->frame_rate_;}\r
-core::field_mode data_frame::field_mode() const{return impl_->field_mode_;}\r
-int data_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
-int data_frame::height() const{return impl_->desc_.planes.at(0).height;}                                               \r
-const void* data_frame::tag() const{return impl_->tag_;}       \r
-std::vector<spl::shared_ptr<ogl::host_buffer>> data_frame::buffers() const{return impl_->buffers_;}\r
-\r
-}}}
\ No newline at end of file
diff --git a/accelerator/ogl/util/data_frame.h b/accelerator/ogl/util/data_frame.h
deleted file mode 100644 (file)
index a8d4921..0000000
+++ /dev/null
@@ -1,80 +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 <common/spl/memory.h>\r
-#include <common/forward.h>\r
-\r
-#include <core/frame/data_frame.h>\r
-#include <core/frame/pixel_format.h>\r
-#include <core/video_format.h>\r
-#include <core/mixer/audio/audio_mixer.h>\r
-\r
-#include <stdint.h>\r
-#include <vector>\r
-\r
-FORWARD1(boost, template <typename> class iterator_range);\r
-FORWARD2(caspar, core, class frame_visitor);\r
-FORWARD2(caspar, core, struct pixel_format_desc);\r
-\r
-namespace caspar { namespace accelerator { namespace ogl {\r
-       \r
-class data_frame sealed : public core::data_frame\r
-{\r
-       data_frame(const data_frame&);\r
-       data_frame& operator=(const data_frame);\r
-public:        \r
-       explicit data_frame(const void* tag);\r
-       explicit data_frame(const spl::shared_ptr<class device>& ogl, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
-\r
-       data_frame(data_frame&& other);\r
-       data_frame& operator=(data_frame&& other);\r
-\r
-       void swap(data_frame& other);\r
-                       \r
-       // data_frame\r
-               \r
-       virtual const core::pixel_format_desc& pixel_format_desc() const override;\r
-\r
-       virtual const boost::iterator_range<const uint8_t*> image_data(int index) const override;\r
-       virtual const core::audio_buffer& audio_data() const override;\r
-\r
-       virtual const boost::iterator_range<uint8_t*> image_data(int index) override;\r
-       virtual core::audio_buffer& audio_data() override;\r
-       \r
-       virtual double frame_rate() const override;\r
-       virtual core::field_mode field_mode() const override;\r
-\r
-       virtual int width() const override;\r
-       virtual int height() const override;\r
-                                                               \r
-       virtual const void* tag() const override;\r
-                       \r
-       // data_frames\r
-\r
-       std::vector<spl::shared_ptr<class host_buffer>> buffers() const;\r
-private:\r
-       struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
-};\r
-\r
-}}}
\ No newline at end of file
index 5df73f3f0f2f20e874d7e2a95cbed38b1097e402..3b20deef8c8401055f492f243f0d66da36f18e13 100644 (file)
 \r
 #include "device.h"\r
 \r
+#include "buffer.h"\r
+#include "texture.h"\r
 #include "shader.h"\r
 \r
 #include <common/assert.h>\r
 #include <common/except.h>\r
+#include <common/concurrency/async.h>\r
 #include <common/gl/gl_check.h>\r
+#include <common/os/windows/windows.h>\r
 \r
 #include <boost/foreach.hpp>\r
 \r
 #include <gl/glew.h>\r
 \r
-#include <windows.h>\r
-\r
 #include <SFML/Window/Context.hpp>\r
 \r
-#include <array>\r
-#include <unordered_map>\r
-\r
 #include <tbb/concurrent_unordered_map.h>\r
+#include <tbb/concurrent_hash_map.h>\r
 #include <tbb/concurrent_queue.h>\r
-#include <tbb/atomic.h>\r
+\r
+#include <boost/utility/declval.hpp>\r
+\r
+#include <array>\r
+#include <unordered_map>\r
 \r
 tbb::atomic<int> g_count = tbb::atomic<int>();\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
                \r
 struct device::impl : public std::enable_shared_from_this<impl>\r
-{\r
-       std::map<host_buffer*, spl::shared_ptr<device_buffer>> write_buffer_transfer_cache_;\r
+{      \r
+       static_assert(std::is_same<decltype(boost::declval<device>().impl_), spl::shared_ptr<impl>>::value, "impl_ must be shared_ptr");\r
+\r
+       tbb::concurrent_hash_map<buffer*, std::shared_ptr<texture>> texture_mapping_;\r
 \r
        std::unique_ptr<sf::Context> device_;\r
        std::unique_ptr<sf::Context> host_alloc_device_;\r
        \r
-       std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<device_buffer>>>, 4>        device_pools_;\r
-       std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<host_buffer>>>, 2>          host_pools_;\r
+       std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<texture>>>, 4>      device_pools_;\r
+       std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<buffer>>>, 2>       host_pools_;\r
        \r
        GLuint fbo_;\r
 \r
-       executor& executor_;\r
-       executor  host_alloc_executor_;\r
+       executor& render_executor_;\r
+       executor  alloc_executor_;\r
                                \r
        impl(executor& executor) \r
-               : executor_(executor)\r
-               , host_alloc_executor_(L"OpenGL allocation device")\r
+               : render_executor_(executor)\r
+               , alloc_executor_(L"OpenGL allocation context.")\r
        {\r
                if(g_count++ > 1)\r
                        CASPAR_LOG(warning) << L"Multiple OGL devices.";\r
 \r
                CASPAR_LOG(info) << L"Initializing OpenGL Device.";\r
                \r
-               auto ctx1 = executor_.invoke([=]() -> HGLRC \r
+               auto ctx1 = render_executor_.invoke([=]() -> HGLRC \r
                {\r
                        device_.reset(new sf::Context());\r
                        device_->SetActive(true);               \r
@@ -95,7 +101,7 @@ struct device::impl : public std::enable_shared_from_this<impl>
                        return ctx1;\r
                });\r
 \r
-               host_alloc_executor_.invoke([=]\r
+               alloc_executor_.invoke([=]\r
                {\r
                        host_alloc_device_.reset(new sf::Context());\r
                        host_alloc_device_->SetActive(true);    \r
@@ -105,7 +111,7 @@ struct device::impl : public std::enable_shared_from_this<impl>
                                BOOST_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Failed to share OpenGL devices."));\r
                });\r
 \r
-               executor_.invoke([=]\r
+               render_executor_.invoke([=]\r
                {               \r
                        device_->SetActive(true);\r
                });\r
@@ -115,14 +121,14 @@ struct device::impl : public std::enable_shared_from_this<impl>
 \r
        ~impl()\r
        {\r
-               host_alloc_executor_.invoke([=]\r
+               alloc_executor_.invoke([=]\r
                {\r
                        host_alloc_device_.reset();\r
                        BOOST_FOREACH(auto& pool, host_pools_)\r
                                pool.clear();\r
                });\r
 \r
-               executor_.invoke([=]\r
+               render_executor_.invoke([=]\r
                {\r
                        BOOST_FOREACH(auto& pool, device_pools_)\r
                                pool.clear();\r
@@ -131,135 +137,131 @@ struct device::impl : public std::enable_shared_from_this<impl>
                        device_.reset();\r
                });\r
        }\r
-\r
-       spl::shared_ptr<device_buffer> allocate_device_buffer(int width, int height, int stride)\r
-       {\r
-               return executor_.invoke([&]() -> spl::shared_ptr<device_buffer>\r
+               \r
+       std::wstring version()\r
+       {       \r
+               try\r
                {\r
-                       try\r
+                       return alloc_executor_.invoke([]\r
                        {\r
-                               return spl::make_shared<device_buffer>(width, height, stride);\r
-                       }\r
-                       catch(...)\r
-                       {\r
-                               CASPAR_LOG(error) << L"ogl: create_device_buffer failed!";\r
-                               throw;\r
-                       }\r
-               });\r
+                               return u16(reinterpret_cast<const char*>(GL2(glGetString(GL_VERSION)))) + L" " + u16(reinterpret_cast<const char*>(GL2(glGetString(GL_VENDOR))));\r
+                       });     \r
+               }\r
+               catch(...)\r
+               {\r
+                       return L"Not found";;\r
+               }\r
        }\r
-                               \r
-       spl::shared_ptr<device_buffer> create_device_buffer(int width, int height, int stride)\r
+                                                       \r
+       spl::shared_ptr<texture> create_texture(int width, int height, int stride)\r
        {\r
                CASPAR_VERIFY(stride > 0 && stride < 5);\r
                CASPAR_VERIFY(width > 0 && height > 0);\r
                \r
                auto pool = &device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
                \r
-               std::shared_ptr<device_buffer> buffer;\r
+               std::shared_ptr<texture> buffer;\r
                if(!pool->try_pop(buffer))              \r
-                       buffer = allocate_device_buffer(width, height, stride);         \r
+                       buffer = spl::make_shared<texture>(width, height, stride);\r
        \r
-               auto self = shared_from_this();\r
-               return spl::shared_ptr<device_buffer>(buffer.get(), [self, buffer, pool](device_buffer*) mutable\r
+               return spl::shared_ptr<texture>(buffer.get(), [buffer, pool](texture*) mutable\r
                {               \r
                        pool->push(buffer);     \r
                });\r
        }\r
-\r
-       spl::shared_ptr<host_buffer> allocate_host_buffer(int size, host_buffer::usage usage)\r
-       {\r
-               return host_alloc_executor_.invoke([=]() -> spl::shared_ptr<host_buffer>\r
-               {\r
-                       try\r
-                       {\r
-                               auto buffer = spl::make_shared<host_buffer>(size, usage);\r
-                               if(usage == host_buffer::usage::write_only)\r
-                                       buffer->map();\r
-                               else\r
-                                       buffer->unmap();        \r
-\r
-                               return buffer;\r
-                       }\r
-                       catch(...)\r
-                       {\r
-                               CASPAR_LOG(error) << L"ogl: create_host_buffer failed!";\r
-                               throw;  \r
-                       }\r
-               });\r
-       }\r
-       \r
-       spl::shared_ptr<host_buffer> create_host_buffer(int size, host_buffer::usage usage)\r
+               \r
+       spl::shared_ptr<buffer> create_buffer(int size, buffer::usage usage)\r
        {\r
-               CASPAR_VERIFY(usage == host_buffer::usage::write_only || usage == host_buffer::usage::read_only);\r
                CASPAR_VERIFY(size > 0);\r
                \r
                auto pool = &host_pools_[usage.value()][size];\r
                \r
-               std::shared_ptr<host_buffer> buffer;\r
-               if(!pool->try_pop(buffer))      \r
-                       buffer = allocate_host_buffer(size, usage);     \r
-       \r
-               bool is_write = (usage == host_buffer::usage::write_only);\r
-\r
-               auto self = shared_from_this();\r
-               return spl::shared_ptr<host_buffer>(buffer.get(), [self, is_write, buffer, pool](host_buffer*) mutable\r
+               std::shared_ptr<buffer> buf;\r
+               if(!pool->try_pop(buf)) \r
                {\r
-                       self->host_alloc_executor_.begin_invoke([=]() mutable\r
-                       {               \r
-                               if(is_write)                            \r
-                                       buffer->map();                          \r
-                               else\r
-                                       buffer->unmap();\r
+                       buf = alloc_executor_.invoke([&]\r
+                       {\r
+                               return spl::make_shared<buffer>(size, usage);\r
+                       });\r
+               }\r
+                               \r
+               auto ptr = buf->data();\r
+               auto self = shared_from_this(); // buffers can leave the device context, take a hold on life-time.\r
+\r
+               auto on_release = [self, buf, ptr, usage, pool]() mutable\r
+               {               \r
+                       if(usage == buffer::usage::write_only)                                  \r
+                               buf->map();                                     \r
+                       else\r
+                               buf->unmap();\r
 \r
-                               pool->push(buffer);\r
-                       }, task_priority::high_priority);       \r
+                       self->texture_mapping_.erase(buf.get());\r
 \r
-                       self->executor_.begin_invoke([=]\r
-                       {\r
-                               write_buffer_transfer_cache_.erase(buffer.get());                               \r
-                       }, task_priority::high_priority);       \r
+                       pool->push(buf);\r
+               };\r
+               \r
+               return spl::shared_ptr<buffer>(buf.get(), [=](buffer*) mutable\r
+               {\r
+                       self->alloc_executor_.begin_invoke(on_release); \r
                });\r
        }\r
-               \r
-       std::wstring version()\r
-       {       \r
-               static std::wstring ver = L"Not found";\r
-               try\r
+\r
+       core::mutable_array create_array(int size)\r
+       {               \r
+               auto buf = create_buffer(size, buffer::usage::write_only);\r
+               return core::mutable_array(buf->data(), buf->size(), buf);\r
+       }\r
+\r
+       boost::unique_future<spl::shared_ptr<texture>> copy_async(const core::mutable_array& source, int width, int height, int stride)\r
+       {\r
+               auto buf = boost::any_cast<spl::shared_ptr<buffer>>(source.storage());\r
+                               \r
+               return render_executor_.begin_invoke([=]() -> spl::shared_ptr<texture>\r
                {\r
-                       ver = u16(executor_.invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VERSION)));})\r
-                       + " "   + executor_.invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));}));                    \r
-               }\r
-               catch(...){}\r
+                       tbb::concurrent_hash_map<buffer*, std::shared_ptr<texture>>::const_accessor a;\r
+                       if(texture_mapping_.find(a, buf.get()))\r
+                               return spl::make_shared_ptr(a->second);\r
+\r
+                       auto texture = create_texture(width, height, stride);\r
+                       texture->copy_from(*buf);       \r
+\r
+                       texture_mapping_.insert(std::make_pair(buf.get(), texture));\r
+\r
+                       return texture;\r
 \r
-               return ver;\r
+               }, task_priority::high_priority);\r
        }\r
-                       \r
-       boost::unique_future<spl::shared_ptr<device_buffer>> copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride)\r
+\r
+       boost::unique_future<core::const_array> copy_async(const spl::shared_ptr<texture>& source)\r
        {\r
-               return executor_.begin_invoke([=]() -> spl::shared_ptr<device_buffer>\r
+               return fold(render_executor_.begin_invoke([=]() -> boost::shared_future<core::const_array>\r
                {\r
-                       auto buffer_it = write_buffer_transfer_cache_.find(source.get());\r
-                       if(buffer_it == write_buffer_transfer_cache_.end())\r
+                       auto buffer = create_buffer(source->size(), buffer::usage::read_only); \r
+                       source->copy_to(*buffer);       \r
+\r
+                       return make_shared(async(launch_policy::deferred, [=]() mutable -> core::const_array\r
                        {\r
-                               auto result = create_device_buffer(width, height, stride);\r
-                               result->copy_from(*source);\r
-                               buffer_it = write_buffer_transfer_cache_.insert(std::make_pair(source.get(), result)).first;\r
-                       }\r
-                       return buffer_it->second;\r
-               }, task_priority::high_priority);\r
+                               const auto& buf = buffer.get();\r
+                               if(!buf->data())\r
+                                       alloc_executor_.invoke(std::bind(&buffer::map, std::ref(buf))); // Defer blocking "map" call until data is needed.\r
+\r
+                               return core::const_array(buf->data(), buf->size(), buffer);\r
+                       }));\r
+               }, task_priority::high_priority));\r
        }\r
 };\r
 \r
 device::device() \r
-       : executor_(L"device")\r
+       : executor_(L"OpenGL Rendering Context.")\r
        , impl_(new impl(executor_))\r
 {\r
 }\r
-       \r
-spl::shared_ptr<device_buffer>                                                 device::create_device_buffer(int width, int height, int stride){return impl_->create_device_buffer(width, height, stride);}\r
-spl::shared_ptr<host_buffer>                                                   device::create_host_buffer(int size, host_buffer::usage usage){return impl_->create_host_buffer(size, usage);}\r
-boost::unique_future<spl::shared_ptr<device_buffer>>   device::copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
-std::wstring                                                                                   device::version(){return impl_->version();}\r
+device::~device(){}    \r
+spl::shared_ptr<texture>                                                       device::create_texture(int width, int height, int stride){return impl_->create_texture(width, height, stride);}\r
+core::mutable_array                                                                    device::create_array(int size){return impl_->create_array(size);}\r
+boost::unique_future<spl::shared_ptr<texture>>         device::copy_async(const core::mutable_array& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
+boost::unique_future<core::const_array>                                device::copy_async(const spl::shared_ptr<texture>& source){return impl_->copy_async(source);}\r
+std::wstring                                                                           device::version(){return impl_->version();}\r
 \r
 \r
 }}}\r
index 540e510456381305b719870ffd0cac2e52c96331..3cacf6b0d9f13e2c8622d771eaf43a1794a6c638 100644 (file)
 \r
 #pragma once\r
 \r
-#include "host_buffer.h"\r
-#include "device_buffer.h"\r
+#include <core/frame/frame.h>\r
 \r
 #include <common/spl/memory.h>\r
-\r
-#include <boost/noncopyable.hpp>\r
-#include <boost/thread/future.hpp>\r
-\r
 #include <common/concurrency/executor.h>\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
-       \r
-class device : public std::enable_shared_from_this<device>, boost::noncopyable\r
+\r
+class texture;\r
+\r
+class device sealed : public std::enable_shared_from_this<device>\r
 {      \r
+       device(const device&);\r
+       device& operator=(const device&);\r
+\r
        executor executor_;\r
 public:                \r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
        device();\r
+       ~device();\r
+\r
+       // Methods\r
                \r
-       spl::shared_ptr<device_buffer>                                                  create_device_buffer(int width, int height, int stride);\r
-       spl::shared_ptr<host_buffer>                                                    create_host_buffer(int size, host_buffer::usage usage);\r
+       spl::shared_ptr<texture> create_texture(int width, int height, int stride);\r
+       core::mutable_array              create_array(int size);\r
 \r
-       boost::unique_future<spl::shared_ptr<device_buffer>>    copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride);\r
+       boost::unique_future<spl::shared_ptr<texture>> copy_async(const core::mutable_array& source, int width, int height, int stride);\r
+       boost::unique_future<core::const_array>            copy_async(const spl::shared_ptr<texture>& source);\r
        \r
-       std::wstring version();\r
-\r
        template<typename Func>\r
        auto begin_invoke(Func&& func, task_priority priority = task_priority::normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
        {                       \r
@@ -57,6 +64,11 @@ public:
        {\r
                return executor_.invoke(std::forward<Func>(func), priority);\r
        }\r
+\r
+       // Properties\r
+       \r
+       std::wstring version();\r
+\r
 private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
index aa585123287058225335fee7fea77e0226892339..d4e6b4712cd6e14991e7adc919fcad97a35ac399 100644 (file)
@@ -139,8 +139,8 @@ public:
        }\r
 };\r
 \r
-\r
 shader::shader(const std::string& vertex_source_str, const std::string& fragment_source_str) : impl_(new impl(vertex_source_str, fragment_source_str)){}\r
+shader::~shader(){}\r
 void shader::set(const std::string& name, bool value){impl_->set(name, value);}\r
 void shader::set(const std::string& name, int value){impl_->set(name, value);}\r
 void shader::set(const std::string& name, float value){impl_->set(name, value);}\r
index d1e7f24de208e57aab6c97f6e9a396e3811303e4..7b02ffa44ccab0520ad418672c0d0cc36257e806 100644 (file)
 \r
 #include <common/spl/memory.h>\r
 \r
-#include <boost/noncopyable.hpp>\r
-\r
 #include <string>\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
                \r
-class shader : boost::noncopyable\r
+class shader sealed\r
 {\r
+       shader(const shader&);\r
+       shader& operator=(const shader&);\r
 public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
        shader(const std::string& vertex_source_str, const std::string& fragment_source_str);\r
+       ~shader();\r
+\r
+       // Methods\r
+\r
        void set(const std::string& name, bool value);\r
        void set(const std::string& name, int value);\r
        void set(const std::string& name, float value);\r
        void set(const std::string& name, double value);\r
        void use() const;\r
-private:\r
-       friend class device;\r
-       struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
 \r
+       // Properties\r
+       \r
        int id() const;\r
+\r
+private:\r
+       struct impl;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
similarity index 73%
rename from accelerator/ogl/util/device_buffer.cpp
rename to accelerator/ogl/util/texture.cpp
index d9b317b421f754dcf53a12f59dee9ce5972fb026..f02ff1b0b6c56ad8908fa161ef7a002b552d02b2 100644 (file)
@@ -21,8 +21,9 @@
 \r
 #include "../../stdafx.h"\r
 \r
-#include "device_buffer.h"\r
-#include "device.h"\r
+#include "texture.h"\r
+\r
+#include "buffer.h"\r
 \r
 #include <common/except.h>\r
 #include <common/gl/gl_check.h>\r
@@ -46,7 +47,7 @@ unsigned int format(int stride)
 \r
 static tbb::atomic<int> g_total_count;\r
 \r
-struct device_buffer::impl : boost::noncopyable\r
+struct texture::impl : boost::noncopyable\r
 {\r
        GLuint                                          id_;\r
 \r
@@ -67,7 +68,7 @@ public:
                GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\r
                GL(glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT[stride_], width_, height_, 0, FORMAT[stride_], TYPE[stride_], NULL));\r
                GL(glBindTexture(GL_TEXTURE_2D, 0));\r
-               CASPAR_LOG(trace) << "[device_buffer] [" << ++g_total_count << L"] allocated size:" << width*height*stride;     \r
+               //CASPAR_LOG(trace) << "[texture] [" << ++g_total_count << L"] allocated size:" << width*height*stride; \r
        }       \r
 \r
        ~impl()\r
@@ -102,7 +103,7 @@ public:
                GL(glClear(GL_COLOR_BUFFER_BIT));\r
        }\r
                \r
-       void copy_from(host_buffer& source)\r
+       void copy_from(buffer& source)\r
        {\r
                source.unmap();\r
                source.bind();\r
@@ -112,7 +113,7 @@ public:
                source.unbind();\r
        }\r
 \r
-       void copy_to(host_buffer& dest)\r
+       void copy_to(buffer& dest)\r
        {\r
                dest.unmap();\r
                dest.bind();\r
@@ -125,16 +126,18 @@ public:
        }\r
 };\r
 \r
-device_buffer::device_buffer(int width, int height, int stride) : impl_(new impl(width, height, stride)){}\r
-int device_buffer::stride() const { return impl_->stride_; }\r
-int device_buffer::width() const { return impl_->width_; }\r
-int device_buffer::height() const { return impl_->height_; }\r
-void device_buffer::bind(int index){impl_->bind(index);}\r
-void device_buffer::unbind(){impl_->unbind();}\r
-void device_buffer::attach(){impl_->attach();}\r
-void device_buffer::clear(){impl_->clear();}\r
-void device_buffer::copy_from(host_buffer& source){impl_->copy_from(source);}\r
-void device_buffer::copy_to(host_buffer& dest){impl_->copy_to(dest);}\r
-int device_buffer::id() const{ return impl_->id_;}\r
+texture::texture(int width, int height, int stride) : impl_(new impl(width, height, stride)){}\r
+texture::~texture(){}\r
+void texture::bind(int index){impl_->bind(index);}\r
+void texture::unbind(){impl_->unbind();}\r
+void texture::attach(){impl_->attach();}\r
+void texture::clear(){impl_->clear();}\r
+void texture::copy_from(buffer& source){impl_->copy_from(source);}\r
+void texture::copy_to(buffer& dest){impl_->copy_to(dest);}\r
+int texture::width() const { return impl_->width_; }\r
+int texture::height() const { return impl_->height_; }\r
+int texture::size() const { return impl_->width_*impl_->height_*impl_->stride_; }\r
+int texture::stride() const { return impl_->stride_; }\r
+int texture::id() const{ return impl_->id_;}\r
 \r
 }}}
\ No newline at end of file
similarity index 75%
rename from accelerator/ogl/util/device_buffer.h
rename to accelerator/ogl/util/texture.h
index c827d11e1681b4e7d270c1f69a15f94ef748448c..8817a1249f2123585e4337907734b3aa1101d926 100644 (file)
 #include <common/spl/memory.h>\r
 #include <common/forward.h>\r
 \r
-#include <boost/noncopyable.hpp>\r
-\r
 FORWARD1(boost, template<typename> class unique_future);\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
                \r
-class host_buffer;\r
+class buffer;\r
 class device;\r
 \r
-class device_buffer : boost::noncopyable\r
+class texture sealed\r
 {\r
+       texture(const texture&);\r
+       texture& operator=(const texture&);\r
 public:        \r
-       device_buffer(int width, int height, int stride);\r
 \r
-       int stride() const;     \r
-       int width() const;\r
-       int height() const;\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
+       texture(int width, int height, int stride);\r
+       ~texture();\r
+\r
+       // Methods\r
                \r
-       void copy_from(host_buffer& source);\r
-       void copy_to(host_buffer& dest);\r
+       void copy_from(buffer& source);\r
+       void copy_to(buffer& dest);\r
                        \r
        void attach();\r
        void clear();\r
        void bind(int index);\r
        void unbind();\r
+\r
+       // Properties\r
+\r
+       int width() const;\r
+       int height() const;\r
+       int size() const;\r
+       int stride() const;     \r
        int id() const;\r
 private:\r
        struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
        \r
 unsigned int format(int stride);\r
index 492b9283938fd58b5c8c9827d0bfc412e823071a..256f932936889a4a07f24c259dee4d5735e53d72 100644 (file)
 #pragma warning (disable : 4482) // nonstandard extension used: enum 'enum' used in qualified name\r
 #pragma warning (disable : 4503) // decorated name length exceeded, name was truncated\r
 #pragma warning (disable : 4512) // assignment operator could not be generated\r
-#pragma warning (disable : 4702) //  unreachable code\r
+#pragma warning (disable : 4702) // unreachable code\r
 #pragma warning (disable : 4714) // marked as __forceinline not inlined\r
-#pragma warning (disable : 4505) //  unreferenced local function has been removed\r
-#pragma warning (disable : 4481) //  nonstandard extension used: override specifier 'override'\r
+#pragma warning (disable : 4505) // unreferenced local function has been \r
+#pragma warning (disable : 4481) // nonstandard extension used: override specifier 'override'\r
+#pragma warning (disable : 4996) // function call with parameters that may be unsafe\r
 #endif\r
 \r
index 6963479b9fcc265ff663279fcdedabacd8cbaeb8..3a0f66beac1fa45daa2dda3e56cf6a6ea51af453 100644 (file)
@@ -86,4 +86,20 @@ auto async(F&& f) -> boost::unique_future<decltype(f())>
        return async(launch_policy::async, std::forward<F>(f));\r
 }\r
 \r
+template<typename T>\r
+auto make_shared(boost::unique_future<T>&& f) -> boost::shared_future<T>\r
+{      \r
+       return boost::shared_future<T>(std::move(f));\r
+}\r
+\r
+template<typename T>\r
+auto fold(boost::unique_future<T>&& f) -> boost::unique_future<decltype(f.get().get())>\r
+{\r
+       auto shared_f = make_shared(std::move(f));\r
+       return async(launch_policy::deferred, [=]() mutable\r
+       {\r
+               return shared_f.get().get();\r
+       });\r
+}\r
+\r
 }
\ No newline at end of file
index 6169dc831059326158f17a8a922df7826a1a461d..7f68ed6c0e6dce692550f519f450f74b81deed3c 100644 (file)
@@ -105,7 +105,7 @@ public:
        virtual ~executor() // noexcept\r
        {\r
                stop();\r
-               join();\r
+               thread_.join();\r
        }\r
 \r
        void set_capacity(size_t capacity) // noexcept\r
@@ -122,22 +122,13 @@ public:
                                \r
        void stop() // noexcept\r
        {\r
-               is_running_ = false;    \r
-               execution_queue_[task_priority::normal_priority].try_push([]{}); // Wake the execution thread.\r
+               invoke([this]{is_running_ = false;});\r
        }\r
 \r
        void wait() // noexcept\r
        {\r
                invoke([]{});\r
        }\r
-\r
-       void join()\r
-       {\r
-               if(boost::this_thread::get_id() == thread_.get_id())\r
-                       BOOST_THROW_EXCEPTION(invalid_operation());\r
-\r
-               thread_.join();\r
-       }\r
                                \r
        template<typename Func>\r
        auto begin_invoke(Func&& func, task_priority priority = task_priority::normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
index 76ec46d37389fdaf0986eff42686494c20391a9d..4aadbc5bdc7c00a9f6eaca863759c88b5328ec0b 100644 (file)
@@ -1,4 +1,4 @@
-////////////////////////////////////////////////////////////\r
+///////////////////////////\r
 //\r
 // SFML - Simple and Fast Multimedia Library\r
 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)\r
@@ -20,7 +20,7 @@
 //\r
 // 3. This notice may not be removed or altered from any source distribution.\r
 //\r
-////////////////////////////////////////////////////////////\r
+///////////////////////////\r
 \r
 #pragma once\r
 \r
index 16dc08127e202bee1eafbaff3439df2d81d2dd83..eff6723483a451134bb404e7f73c847637c1430c 100644 (file)
@@ -1,4 +1,4 @@
-////////////////////////////////////////////////////////////\r
+///////////////////////////\r
 //\r
 // SFML - Simple and Fast Multimedia Library\r
 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)\r
@@ -20,7 +20,7 @@
 //\r
 // 3. This notice may not be removed or altered from any source distribution.\r
 //\r
-////////////////////////////////////////////////////////////\r
+///////////////////////////\r
 \r
 #pragma once\r
 \r
index b6a1b5a044fa6d781bb269fa557a2ef126ea66ba..90989debce4d799ba91c63d9a49eb493d0705931 100644 (file)
@@ -26,7 +26,7 @@
 #include <common/except.h>\r
 \r
 #include <core/video_format.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <common/concurrency/async.h>\r
 \r
@@ -76,7 +76,7 @@ public:
                }); \r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const class data_frame>& frame) override                                        {return consumer_->send(frame);}\r
+       virtual bool send(const_frame frame) override                                                                                                   {return consumer_->send(std::move(frame));}\r
        virtual void initialize(const struct video_format_desc& format_desc, int channel_index) override        {return consumer_->initialize(format_desc, channel_index);}\r
        virtual std::wstring print() const override                                                                                                                     {return consumer_->print();}    \r
        virtual std::wstring name() const override                                                                                                                      {return consumer_->name();}\r
@@ -104,7 +104,7 @@ public:
                CASPAR_LOG(info) << str << L" Uninitialized.";\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const class data_frame>& frame) override                                        {return consumer_->send(frame);}\r
+       virtual bool send(const_frame frame) override                                                                                                   {return consumer_->send(std::move(frame));}\r
        virtual void initialize(const struct video_format_desc& format_desc, int channel_index) override        {return consumer_->initialize(format_desc, channel_index);}\r
        virtual std::wstring print() const override                                                                                                                     {return consumer_->print();}\r
        virtual std::wstring name() const override                                                                                                                      {return consumer_->name();}\r
@@ -125,7 +125,7 @@ public:
        {\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const class data_frame>& frame)                                 \r
+       virtual bool send(const_frame frame)                                    \r
        {\r
                try\r
                {\r
@@ -167,8 +167,8 @@ public:
 class cadence_guard : public frame_consumer\r
 {\r
        spl::shared_ptr<frame_consumer>         consumer_;\r
-       std::vector<int>                                audio_cadence_;\r
-       boost::circular_buffer<int>     sync_buffer_;\r
+       std::vector<int>                                        audio_cadence_;\r
+       boost::circular_buffer<std::size_t>     sync_buffer_;\r
 public:\r
        cadence_guard(const spl::shared_ptr<frame_consumer>& consumer)\r
                : consumer_(consumer)\r
@@ -178,18 +178,18 @@ public:
        virtual void initialize(const video_format_desc& format_desc, int channel_index) override\r
        {\r
                audio_cadence_  = format_desc.audio_cadence;\r
-               sync_buffer_    = boost::circular_buffer<int>(format_desc.audio_cadence.size());\r
+               sync_buffer_    = boost::circular_buffer<std::size_t>(format_desc.audio_cadence.size());\r
                consumer_->initialize(format_desc, channel_index);\r
        }\r
 \r
-       virtual bool send(const spl::shared_ptr<const data_frame>& frame) override\r
+       virtual bool send(const_frame frame) override\r
        {               \r
                if(audio_cadence_.size() == 1)\r
                        return consumer_->send(frame);\r
 \r
                bool result = true;\r
                \r
-               if(boost::range::equal(sync_buffer_, audio_cadence_) && audio_cadence_.front() == static_cast<int>(frame->audio_data().size())) \r
+               if(boost::range::equal(sync_buffer_, audio_cadence_) && audio_cadence_.front() == static_cast<int>(frame.audio_data().size())) \r
                {       \r
                        // Audio sent so far is in sync, now we can send the next chunk.\r
                        result = consumer_->send(frame);\r
@@ -198,7 +198,7 @@ public:
                else\r
                        CASPAR_LOG(trace) << print() << L" Syncing audio.";\r
 \r
-               sync_buffer_.push_back(static_cast<int>(frame->audio_data().size()));\r
+               sync_buffer_.push_back(static_cast<int>(frame.audio_data().size()));\r
                \r
                return result;\r
        }\r
@@ -245,7 +245,7 @@ const spl::shared_ptr<frame_consumer>& frame_consumer::empty()
        class empty_frame_consumer : public frame_consumer\r
        {\r
        public:\r
-               virtual bool send(const spl::shared_ptr<const data_frame>&) override {return false;}\r
+               virtual bool send(const_frame) override {return false;}\r
                virtual void initialize(const video_format_desc&, int) override{}\r
                virtual std::wstring print() const override {return L"empty";}\r
                virtual std::wstring name() const override {return L"empty";}\r
index 39ee733ab2d88fb76bb3dfccb3469c1627eda923..c9fd5921289c1800cb4bae63bcb523602a71e428 100644 (file)
 \r
 namespace caspar { namespace core {\r
        \r
-/// Interface\r
+// Interface\r
 class frame_consumer\r
 {\r
        frame_consumer(const frame_consumer&);\r
        frame_consumer& operator=(const frame_consumer&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
        \r
        static const spl::shared_ptr<frame_consumer>& empty();\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        frame_consumer(){}\r
        virtual ~frame_consumer() {}\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
-       virtual bool                                                    send(const spl::shared_ptr<const class data_frame>& frame) = 0;\r
+       virtual bool                                                    send(class const_frame frame) = 0;\r
        virtual void                                                    initialize(const struct video_format_desc& format_desc, int channel_index) = 0;\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        virtual std::wstring                                    print() const = 0;\r
        virtual std::wstring                                    name() const = 0;\r
index a416f8607790c9fbd288a094435eee2f4dc982de..9bc1a59b61f38ca745a61ec35ef07cf45098ff17 100644 (file)
@@ -30,7 +30,7 @@
 #include "frame_consumer.h"\r
 \r
 #include "../video_format.h"\r
-#include "../frame/data_frame.h"\r
+#include "../frame/frame.h"\r
 \r
 #include <common/concurrency/async.h>\r
 #include <common/concurrency/executor.h>\r
@@ -50,13 +50,13 @@ namespace caspar { namespace core {
        \r
 struct output::impl\r
 {              \r
-       spl::shared_ptr<diagnostics::graph>                                                     graph_;\r
-       const int                                                                                                       channel_index_;\r
-       video_format_desc                                                                                       format_desc_;\r
-       std::map<int, spl::shared_ptr<frame_consumer>>                          consumers_;     \r
-       prec_timer                                                                                                      sync_timer_;\r
-       boost::circular_buffer<spl::shared_ptr<const data_frame>>       frames_;\r
-       executor                                                                                                        executor_;              \r
+       spl::shared_ptr<diagnostics::graph>                             graph_;\r
+       const int                                                                               channel_index_;\r
+       video_format_desc                                                               format_desc_;\r
+       std::map<int, spl::shared_ptr<frame_consumer>>  consumers_;     \r
+       prec_timer                                                                              sync_timer_;\r
+       boost::circular_buffer<const_frame>             frames_;\r
+       executor                                                                                executor_;              \r
 public:\r
        impl(spl::shared_ptr<diagnostics::graph> graph, const video_format_desc& format_desc, int channel_index) \r
                : graph_(std::move(graph))\r
@@ -146,7 +146,7 @@ public:
                return boost::range::count_if(consumers_ | boost::adaptors::map_values, [](const spl::shared_ptr<frame_consumer>& x){return x->has_synchronization_clock();}) > 0;\r
        }\r
                \r
-       void operator()(spl::shared_ptr<const data_frame> input_frame, const core::video_format_desc& format_desc)\r
+       void operator()(const_frame input_frame, const core::video_format_desc& format_desc)\r
        {\r
                video_format_desc(format_desc);\r
 \r
@@ -157,8 +157,7 @@ public:
                        if(!has_synchronization_clock())\r
                                sync_timer_.tick(1.0/format_desc_.fps);\r
                                \r
-                       if(input_frame->width() != format_desc_.width ||\r
-                          input_frame->height() != format_desc_.height)\r
+                       if(input_frame.size() != format_desc_.size)\r
                        {\r
                                sync_timer_.tick(1.0/format_desc_.fps);\r
                                return;\r
@@ -216,5 +215,5 @@ void output::add(const spl::shared_ptr<frame_consumer>& consumer){impl_->add(con
 void output::remove(int index){impl_->remove(index);}\r
 void output::remove(const spl::shared_ptr<frame_consumer>& consumer){impl_->remove(consumer);}\r
 boost::unique_future<boost::property_tree::wptree> output::info() const{return impl_->info();}\r
-void output::operator()(spl::shared_ptr<const data_frame> frame, const video_format_desc& format_desc){(*impl_)(std::move(frame), format_desc);}\r
+void output::operator()(const_frame frame, const video_format_desc& format_desc){(*impl_)(std::move(frame), format_desc);}\r
 }}
\ No newline at end of file
index 78dbe744402edc3dfefd1d9dfdb4e14be635d41d..24b92d09e7a593a99274f94512396c884e226525 100644 (file)
@@ -38,22 +38,22 @@ class output sealed
        output& operator=(const output&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        explicit output(spl::shared_ptr<diagnostics::graph> graph, const struct video_format_desc& format_desc, int channel_index);\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
-       void operator()(spl::shared_ptr<const class data_frame> frame, const struct video_format_desc& format_desc);\r
+       void operator()(class const_frame frame, const struct video_format_desc& format_desc);\r
        \r
        void add(const spl::shared_ptr<class frame_consumer>& consumer);\r
        void add(int index, const spl::shared_ptr<class frame_consumer>& consumer);\r
        void remove(const spl::shared_ptr<class frame_consumer>& consumer);\r
        void remove(int index);\r
        \r
-       /// Properties\r
+       // Properties\r
 \r
        boost::unique_future<boost::property_tree::wptree> info() const;\r
 \r
index 3094dd60a7dd65e0ad29dbe0fd768ae759ccf21b..cec7204420b300c6c7d16d9bdf69a1eabf459f23 100644 (file)
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ClInclude Include="frame\draw_frame.h" />\r
-    <ClInclude Include="frame\data_frame.h" />\r
+    <ClInclude Include="frame\frame.h" />\r
     <ClInclude Include="frame\frame_factory.h" />\r
     <ClInclude Include="frame\frame_transform.h" />\r
     <ClInclude Include="frame\frame_visitor.h" />\r
     <ClInclude Include="StdAfx.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="frame\data_frame.cpp">\r
+    <ClCompile Include="frame\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
index 0fc9cfb1bba8c87204ac9b1dbb39e03278034a08..ce6033f7b39b05ab819e9b86913f6cdeb54cacfe 100644 (file)
     <ClInclude Include="frame\pixel_format.h">\r
       <Filter>source\frame</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="frame\data_frame.h">\r
-      <Filter>source\frame</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="frame\draw_frame.h">\r
       <Filter>source\frame</Filter>\r
     </ClInclude>\r
     <ClInclude Include="monitor\monitor.h">\r
       <Filter>source\monitor</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="frame\frame.h">\r
+      <Filter>source\frame</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="producer\transition\transition_producer.cpp">\r
     <ClCompile Include="frame\draw_frame.cpp">\r
       <Filter>source\frame</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="frame\data_frame.cpp">\r
-      <Filter>source\frame</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="monitor\monitor.cpp">\r
       <Filter>source\monitor</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="frame\frame.cpp">\r
+      <Filter>source\frame</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/core/frame/data_frame.cpp b/core/frame/data_frame.cpp
deleted file mode 100644 (file)
index e0bc316..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "../StdAfx.h"\r
-\r
-#include "data_frame.h"\r
-\r
-#include "pixel_format.h"\r
-\r
-namespace caspar { namespace core {\r
-       \r
-spl::shared_ptr<data_frame> data_frame::empty()\r
-{\r
-       class empty_frame : public data_frame\r
-       {\r
-       public:\r
-               empty_frame(){}\r
-               virtual const struct core::pixel_format_desc& pixel_format_desc() const override\r
-               {\r
-                       static core::pixel_format_desc invalid(pixel_format::invalid);\r
-                       return invalid;\r
-               }\r
-               virtual const boost::iterator_range<const uint8_t*> image_data(int) const override\r
-               {\r
-                       return boost::iterator_range<const uint8_t*>();\r
-               }\r
-               virtual audio_buffer& audio_data() const override\r
-               {\r
-                       static audio_buffer buffer;\r
-                       return buffer;\r
-               }\r
-               const boost::iterator_range<uint8_t*> image_data(int) override\r
-               {\r
-                       return boost::iterator_range<uint8_t*>();\r
-               }\r
-               audio_buffer& audio_data() override\r
-               {\r
-                       static audio_buffer buffer;\r
-                       return buffer;\r
-               }\r
-               virtual double frame_rate() const override\r
-               {\r
-                       return 0.0;\r
-               }\r
-               virtual core::field_mode field_mode() const override\r
-               {\r
-                       return core::field_mode::empty;\r
-               }\r
-               virtual int width() const override\r
-               {\r
-                       return 0;\r
-               }\r
-               virtual int height() const override\r
-               {\r
-                       return 0;\r
-               }\r
-               virtual const void* tag() const override\r
-               {\r
-                       return 0;\r
-               }\r
-       };\r
-\r
-       static spl::shared_ptr<empty_frame> empty;\r
-       return empty;\r
-}\r
-\r
-}}
\ No newline at end of file
diff --git a/core/frame/data_frame.h b/core/frame/data_frame.h
deleted file mode 100644 (file)
index a59e910..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once\r
-\r
-#include <common/spl/memory.h>\r
-\r
-#include <boost/range.hpp>\r
-\r
-#include <tbb/cache_aligned_allocator.h>\r
-\r
-#include <stdint.h>\r
-\r
-#include "../video_format.h"\r
-\r
-namespace caspar { namespace core {\r
-       \r
-typedef std::vector<int32_t, tbb::cache_aligned_allocator<int32_t>> audio_buffer;\r
-\r
- /// Interface\r
-class data_frame\r
-{\r
-       data_frame(const data_frame&);\r
-       data_frame& operator=(const data_frame&);\r
-public:\r
-       /// Static Members\r
-       \r
-       static spl::shared_ptr<data_frame> empty();\r
-\r
-       ///  Constructors\r
-\r
-       data_frame(){}\r
-       virtual ~data_frame(){}\r
-\r
-       /// Methods\r
-\r
-       /// Properties\r
-\r
-       virtual const struct pixel_format_desc&                         pixel_format_desc() const = 0;\r
-\r
-       virtual const boost::iterator_range<const uint8_t*> image_data(int index = 0) const = 0;\r
-       virtual const boost::iterator_range<uint8_t*>           image_data(int index) = 0;\r
-\r
-       virtual const audio_buffer&                                                     audio_data() const = 0; \r
-       virtual audio_buffer&                                                           audio_data() = 0;\r
-\r
-       virtual double                                                                          frame_rate() const = 0;\r
-       virtual field_mode                                                                      field_mode() const = 0;\r
-\r
-       virtual int                                                                                     width() const = 0;\r
-       virtual int                                                                                     height() const = 0;\r
-\r
-       virtual const void*                                                                     tag() const = 0;\r
-};\r
-\r
-}}
\ No newline at end of file
index 5e90638fd888bde3261cbfcc126321fef3a6f19e..e4861ff8d11d8ce87f645e72bf22ef9fd343b6c7 100644 (file)
@@ -23,7 +23,7 @@
 \r
 #include "draw_frame.h"\r
 \r
-#include "data_frame.h"\r
+#include "frame.h"\r
 \r
 #include "frame_transform.h"\r
 \r
@@ -33,11 +33,11 @@ namespace caspar { namespace core {
                \r
 struct draw_frame::impl\r
 {              \r
-       int                                                                                                     tag_;\r
-       std::vector<draw_frame>                                                         frames_;\r
-       std::shared_ptr<spl::unique_ptr<const data_frame>>      data_frame_;\r
+       int                                                                     tag_;\r
+       std::vector<draw_frame>                         frames_;\r
+       std::shared_ptr<mutable_frame>  frame_;\r
 \r
-       core::frame_transform frame_transform_;         \r
+       core::frame_transform                           frame_transform_;               \r
 public:                \r
        enum tags\r
        {\r
@@ -52,9 +52,9 @@ public:
        {\r
        }\r
 \r
-       impl(spl::unique_ptr<const data_frame>&& frame) \r
+       impl(mutable_frame&& frame) \r
                : tag_(frame_tag)\r
-               , data_frame_(new spl::unique_ptr<const data_frame>(std::move(frame)))\r
+               , frame_(new mutable_frame(std::move(frame)))\r
        {\r
        }\r
        \r
@@ -63,13 +63,21 @@ public:
                , frames_(std::move(frames))\r
        {\r
        }\r
-               \r
+\r
+       impl(const impl& other)\r
+               : tag_(other.tag_)\r
+               , frames_(other.frames_)\r
+               , frame_(other.frame_)\r
+               , frame_transform_(other.frame_transform_)\r
+       {\r
+       }\r
+                       \r
        void accept(frame_visitor& visitor) const\r
        {\r
                visitor.push(frame_transform_);\r
-               if(data_frame_)\r
+               if(frame_)\r
                {\r
-                       visitor.visit(**data_frame_);\r
+                       visitor.visit(*frame_);\r
                }\r
                else\r
                {\r
@@ -78,12 +86,12 @@ public:
                }\r
                visitor.pop();\r
        }       \r
-\r
+               \r
        bool operator==(const impl& other)\r
        {\r
                return  tag_ == other.tag_ && \r
                                frames_ == other.frames_ && \r
-                               data_frame_ == other.data_frame_;\r
+                               frame_ == other.frame_;\r
        }\r
 };\r
        \r
@@ -91,7 +99,7 @@ draw_frame::draw_frame() : impl_(new impl()){}
 draw_frame::draw_frame(int tag) : impl_(new impl(std::move(tag))){}\r
 draw_frame::draw_frame(const draw_frame& other) : impl_(new impl(*other.impl_)){}\r
 draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
-draw_frame::draw_frame(spl::unique_ptr<const data_frame>&& frame)  : impl_(new impl(std::move(frame))){}\r
+draw_frame::draw_frame(mutable_frame&& frame)  : impl_(new impl(std::move(frame))){}\r
 draw_frame::draw_frame(std::vector<draw_frame> frames) : impl_(new impl(frames)){}\r
 draw_frame::~draw_frame(){}\r
 draw_frame& draw_frame::operator=(draw_frame other)\r
index c1a15d97251aa526c54d650d728dcc4eae4bf604..f0855e9c5b09028596239ac16028ff0fe3daab09 100644 (file)
@@ -37,7 +37,7 @@ class draw_frame sealed
 {\r
        draw_frame(int tag);\r
 public:                \r
-       /// Static Members\r
+       // Static Members\r
 \r
        static draw_frame interlace(draw_frame frame1, draw_frame frame2, core::field_mode mode);\r
        static draw_frame over(draw_frame frame1, draw_frame frame2);\r
@@ -48,17 +48,17 @@ public:
        static const draw_frame& empty();\r
        static const draw_frame& late();\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        draw_frame();\r
        draw_frame(const draw_frame& other);\r
        draw_frame(draw_frame&& other); \r
-       explicit draw_frame(spl::unique_ptr<const data_frame>&& frame);\r
+       explicit draw_frame(class mutable_frame&& frame);\r
        explicit draw_frame(std::vector<draw_frame> frames);\r
 \r
        ~draw_frame();\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
        draw_frame& operator=(draw_frame other);\r
 \r
@@ -69,7 +69,7 @@ public:
        bool operator==(const draw_frame& other) const;\r
        bool operator!=(const draw_frame& other) const;\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        const core::frame_transform&    transform() const;\r
        core::frame_transform&                  transform();                    \r
diff --git a/core/frame/frame.cpp b/core/frame/frame.cpp
new file mode 100644 (file)
index 0000000..51b5cfa
--- /dev/null
@@ -0,0 +1,171 @@
+/*\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 "frame.h"\r
+\r
+#include <common/except.h>\r
+#include <core/frame/frame_visitor.h>\r
+#include <core/frame/pixel_format.h>\r
+\r
+#include <boost/lexical_cast.hpp>\r
+#include <boost/thread/future.hpp>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+const const_frame& const_frame::empty()\r
+{\r
+       static int dummy;\r
+       static const_frame empty(&dummy);\r
+       return empty;\r
+}\r
+\r
+struct const_frame::impl : boost::noncopyable\r
+{                      \r
+       mutable boost::shared_future<const_array>       future_buffer_;\r
+       int                                                                                     id_;\r
+       core::audio_buffer                                                      audio_data_;\r
+       const core::pixel_format_desc                           desc_;\r
+       const void*                                                                     tag_;\r
+       double                                                                          frame_rate_;\r
+       core::field_mode                                                        field_mode_;\r
+\r
+       impl(const void* tag)\r
+               : desc_(core::pixel_format::invalid)\r
+               , tag_(tag)     \r
+               , id_(0)\r
+               , field_mode_(core::field_mode::empty)\r
+       {\r
+       }\r
+       \r
+       impl(boost::shared_future<const_array> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+               : future_buffer_(std::move(image))\r
+               , audio_data_(std::move(audio_buffer))\r
+               , desc_(desc)\r
+               , tag_(tag)\r
+               , id_(reinterpret_cast<int>(this))\r
+               , frame_rate_(frame_rate)\r
+               , field_mode_(field_mode)\r
+       {\r
+               if(desc.format != core::pixel_format::bgra)\r
+                       BOOST_THROW_EXCEPTION(not_implemented());\r
+       }\r
+\r
+       const_array image_data() const\r
+       {\r
+               return tag_ != empty().tag() ? future_buffer_.get() : const_array(nullptr, 0, 0);\r
+       }\r
+\r
+       std::size_t width() const\r
+       {\r
+               return tag_ != empty().tag() ? desc_.planes.at(0).width : 0;\r
+       }\r
+\r
+       std::size_t height() const\r
+       {\r
+               return tag_ != empty().tag() ? desc_.planes.at(0).height : 0;\r
+       }\r
+\r
+       std::size_t size() const\r
+       {\r
+               return tag_ != empty().tag() ? desc_.planes.at(0).size : 0;\r
+       }\r
+\r
+       bool operator==(const impl& other)\r
+       {\r
+               return tag_ == other.tag_ && id_ == other.id_;\r
+       }\r
+};\r
+       \r
+const_frame::const_frame(const void* tag) : impl_(new impl(tag)){}\r
+const_frame::const_frame(boost::shared_future<const_array> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+       : impl_(new impl(std::move(image), std::move(audio_buffer), tag, desc, frame_rate, field_mode)){}\r
+const_frame::~const_frame(){}\r
+const_frame::const_frame(const_frame&& other) : impl_(std::move(other.impl_)){}\r
+const_frame& const_frame::operator=(const_frame&& other)\r
+{\r
+       impl_ = std::move(other.impl_);\r
+       return *this;\r
+}\r
+const_frame::const_frame(const const_frame& other) : impl_(other.impl_){}\r
+const_frame& const_frame::operator=(const const_frame& other)\r
+{\r
+       impl_ = other.impl_;\r
+       return *this;\r
+}\r
+bool const_frame::operator==(const const_frame& other){return *impl_ == *other.impl_;}\r
+bool const_frame::operator!=(const const_frame& other){return !(*this == other);}\r
+const core::pixel_format_desc& const_frame::pixel_format_desc()const{return impl_->desc_;}\r
+const_array const_frame::image_data()const{return impl_->image_data();}\r
+const core::audio_buffer& const_frame::audio_data()const{return impl_->audio_data_;}\r
+double const_frame::frame_rate()const{return impl_->frame_rate_;}\r
+core::field_mode const_frame::field_mode()const{return impl_->field_mode_;}\r
+std::size_t const_frame::width()const{return impl_->width();}\r
+std::size_t const_frame::height()const{return impl_->height();}        \r
+std::size_t const_frame::size()const{return impl_->size();}                                            \r
+const void* const_frame::tag()const{return impl_->tag_;}       \r
+\r
+struct mutable_frame::impl : boost::noncopyable\r
+{                      \r
+       std::vector<mutable_array>                                      buffers_;\r
+       core::audio_buffer                                                      audio_data_;\r
+       const core::pixel_format_desc                           desc_;\r
+       const void*                                                                     tag_;\r
+       double                                                                          frame_rate_;\r
+       core::field_mode                                                        field_mode_;\r
+       \r
+       impl(std::vector<mutable_array> buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+               : buffers_(std::move(buffers))\r
+               , audio_data_(std::move(audio_buffer))\r
+               , desc_(desc)\r
+               , tag_(tag)\r
+               , frame_rate_(frame_rate)\r
+               , field_mode_(field_mode)\r
+       {\r
+               BOOST_FOREACH(auto& buffer, buffers_)\r
+                       if(!buffer.data())\r
+                               BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("mutable_frame: null argument"));\r
+       }\r
+};\r
+       \r
+mutable_frame::mutable_frame(std::vector<mutable_array> image_buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+       : impl_(new impl(std::move(image_buffers), std::move(audio_buffer), tag, desc, frame_rate, field_mode)){}\r
+mutable_frame::~mutable_frame(){}\r
+mutable_frame::mutable_frame(mutable_frame&& other) : impl_(std::move(other.impl_)){}\r
+mutable_frame& mutable_frame::operator=(mutable_frame&& other)\r
+{\r
+       impl_ = std::move(other.impl_);\r
+       return *this;\r
+}\r
+void mutable_frame::swap(mutable_frame& other){impl_.swap(other.impl_);}\r
+const core::pixel_format_desc& mutable_frame::pixel_format_desc() const{return impl_->desc_;}\r
+const mutable_array& mutable_frame::image_data(std::size_t index) const{return impl_->buffers_.at(index);}\r
+const core::audio_buffer& mutable_frame::audio_data() const{return impl_->audio_data_;}\r
+mutable_array& mutable_frame::image_data(std::size_t index){return impl_->buffers_.at(index);}\r
+core::audio_buffer& mutable_frame::audio_data(){return impl_->audio_data_;}\r
+double mutable_frame::frame_rate() const{return impl_->frame_rate_;}\r
+core::field_mode mutable_frame::field_mode() const{return impl_->field_mode_;}\r
+std::size_t mutable_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
+std::size_t mutable_frame::height() const{return impl_->desc_.planes.at(0).height;}                                            \r
+const void* mutable_frame::tag() const{return impl_->tag_;}    \r
+\r
+}}
\ No newline at end of file
diff --git a/core/frame/frame.h b/core/frame/frame.h
new file mode 100644 (file)
index 0000000..e26fa13
--- /dev/null
@@ -0,0 +1,231 @@
+#pragma once\r
+\r
+#include "../video_format.h"\r
+\r
+#include <common/spl/memory.h>\r
+#include <common/forward.h>\r
+\r
+#include <boost/range.hpp>\r
+#include <boost/any.hpp>\r
+\r
+#include <tbb/cache_aligned_allocator.h>\r
+\r
+#include <cstddef>\r
+#include <stdint.h>\r
+\r
+FORWARD1(boost, template<typename> class shared_future);\r
+\r
+namespace caspar { namespace core {\r
+\r
+class const_array\r
+{\r
+public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
+       template<typename T>\r
+       explicit const_array(const uint8_t* ptr, std::size_t size, T&& storage)\r
+               : ptr_(ptr)\r
+               , size_(size)\r
+               , storage_(new boost::any(std::forward<T>(storage)))\r
+       {\r
+       }\r
+       \r
+       const_array(const const_array& other)\r
+               : ptr_(other.ptr_)\r
+               , size_(other.size_)\r
+               , storage_(other.storage_)\r
+       {\r
+       }\r
+\r
+       const_array(const_array&& other)\r
+               : ptr_(other.ptr_)\r
+               , size_(other.size_)\r
+               , storage_(std::move(other.storage_))\r
+       {\r
+       }\r
+\r
+       // Methods\r
+\r
+       const_array& operator=(const_array other)\r
+       {\r
+               other.swap(*this);\r
+               return *this;\r
+       }\r
+\r
+       void swap(const_array& other)\r
+       {\r
+               std::swap(ptr_, other.ptr_);\r
+               std::swap(size_, other.size_);\r
+               std::swap(storage_, other.storage_);\r
+       }\r
+\r
+       // Properties\r
+               \r
+       const uint8_t* begin() const    {return ptr_;}          \r
+       const uint8_t* data() const             {return ptr_;}\r
+       const uint8_t* end() const              {return ptr_ + size_;}\r
+       std::size_t size() const                {return size_;}\r
+       bool empty() const                              {return size() == 0;}\r
+               \r
+private:\r
+       const uint8_t*  ptr_;\r
+       std::size_t             size_;\r
+       spl::shared_ptr<boost::any>     storage_;\r
+};\r
+\r
+class mutable_array\r
+{\r
+       mutable_array(const mutable_array&);\r
+       mutable_array& operator=(const mutable_array&);\r
+public:\r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+       \r
+       template<typename T>\r
+       explicit mutable_array(uint8_t* ptr, std::size_t size, T&& storage)\r
+               : ptr_(ptr)\r
+               , size_(size)\r
+               , storage_(new boost::any(std::forward<T>(storage)))\r
+       {\r
+       }\r
+\r
+       mutable_array(mutable_array&& other)\r
+               : ptr_(other.ptr_)\r
+               , size_(other.size_)\r
+               , storage_(std::move(other.storage_))\r
+       {\r
+       }\r
+\r
+       // Methods\r
+\r
+       mutable_array& operator=(mutable_array&& other)\r
+       {\r
+               ptr_            = other.ptr_;\r
+               size_           = other.size_;\r
+               storage_        = std::move(other.storage_);\r
+               return *this;\r
+       }\r
+\r
+       // Properties\r
+       \r
+       uint8_t* begin()                                        {return ptr_;}          \r
+       uint8_t* data()                                         {return ptr_;}\r
+       uint8_t* end()                                          {return ptr_ + size_;}  \r
+       const uint8_t* begin() const            {return ptr_;}          \r
+       const uint8_t* data() const                     {return ptr_;}\r
+       const uint8_t* end() const                      {return ptr_ + size_;}\r
+       std::size_t size() const                        {return size_;}\r
+       bool empty() const                                      {return size() == 0;}\r
+       const boost::any& storage() const       {return *storage_;}\r
+private:\r
+       uint64_t        id_;\r
+       uint8_t*        ptr_;\r
+       std::size_t     size_;\r
+       spl::unique_ptr<boost::any>     storage_;\r
+};\r
+\r
+typedef std::vector<int32_t, tbb::cache_aligned_allocator<int32_t>> audio_buffer;\r
+\r
+class const_frame sealed\r
+{\r
+public:        \r
+\r
+       // Static Members\r
+\r
+       static const const_frame& empty();\r
+\r
+       // Constructors\r
+\r
+       explicit const_frame(const void* tag = nullptr);\r
+       explicit const_frame(boost::shared_future<const_array> image, \r
+                                               audio_buffer audio_buffer, \r
+                                               const void* tag, \r
+                                               const struct pixel_format_desc& desc, \r
+                                               double frame_rate, \r
+                                               core::field_mode field_mode);\r
+       ~const_frame();\r
+\r
+       // Methods\r
+\r
+       const_frame(const_frame&& other);\r
+       const_frame& operator=(const_frame&& other);\r
+       const_frame(const const_frame&);\r
+       const_frame& operator=(const const_frame& other);\r
+                               \r
+       // Properties\r
+                       \r
+       const struct pixel_format_desc& pixel_format_desc() const;\r
+\r
+       const_array image_data() const;\r
+       const core::audio_buffer& audio_data() const;\r
+               \r
+       double frame_rate() const;\r
+       core::field_mode field_mode() const;\r
+\r
+       std::size_t width() const;\r
+       std::size_t height() const;\r
+       std::size_t size() const;\r
+                                                               \r
+       const void* tag() const;\r
+\r
+       bool operator==(const const_frame& other);\r
+       bool operator!=(const const_frame& other);\r
+                       \r
+private:\r
+       struct impl;\r
+       spl::shared_ptr<impl> impl_;\r
+};\r
+\r
+class mutable_frame sealed\r
+{\r
+       mutable_frame(const mutable_frame&);\r
+       mutable_frame& operator=(const mutable_frame&);\r
+public:        \r
+\r
+       // Static Members\r
+\r
+       // Constructors\r
+\r
+       explicit mutable_frame(std::vector<mutable_array> image_buffers, \r
+                                               audio_buffer audio_buffer, \r
+                                               const void* tag, \r
+                                               const struct pixel_format_desc& desc, \r
+                                               double frame_rate, \r
+                                               core::field_mode field_mode);\r
+       ~mutable_frame();\r
+\r
+       // Methods\r
+\r
+       mutable_frame(mutable_frame&& other);\r
+       mutable_frame& operator=(mutable_frame&& other);\r
+\r
+       void swap(mutable_frame& other);\r
+                       \r
+       // Properties\r
+                       \r
+       const struct pixel_format_desc& pixel_format_desc() const;\r
+\r
+       const mutable_array& image_data(std::size_t index = 0) const;\r
+       const core::audio_buffer& audio_data() const;\r
+\r
+       mutable_array& image_data(std::size_t index = 0);\r
+       core::audio_buffer& audio_data();\r
+       \r
+       double frame_rate() const;\r
+       core::field_mode field_mode() const;\r
+\r
+       std::size_t width() const;\r
+       std::size_t height() const;\r
+                                                               \r
+       const void* tag() const;\r
+                       \r
+private:\r
+       struct impl;\r
+       spl::unique_ptr<impl> impl_;\r
+};\r
+}}
\ No newline at end of file
index ae575d1ea2888ced63b644e11d7106ac5df455f3..879cccc245b39a1624ca0ca117806c53574a58c0 100644 (file)
@@ -21,7 +21,7 @@
 \r
 #pragma once\r
 \r
-#include "data_frame.h"\r
+#include "frame.h"\r
 \r
 #include <common/spl/memory.h>\r
 \r
@@ -34,25 +34,23 @@ class frame_factory : boost::noncopyable
        frame_factory(const frame_factory&);\r
        frame_factory& operator=(const frame_factory&);\r
 public:\r
-       /// Static Members\r
+       // Static Members\r
 \r
-       //Constructors\r
+       // Constructors\r
 \r
        frame_factory(){}\r
        virtual ~frame_factory(){}\r
 \r
-       /// Methods\r
+       // Methods\r
 \r
-       virtual spl::unique_ptr<class data_frame>       create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;   \r
-       spl::unique_ptr<class data_frame>                       create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc)\r
+       virtual class mutable_frame     create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;   \r
+       class mutable_frame                     create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc)\r
        {\r
                auto format_desc = video_format_desc();\r
                return create_frame(video_stream_tag, desc, format_desc.fps, format_desc.field_mode);\r
        }\r
 \r
-       /// Properties\r
-\r
-       virtual struct video_format_desc video_format_desc() const = 0; \r
+       // Properties\r
 };\r
 \r
 }}
\ No newline at end of file
index e39ad4f45b4c3d2e995a24d32c3961a3d9985a71..ec0971f558067db120ee54de9d18428f9f64b37f 100644 (file)
@@ -28,20 +28,20 @@ class frame_visitor
        frame_visitor(const frame_visitor&);\r
        frame_visitor& operator=(const frame_visitor&);\r
 public:\r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        frame_visitor(){}\r
        virtual ~frame_visitor(){}\r
 \r
-       /// Methods\r
+       // Methods\r
 \r
        virtual void push(const struct frame_transform& transform) = 0;\r
-       virtual void visit(const class data_frame& frame) = 0;\r
+       virtual void visit(const class mutable_frame& frame) = 0;\r
        virtual void pop() = 0;\r
 \r
-       /// Properties\r
+       // Properties\r
 };\r
 \r
 }}
\ No newline at end of file
index e29dc2766e94ec913589d79def07d735f8eb8753..d14d9f2da44864ad8ccc039a7c7651df85f585dc 100644 (file)
@@ -25,6 +25,7 @@
 \r
 #include <common/enum_class.h>\r
 \r
+#include <cstddef>\r
 #include <vector>\r
 \r
 namespace caspar { namespace core {\r
@@ -55,23 +56,23 @@ struct pixel_format_desc sealed
                int width;\r
                int height;\r
                int size;\r
-               int channels;\r
+               int stride;\r
 \r
                plane() \r
                        : linesize(0)\r
                        , width(0)\r
                        , height(0)\r
                        , size(0)\r
-                       , channels(0)\r
+                       , stride(0)\r
                {\r
                }\r
 \r
-               plane(int width, int height, int channels)\r
-                       : linesize(width*channels)\r
+               plane(int width, int height, int stride)\r
+                       : linesize(width*stride)\r
                        , width(width)\r
                        , height(height)\r
-                       , size(width*height*channels)\r
-                       , channels(channels)\r
+                       , size(width*height*stride)\r
+                       , stride(stride)\r
                {\r
                }\r
        };\r
index a1e624890087f7f8cc4e7ff2a234e84c8a007ed9..66df1c444b95e0c3262a0a0ef5f0ccb4b6cf11e7 100644 (file)
@@ -23,7 +23,7 @@
 \r
 #include "audio_mixer.h"\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/frame_transform.h>\r
 #include <common/diagnostics/graph.h>\r
 \r
@@ -81,7 +81,7 @@ public:
                transform_stack_.push(transform_stack_.top()*transform.audio_transform);\r
        }\r
 \r
-       void visit(const data_frame& frame)\r
+       void visit(const mutable_frame& frame)\r
        {\r
                audio_item item;\r
                item.tag                = frame.tag();\r
@@ -193,7 +193,7 @@ public:
 \r
 audio_mixer::audio_mixer() : impl_(new impl()){}\r
 void audio_mixer::push(const frame_transform& transform){impl_->push(transform);}\r
-void audio_mixer::visit(const data_frame& frame){impl_->visit(frame);}\r
+void audio_mixer::visit(const mutable_frame& frame){impl_->visit(frame);}\r
 void audio_mixer::pop(){impl_->pop();}\r
 audio_buffer audio_mixer::operator()(const video_format_desc& format_desc){return impl_->mix(format_desc);}\r
 \r
index d112f55fee1bdb2262deb3b0104cd4a9160b5af2..2545965327eec6bb0a725a9999a1d991e81e4ff9 100644 (file)
@@ -42,23 +42,23 @@ class audio_mixer sealed : public frame_visitor
        audio_mixer& operator=(const audio_mixer&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        audio_mixer();\r
 \r
-       /// Methods\r
+       // Methods\r
        \r
        audio_buffer operator()(const struct video_format_desc& format_desc);\r
 \r
        // frame_visitor\r
 \r
        virtual void push(const struct frame_transform& transform);\r
-       virtual void visit(const class data_frame& frame);\r
+       virtual void visit(const class mutable_frame& frame);\r
        virtual void pop();\r
        \r
-       /// Properties\r
+       // Properties\r
 \r
 private:\r
        struct impl;\r
index 039197879f8dff9578aa4543288e5f033f0a4539..30988fcddfa65f9067f447742505e6ce410bc588 100644 (file)
 \r
 #include <core/video_format.h>\r
 #include <core/frame/frame_visitor.h>\r
+#include <core/frame/frame_factory.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <boost/range.hpp>\r
 \r
 #include <stdint.h>\r
 \r
-FORWARD1(boost, template<typename> class shared_future);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD1(boost, template<typename> class unique_future);\r
 FORWARD2(caspar, core, struct pixel_format_desc);\r
 \r
 namespace caspar { namespace core {\r
        \r
-/// Interface\r
+// Interface\r
 class image_mixer : public frame_visitor\r
+                                 , public frame_factory\r
 {\r
        image_mixer(const image_mixer&);\r
        image_mixer& operator=(const image_mixer&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        image_mixer(){}\r
        virtual ~image_mixer(){}\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
        virtual void push(const struct frame_transform& frame) = 0;\r
-       virtual void visit(const class data_frame& frame) = 0;\r
+       virtual void visit(const class mutable_frame& frame) = 0;\r
        virtual void pop() = 0;\r
 \r
        virtual void begin_layer(blend_mode blend_mode) = 0;\r
        virtual void end_layer() = 0;\r
                \r
-       virtual boost::shared_future<boost::iterator_range<const uint8_t*>> operator()(const struct video_format_desc& format_desc) = 0;\r
+       virtual boost::unique_future<const_array> operator()(const struct video_format_desc& format_desc) = 0;\r
 \r
-       virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;\r
+       virtual class mutable_frame create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;\r
 \r
-       /// Properties\r
+       // Properties\r
 };\r
 \r
 }}
\ No newline at end of file
index 846807d88b268598216aa86794915c4980d4af15..3ce5dda3cd0eb8d84a59005f5694e612858dba0f 100644 (file)
@@ -23,7 +23,7 @@
 \r
 #include "mixer.h"\r
 \r
-#include "../frame/data_frame.h"\r
+#include "../frame/frame.h"\r
 \r
 #include "audio/audio_mixer.h"\r
 #include "image/image_mixer.h"\r
 \r
 namespace caspar { namespace core {\r
 \r
-class mixed_frame : public data_frame\r
-{\r
-       mutable boost::shared_future<boost::iterator_range<const uint8_t*>>     image_data_;\r
-       const audio_buffer                                                                                                      audio_data_;\r
-       const video_format_desc                                                                                         video_desc_;\r
-       core::pixel_format_desc                                                                                         pixel_desc_;\r
-       const void*                                                                                                                     tag_;\r
-\r
-public:\r
-       mixed_frame(const void* tag, boost::shared_future<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& 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 frame_rate() const override\r
-       {\r
-               return video_desc_.fps;\r
-       }\r
-\r
-       virtual core::field_mode field_mode() const\r
-       {\r
-               return video_desc_.field_mode;\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
        spl::shared_ptr<diagnostics::graph> graph_;\r
        audio_mixer                                                     audio_mixer_;\r
-       spl::unique_ptr<image_mixer>            image_mixer_;\r
+       spl::shared_ptr<image_mixer>            image_mixer_;\r
        \r
        std::unordered_map<int, blend_mode>     blend_modes_;\r
                        \r
        executor executor_;\r
 \r
 public:\r
-       impl(spl::shared_ptr<diagnostics::graph> graph, spl::unique_ptr<image_mixer> image_mixer) \r
+       impl(spl::shared_ptr<diagnostics::graph> graph, spl::shared_ptr<image_mixer> image_mixer) \r
                : graph_(std::move(graph))\r
                , audio_mixer_()\r
                , image_mixer_(std::move(image_mixer))\r
                , executor_(L"mixer")\r
        {                       \r
                graph_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 0.9f, 0.8));\r
+               graph_->set_color("audio-mix-time", diagnostics::color(1.0f, 0.0f, 0.0f, 0.8));\r
+               graph_->set_color("video-mix-time", diagnostics::color(0.0f, 1.0f, 1.0f, 0.8));\r
        }       \r
        \r
-       spl::shared_ptr<const data_frame> operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc)\r
+       const_frame operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc)\r
        {               \r
-               return executor_.invoke([=]() mutable -> spl::shared_ptr<const class data_frame>\r
+               return executor_.invoke([=]() mutable -> const_frame\r
                {               \r
                        try\r
                        {       \r
@@ -161,18 +93,26 @@ public:
 \r
                                        image_mixer_->end_layer();\r
                                }\r
-\r
+                               \r
+                               boost::timer video_frame_timer;\r
                                auto image = (*image_mixer_)(format_desc);\r
+                               graph_->set_value("video-mix-time", video_frame_timer.elapsed()*format_desc.fps*0.5);\r
+\r
+                               \r
+                               boost::timer audio_frame_timer;\r
                                auto audio = audio_mixer_(format_desc);\r
+                               graph_->set_value("audio-mix-time", audio_frame_timer.elapsed()*format_desc.fps*0.5);\r
                                \r
                                graph_->set_value("mix-time", frame_timer.elapsed()*format_desc.fps*0.5);\r
 \r
-                               return spl::make_shared<mixed_frame>(this, std::move(image), std::move(audio), format_desc);    \r
+                               auto desc = core::pixel_format_desc(core::pixel_format::bgra);\r
+                               desc.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4));\r
+                               return const_frame(std::move(image), std::move(audio), this, desc, format_desc.fps, format_desc.field_mode);    \r
                        }\r
                        catch(...)\r
                        {\r
                                CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               return data_frame::empty();\r
+                               return const_frame::empty();\r
                        }       \r
                });             \r
        }\r
@@ -197,10 +137,10 @@ public:
        }\r
 };\r
        \r
-mixer::mixer(spl::shared_ptr<diagnostics::graph> graph, spl::unique_ptr<image_mixer> image_mixer) \r
+mixer::mixer(spl::shared_ptr<diagnostics::graph> graph, spl::shared_ptr<image_mixer> image_mixer) \r
        : impl_(new impl(std::move(graph), std::move(image_mixer))){}\r
 void mixer::set_blend_mode(int index, blend_mode value){impl_->set_blend_mode(index, value);}\r
 boost::unique_future<boost::property_tree::wptree> mixer::info() const{return impl_->info();}\r
-spl::shared_ptr<const data_frame> mixer::operator()(std::map<int, draw_frame> frames, const struct video_format_desc& format_desc){return (*impl_)(std::move(frames), format_desc);}\r
-spl::unique_ptr<data_frame> mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->image_mixer_->create_frame(tag, desc, frame_rate, field_mode);}\r
+const_frame mixer::operator()(std::map<int, draw_frame> frames, const struct video_format_desc& format_desc){return (*impl_)(std::move(frames), format_desc);}\r
+mutable_frame mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->image_mixer_->create_frame(tag, desc, frame_rate, field_mode);}\r
 }}
\ No newline at end of file
index 897799c4e98b8ec37bcf94de7e6e109872072d6f..0874aca482f20eb32ee72631bd8ff49b23e5b575 100644 (file)
@@ -44,21 +44,21 @@ class mixer sealed
        mixer& operator=(const mixer&);\r
 public:\r
        \r
-       /// Static Members\r
+       // Static Members\r
                                        \r
-       // Constructors\r
+       // Constructors\r
        \r
-       explicit mixer(spl::shared_ptr<diagnostics::graph> graph, spl::unique_ptr<class image_mixer> image_mixer);\r
+       explicit mixer(spl::shared_ptr<diagnostics::graph> graph, spl::shared_ptr<class image_mixer> image_mixer);\r
 \r
-       /// Methods\r
+       // Methods\r
                \r
-       spl::shared_ptr<const class data_frame> operator()(std::map<int, class draw_frame> frames, const struct video_format_desc& format_desc);\r
+       class const_frame operator()(std::map<int, class draw_frame> frames, const struct video_format_desc& format_desc);\r
        \r
-       void                                                            set_blend_mode(int index, blend_mode value);\r
+       void set_blend_mode(int index, blend_mode value);\r
 \r
-       spl::unique_ptr<class data_frame>       create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
+       class mutable_frame create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        boost::unique_future<boost::property_tree::wptree> info() const;\r
 \r
index 8e810470e38e8bc43efd5f0e43351eabe01fb476..66b78e985b089b94d8b287a8a61e5f100be4868d 100644 (file)
@@ -51,9 +51,9 @@ class path sealed
 {\r
 public:        \r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        path();         \r
        path(const char* path);\r
@@ -62,7 +62,7 @@ public:
        path(const path& other);        \r
        path(path&& other);\r
                \r
-       /// Methods\r
+       // Methods\r
 \r
        path& operator=(path other);\r
        path& operator%=(path other);\r
@@ -85,7 +85,7 @@ public:
 \r
        void swap(path& other);\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        const std::string& str() const; \r
        bool empty() const;\r
@@ -115,18 +115,18 @@ class event sealed
 {      \r
 public:        \r
        \r
-       /// Static Members\r
+       // Static Members\r
 \r
        typedef std::vector<param, tbb::cache_aligned_allocator<param>> params_t;\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        event(path path);       \r
        event(path path, params_t params);                                      \r
        event(const event& other);\r
        event(event&& other);\r
 \r
-       /// Methods\r
+       // Methods\r
 \r
        event& operator=(event other);\r
 \r
@@ -141,7 +141,7 @@ public:
        \r
        event                   propagate(path path) const;\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        const path&             path() const;\r
        const params_t& params() const;\r
@@ -206,9 +206,9 @@ class basic_subject sealed : public reactive::subject<monitor::event>
 \r
 public:                \r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        basic_subject(monitor::path path = monitor::path())\r
                : impl_(std::make_shared<impl>(std::move(path)))\r
@@ -221,7 +221,7 @@ public:
        {\r
        }\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
        basic_subject& operator=(basic_subject&& other)\r
        {\r
@@ -252,7 +252,7 @@ public:
                impl_->on_next(e);\r
        }\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
 private:\r
        std::shared_ptr<impl>   impl_;\r
index bb12fb44fb529e14a9f27d5537ec63a36f653427..9686f139d5d53660f682a7d06cbdc9176ba4ad84 100644 (file)
@@ -24,7 +24,7 @@
 #include "color_producer.h"\r
 \r
 #include <core/producer/frame_producer.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/pixel_format.h>\r
@@ -146,7 +146,7 @@ draw_frame create_color_frame(void* tag, const spl::shared_ptr<frame_factory>& f
                \r
        // Read color from hex-string and write to frame pixel.\r
 \r
-       auto& value = *reinterpret_cast<uint32_t*>(frame->image_data(0).begin());\r
+       auto& value = *reinterpret_cast<uint32_t*>(frame.image_data(0).begin());\r
        std::wstringstream str(color2.substr(1));\r
        if(!(str >> std::hex >> value) || !str.eof())\r
                BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(color2) << msg_info("Invalid color."));\r
index edec5c9e0116da2caa124a46cd58469faaa2636b..ca14bea7accf892d8acd4bfcb60c976da821d58a 100644 (file)
@@ -133,7 +133,7 @@ spl::shared_ptr<core::frame_producer> create_destroy_proxy(spl::shared_ptr<core:
        return spl::make_shared<destroy_producer_proxy>(std::move(producer));\r
 }\r
 \r
-spl::shared_ptr<core::frame_producer> do_create_producer(const spl::shared_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> do_create_producer(const spl::shared_ptr<frame_factory>& my_frame_factory, const video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty())\r
                BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));\r
@@ -143,7 +143,7 @@ spl::shared_ptr<core::frame_producer> do_create_producer(const spl::shared_ptr<f
                {\r
                        try\r
                        {\r
-                               producer = factory(my_frame_factory, params);\r
+                               producer = factory(my_frame_factory, format_desc, params);\r
                        }\r
                        catch(...)\r
                        {\r
@@ -161,9 +161,9 @@ spl::shared_ptr<core::frame_producer> do_create_producer(const spl::shared_ptr<f
        return create_destroy_proxy(producer);\r
 }\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>& my_frame_factory, const video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {      \r
-       auto producer = do_create_producer(my_frame_factory, params);\r
+       auto producer = do_create_producer(my_frame_factory, format_desc, params);\r
        auto key_producer = frame_producer::empty();\r
        \r
        try // to find a key file.\r
@@ -172,11 +172,11 @@ spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<fram
                if(params_copy.size() > 0)\r
                {\r
                        params_copy[0] += L"_A";\r
-                       key_producer = do_create_producer(my_frame_factory, params_copy);                       \r
+                       key_producer = do_create_producer(my_frame_factory, format_desc, params_copy);                  \r
                        if(key_producer == frame_producer::empty())\r
                        {\r
                                params_copy[0] += L"LPHA";\r
-                               key_producer = do_create_producer(my_frame_factory, params_copy);       \r
+                               key_producer = do_create_producer(my_frame_factory, format_desc, params_copy);  \r
                        }\r
                }\r
        }\r
@@ -197,13 +197,13 @@ spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<fram
 }\r
 \r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>& factory, const std::wstring& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>& factory, const video_format_desc& format_desc, const std::wstring& params)\r
 {\r
        std::wstringstream iss(params);\r
        std::vector<std::wstring> tokens;\r
        typedef std::istream_iterator<std::wstring, wchar_t, std::char_traits<wchar_t> > iterator;\r
        std::copy(iterator(iss),  iterator(), std::back_inserter(tokens));\r
-       return create_producer(factory, tokens);\r
+       return create_producer(factory, format_desc, tokens);\r
 }\r
 \r
 }}
\ No newline at end of file
index adcafcb7f92a46e764c4d74949088b7d5d36d139..6369fcaa23da7358db7cf983699cf313627dc8d3 100644 (file)
@@ -22,6 +22,7 @@
 #pragma once\r
 \r
 #include "../monitor/monitor.h"\r
+#include "../video_format.h"\r
 \r
 #include <common/forward.h>\r
 #include <common/spl/memory.h>\r
@@ -41,14 +42,14 @@ FORWARD1(boost, template<typename T> class unique_future);
 \r
 namespace caspar { namespace core {\r
        \r
-/// Interface\r
+// Interface\r
 class frame_producer : public monitor::observable\r
 {\r
        frame_producer(const frame_producer&);\r
        frame_producer& operator=(const frame_producer&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
        \r
        struct flags_def\r
        {\r
@@ -63,12 +64,12 @@ public:
 \r
        static const spl::shared_ptr<frame_producer>& empty();\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        frame_producer(){}\r
        virtual ~frame_producer(){}     \r
 \r
-       /// Methods     \r
+       // Methods      \r
 \r
        virtual class draw_frame                                        receive(int flags) = 0;\r
        virtual boost::unique_future<std::wstring>      call(const std::wstring&);\r
@@ -78,7 +79,7 @@ public:
        virtual void subscribe(const monitor::observable::observer_ptr& o) {}\r
        virtual void unsubscribe(const monitor::observable::observer_ptr& o) {}\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        virtual std::wstring                                            print() const = 0;\r
        virtual std::wstring                                            name() const = 0;\r
@@ -88,11 +89,11 @@ public:
        virtual void                                                            leading_producer(const spl::shared_ptr<frame_producer>&) {}     \r
 };\r
 \r
-typedef std::function<spl::shared_ptr<core::frame_producer>(const spl::shared_ptr<class frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
+typedef std::function<spl::shared_ptr<core::frame_producer>(const spl::shared_ptr<class frame_factory>&, const video_format_desc& format_desc, const std::vector<std::wstring>&)> producer_factory_t;\r
 void register_producer_factory(const producer_factory_t& factory); // Not thread-safe.\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>&, const std::vector<std::wstring>& params);\r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>&, const std::wstring& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>&, const video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<frame_factory>&, const video_format_desc& format_desc, const std::wstring& params);\r
 \r
 spl::shared_ptr<core::frame_producer> create_destroy_proxy(spl::shared_ptr<core::frame_producer> producer);\r
                \r
index 3f9da137ca671f31b861cf881d2f9fea0e024f39..82fe1aeec563413c3887766eee1171cd22d16139 100644 (file)
@@ -42,14 +42,14 @@ class layer sealed : public monitor::observable
        layer(const layer&);\r
        layer& operator=(const layer&);\r
 public:\r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        explicit layer(int index = -1); \r
        layer(layer&& other); \r
 \r
-       /// Methods\r
+       // Methods\r
 \r
        layer& operator=(layer&& other); \r
 \r
@@ -67,7 +67,7 @@ public:
        virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
        virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
 \r
-       /// Properties\r
+       // Properties\r
                \r
        spl::shared_ptr<class frame_producer>   foreground() const; \r
        spl::shared_ptr<class frame_producer>   background() const; \r
index 6f159f15d4373e1fdaa460f89dab3ab8836a61ba..900d841c990b208691ffc73742c7893c2147c5f8 100644 (file)
@@ -47,16 +47,16 @@ class stage sealed : public monitor::observable
        stage& operator=(const stage&);\r
 public:        \r
 \r
-       /// Static Members\r
+       // Static Members\r
        \r
        typedef std::function<struct frame_transform(struct frame_transform)> transform_func_t;\r
        typedef std::tuple<int, transform_func_t, unsigned int, tweener> transform_tuple_t;\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
        explicit stage(spl::shared_ptr<diagnostics::graph> graph);\r
        \r
-       /// Methods\r
+       // Methods\r
 \r
        std::map<int, class draw_frame> operator()(const struct video_format_desc& format_desc);\r
 \r
@@ -80,7 +80,7 @@ public:
        virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
        virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        boost::unique_future<spl::shared_ptr<class frame_producer>>     foreground(int index);\r
        boost::unique_future<spl::shared_ptr<class frame_producer>>     background(int index);\r
index 193702cc8698107694f630e2a10502588d274b2b..623bd56a43e810bf3c1923a7aa7b327523cd15a5 100644 (file)
@@ -28,7 +28,7 @@
 #include "producer/stage.h"\r
 #include "mixer/mixer.h"\r
 #include "consumer/output.h"\r
-#include "frame/data_frame.h"\r
+#include "frame/frame.h"\r
 #include "frame/draw_frame.h"\r
 #include "frame/frame_factory.h"\r
 \r
@@ -47,7 +47,7 @@
 \r
 namespace caspar { namespace core {\r
 \r
-struct video_channel::impl sealed : public frame_factory\r
+struct video_channel::impl sealed\r
 {\r
        monitor::basic_subject                                                  event_subject_;\r
 \r
@@ -59,17 +59,19 @@ struct video_channel::impl sealed : public frame_factory
        const spl::shared_ptr<diagnostics::graph>               graph_;\r
 \r
        caspar::core::output                                                    output_;\r
+       spl::shared_ptr<image_mixer>                                    image_mixer_;\r
        caspar::core::mixer                                                             mixer_;\r
        caspar::core::stage                                                             stage_; \r
 \r
        executor                                                                                executor_;\r
 public:\r
-       impl(int index, const core::video_format_desc& format_desc, spl::unique_ptr<image_mixer> image_mixer)  \r
+       impl(int index, const core::video_format_desc& format_desc, std::unique_ptr<image_mixer> image_mixer)  \r
                : event_subject_(monitor::path() % "channel" % index)\r
                , index_(index)\r
                , format_desc_(format_desc)\r
                , output_(graph_, format_desc, index)\r
-               , mixer_(graph_, std::move(image_mixer))\r
+               , image_mixer_(std::move(image_mixer))\r
+               , mixer_(graph_, image_mixer_)\r
                , stage_(graph_)\r
                , executor_(L"video_channel")\r
        {\r
@@ -83,24 +85,15 @@ public:
 \r
                CASPAR_LOG(info) << print() << " Successfully Initialized.";\r
        }\r
-       \r
-       // frame_factory\r
-                                               \r
-       virtual spl::unique_ptr<data_frame> create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override\r
-       {               \r
-               return mixer_.create_frame(tag, desc, frame_rate, field_mode);\r
-       }\r
-       \r
-       virtual core::video_format_desc video_format_desc() const\r
+                                                       \r
+       core::video_format_desc video_format_desc() const\r
        {\r
                return lock(format_desc_mutex_, [&]\r
                {\r
                        return format_desc_;\r
                });\r
        }\r
-       \r
-       // video_channel\r
-       \r
+               \r
        void video_format_desc(const core::video_format_desc& format_desc)\r
        {\r
                lock(format_desc_mutex_, [&]\r
@@ -164,14 +157,15 @@ public:
        }\r
 };\r
 \r
-video_channel::video_channel(int index, const core::video_format_desc& format_desc, spl::unique_ptr<image_mixer> image_mixer) : impl_(new impl(index, format_desc, std::move(image_mixer))){}\r
+video_channel::video_channel(int index, const core::video_format_desc& format_desc, std::unique_ptr<image_mixer> image_mixer) : impl_(new impl(index, format_desc, std::move(image_mixer))){}\r
+video_channel::~video_channel(){}\r
 const stage& video_channel::stage() const { return impl_->stage_;} \r
 stage& video_channel::stage() { return impl_->stage_;} \r
 const mixer& video_channel::mixer() const{ return impl_->mixer_;} \r
 mixer& video_channel::mixer() { return impl_->mixer_;} \r
 const output& video_channel::output() const { return impl_->output_;} \r
 output& video_channel::output() { return impl_->output_;} \r
-spl::shared_ptr<frame_factory> video_channel::frame_factory() { return impl_;} \r
+spl::shared_ptr<frame_factory> video_channel::frame_factory() { return impl_->image_mixer_;} \r
 core::video_format_desc video_channel::video_format_desc() const{return impl_->video_format_desc();}\r
 void core::video_channel::video_format_desc(const core::video_format_desc& format_desc){impl_->video_format_desc(format_desc);}\r
 boost::property_tree::wptree video_channel::info() const{return impl_->info();}                \r
index ac883f8a02f12f7d870fbd9f3eeb6de5db129b6f..0075c09bad6db7ec9530988ef227d6e92a84b6fa 100644 (file)
@@ -45,20 +45,20 @@ class video_channel sealed : public monitor::observable
        video_channel& operator=(const video_channel&);\r
 public:\r
 \r
-       /// Static Members\r
+       // Static Members\r
 \r
-       // Constructors\r
+       // Constructors\r
 \r
-       explicit video_channel(int index, const video_format_desc& format_desc, spl::unique_ptr<image_mixer> image_mixer);\r
-       \r
-       /// Methods\r
+       explicit video_channel(int index, const video_format_desc& format_desc, std::unique_ptr<image_mixer> image_mixer);\r
+       ~video_channel();\r
+       // Methods\r
                        \r
        // monitor::observable\r
 \r
        virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
        virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
 \r
-       /// Properties\r
+       // Properties\r
 \r
        const core::stage&                                       stage() const;\r
        core::stage&                                             stage();\r
@@ -75,7 +75,7 @@ public:
        boost::property_tree::wptree             info() const;\r
 private:\r
        struct impl;\r
-       spl::shared_ptr<impl> impl_;\r
+       spl::unique_ptr<impl> impl_;\r
 };\r
 \r
 }}
\ No newline at end of file
index 7f3ed64a351ffb71008ba3f4b71df3b8792deaf8..34cd6f6cfbf1e7e5cbc212a71456da3b3d921c99 100644 (file)
@@ -25,6 +25,7 @@
 \r
 #include <vector>\r
 #include <string>\r
+#include <cstddef>\r
 \r
 namespace caspar { namespace core {\r
        \r
index 9e9bed30729248a84e494dc481c8eba85dd89d97..9193544b810ee9e1a47c9366cce7b9d9d7b74789 100644 (file)
@@ -26,7 +26,7 @@
 #include "../util/memory.h"\r
 \r
 #include <core/video_format.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <common/concurrency/executor.h>\r
 #include <common/diagnostics/graph.h>\r
@@ -67,7 +67,7 @@ struct bluefish_consumer : boost::noncopyable
        unsigned int                                            vid_fmt_;\r
 \r
        std::array<blue_dma_buffer_ptr, 4>      reserved_frames_;       \r
-       tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<core::const_frame> frame_buffer_;\r
        \r
        const bool                                                      embedded_audio_;\r
        const bool                                                      key_only_;\r
@@ -153,7 +153,7 @@ public:
                enable_video_output();\r
                                                \r
                int n = 0;\r
-               boost::range::generate(reserved_frames_, [&]{return std::make_shared<blue_dma_buffer>(format_desc_.size, n++);});\r
+               boost::range::generate(reserved_frames_, [&]{return std::make_shared<blue_dma_buffer>(static_cast<int>(format_desc_.size), n++);});\r
        }\r
 \r
        ~bluefish_consumer()\r
@@ -185,7 +185,7 @@ public:
                        CASPAR_LOG(error)<< print() << TEXT(" Failed to disable video output.");                \r
        }\r
        \r
-       void send(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void send(core::const_frame& frame)\r
        {                                       \r
                executor_.begin_invoke([=]\r
                {\r
@@ -202,7 +202,7 @@ public:
                });\r
        }\r
 \r
-       void display_frame(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void display_frame(core::const_frame frame)\r
        {\r
                // Sync\r
 \r
@@ -215,12 +215,12 @@ public:
 \r
                // Copy to local buffers\r
                \r
-               if(!frame->image_data().empty())\r
+               if(!frame.image_data().empty())\r
                {\r
                        if(key_only_)                                           \r
-                               aligned_memshfl(reserved_frames_.front()->image_data(), std::begin(frame->image_data()), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
+                               aligned_memshfl(reserved_frames_.front()->image_data(), frame.image_data().begin(), frame.image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
                        else\r
-                               A_memcpy(reserved_frames_.front()->image_data(), std::begin(frame->image_data()), frame->image_data().size());\r
+                               A_memcpy(reserved_frames_.front()->image_data(), frame.image_data().begin(), frame.image_data().size());\r
                }\r
                else\r
                        A_memset(reserved_frames_.front()->image_data(), 0, reserved_frames_.front()->image_size());\r
@@ -230,11 +230,11 @@ public:
 \r
                if(embedded_audio_)\r
                {               \r
-                       auto frame_audio = core::audio_32_to_24(frame->audio_data());                   \r
+                       auto frame_audio = core::audio_32_to_24(frame.audio_data());                    \r
                        encode_hanc(reinterpret_cast<BLUE_UINT32*>(reserved_frames_.front()->hanc_data()), \r
                                                frame_audio.data(), \r
-                                               static_cast<int>(frame->audio_data().size()/format_desc_.audio_channels), \r
-                                               format_desc_.audio_channels);\r
+                                               static_cast<int>(frame.audio_data().size()/format_desc_.audio_channels), \r
+                                               static_cast<int>(format_desc_.audio_channels));\r
                                                                \r
                        blue_->system_buffer_write_async(const_cast<uint8_t*>(reserved_frames_.front()->image_data()), \r
                                                                                        static_cast<unsigned long>(reserved_frames_.front()->image_size()), \r
@@ -316,7 +316,7 @@ public:
                consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_, key_only_, channel_index));\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {\r
                consumer_->send(frame);\r
                return true;\r
index b4665113ad9480cfaac5fa0411d2886ca05b72f8..f8310be5ce989bdc208be51e091f1f63c8689aa5 100644 (file)
@@ -27,7 +27,7 @@
 \r
 #include "../interop/DeckLinkAPI_h.h"\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/mixer/audio/audio_mixer.h>\r
 \r
 #include <common/concurrency/executor.h>\r
@@ -91,13 +91,13 @@ struct configuration
 class decklink_frame : public IDeckLinkVideoFrame\r
 {\r
        tbb::atomic<int>                                                                                        ref_count_;\r
-       std::shared_ptr<const core::data_frame>                                                         frame_;\r
+       core::const_frame                                                                               frame_;\r
        const core::video_format_desc                                                           format_desc_;\r
 \r
        const bool                                                                                                      key_only_;\r
        std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> data_;\r
 public:\r
-       decklink_frame(const spl::shared_ptr<const core::data_frame>& frame, const core::video_format_desc& format_desc, bool key_only)\r
+       decklink_frame(core::const_frame frame, const core::video_format_desc& format_desc, bool key_only)\r
                : frame_(frame)\r
                , format_desc_(format_desc)\r
                , key_only_(key_only)\r
@@ -126,9 +126,9 @@ public:
 \r
        // IDecklinkVideoFrame\r
 \r
-       STDMETHOD_(long,                        GetWidth())                     {return format_desc_.width;}        \r
-    STDMETHOD_(long,                   GetHeight())            {return format_desc_.height;}        \r
-    STDMETHOD_(long,                   GetRowBytes())          {return format_desc_.width*4;}        \r
+       STDMETHOD_(long,                        GetWidth())                     {return static_cast<long>(format_desc_.width);}        \r
+    STDMETHOD_(long,                   GetHeight())            {return static_cast<long>(format_desc_.height);}        \r
+    STDMETHOD_(long,                   GetRowBytes())          {return static_cast<long>(format_desc_.width*4);}        \r
        STDMETHOD_(BMDPixelFormat,      GetPixelFormat())       {return bmdFormat8BitBGRA;}        \r
     STDMETHOD_(BMDFrameFlags,  GetFlags())                     {return bmdFrameFlagDefault;}\r
         \r
@@ -136,7 +136,7 @@ public:
        {\r
                try\r
                {\r
-                       if(static_cast<int>(frame_->image_data().size()) != format_desc_.size)\r
+                       if(static_cast<int>(frame_.image_data().size()) != format_desc_.size)\r
                        {\r
                                data_.resize(format_desc_.size, 0);\r
                                *buffer = data_.data();\r
@@ -145,13 +145,13 @@ public:
                        {\r
                                if(data_.empty())\r
                                {\r
-                                       data_.resize(frame_->image_data().size());\r
-                                       aligned_memshfl(data_.data(), frame_->image_data().begin(), frame_->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
+                                       data_.resize(frame_.image_data().size());\r
+                                       aligned_memshfl(data_.data(), frame_.image_data().begin(), frame_.image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
                                }\r
                                *buffer = data_.data();\r
                        }\r
                        else\r
-                               *buffer = const_cast<uint8_t*>(frame_->image_data().begin());\r
+                               *buffer = const_cast<uint8_t*>(frame_.image_data().begin());\r
                }\r
                catch(...)\r
                {\r
@@ -169,7 +169,7 @@ public:
 \r
        const core::audio_buffer& audio_data()\r
        {\r
-               return frame_->audio_data();\r
+               return frame_.audio_data();\r
        }\r
 };\r
 \r
@@ -200,8 +200,8 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLink
                \r
        boost::circular_buffer<std::vector<int32_t>>    audio_container_;\r
 \r
-       tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>> video_frame_buffer_;\r
-       tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>> audio_frame_buffer_;\r
+       tbb::concurrent_bounded_queue<core::const_frame> video_frame_buffer_;\r
+       tbb::concurrent_bounded_queue<core::const_frame> audio_frame_buffer_;\r
        \r
        spl::shared_ptr<diagnostics::graph> graph_;\r
        boost::timer tick_timer_;\r
@@ -249,7 +249,7 @@ public:
                        output_->BeginAudioPreroll();           \r
                \r
                for(int n = 0; n < buffer_size_; ++n)\r
-                       schedule_next_video(core::data_frame::empty());\r
+                       schedule_next_video(core::const_frame::empty());\r
 \r
                if(!config.embedded_audio)\r
                        start_playback();\r
@@ -258,8 +258,8 @@ public:
        ~decklink_consumer()\r
        {               \r
                is_running_ = false;\r
-               video_frame_buffer_.try_push(core::data_frame::empty());\r
-               audio_frame_buffer_.try_push(core::data_frame::empty());\r
+               video_frame_buffer_.try_push(core::const_frame::empty());\r
+               audio_frame_buffer_.try_push(core::const_frame::empty());\r
 \r
                if(output_ != nullptr) \r
                {\r
@@ -372,9 +372,9 @@ public:
                        else if(result == bmdOutputFrameFlushed)\r
                                graph_->set_tag("flushed-frame");\r
 \r
-                       std::shared_ptr<const core::data_frame> frame;  \r
+                       auto frame = core::const_frame::empty();        \r
                        video_frame_buffer_.pop(frame);                                 \r
-                       schedule_next_video(spl::make_shared_ptr(frame));       \r
+                       schedule_next_video(frame);     \r
                        \r
                        unsigned long buffered;\r
                        output_->GetBufferedVideoFrameCount(&buffered);\r
@@ -411,9 +411,9 @@ public:
                        }\r
                        else\r
                        {\r
-                               std::shared_ptr<const core::data_frame> frame;\r
+                               auto frame = core::const_frame::empty();\r
                                audio_frame_buffer_.pop(frame);\r
-                               schedule_next_audio(frame->audio_data());\r
+                               schedule_next_audio(frame.audio_data());\r
                        }\r
 \r
                        unsigned long buffered;\r
@@ -443,7 +443,7 @@ public:
                audio_scheduled_ += sample_frame_count;\r
        }\r
                        \r
-       void schedule_next_video(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void schedule_next_video(core::const_frame frame)\r
        {\r
                CComPtr<IDeckLinkVideoFrame> frame2(new decklink_frame(frame, format_desc_, config_.key_only));\r
                if(FAILED(output_->ScheduleVideoFrame(frame2, video_scheduled_, format_desc_.duration, format_desc_.time_scale)))\r
@@ -455,7 +455,7 @@ public:
                tick_timer_.restart();\r
        }\r
 \r
-       void send(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void send(core::const_frame frame)\r
        {\r
                auto exception = lock(exception_mutex_, [&]\r
                {\r
@@ -516,7 +516,7 @@ public:
                });\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {\r
                consumer_->send(frame);\r
                return true;\r
index ee21fa670cc35c0288cede9b158cdbbb9a0e7d4a..f766c6e1ae96eb7b3171592b2ae8070938ab7da5 100644 (file)
@@ -37,7 +37,7 @@
 #include <common/log.h>\r
 #include <common/param.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/frame_factory.h>\r
@@ -88,33 +88,39 @@ class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback
        CComQIPtr<IDeckLinkAttributes >                                 attributes_;\r
        \r
        const std::wstring                                                              model_name_;\r
-       const size_t                                                                    device_index_;\r
+       const int                                                                               device_index_;\r
        const std::wstring                                                              filter_;\r
        \r
-       core::video_format_desc                                                 format_desc_;\r
        std::vector<int>                                                                audio_cadence_;\r
        boost::circular_buffer<size_t>                                  sync_buffer_;\r
        ffmpeg::frame_muxer                                                             muxer_;\r
                        \r
        tbb::atomic<int>                                                                flags_;\r
        spl::shared_ptr<core::frame_factory>                    frame_factory_;\r
+       core::video_format_desc                                                 in_format_desc_;\r
+       core::video_format_desc                                                 out_format_desc_;\r
 \r
        tbb::concurrent_bounded_queue<core::draw_frame> frame_buffer_;\r
 \r
        std::exception_ptr                                                              exception_;             \r
 \r
 public:\r
-       decklink_producer(const core::video_format_desc& format_desc, size_t device_index, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
+       decklink_producer(const core::video_format_desc& in_format_desc, \r
+                                         int device_index, \r
+                                         const spl::shared_ptr<core::frame_factory>& frame_factory, \r
+                                         const core::video_format_desc& out_format_desc, \r
+                                         const std::wstring& filter)\r
                : decklink_(get_device(device_index))\r
                , input_(decklink_)\r
                , attributes_(decklink_)\r
                , model_name_(get_model_name(decklink_))\r
                , device_index_(device_index)\r
                , filter_(filter)\r
-               , format_desc_(format_desc)\r
-               , audio_cadence_(format_desc.audio_cadence)\r
-               , muxer_(format_desc.fps, frame_factory, filter)\r
-               , sync_buffer_(format_desc.audio_cadence.size())\r
+               , in_format_desc_(in_format_desc)\r
+               , out_format_desc_(out_format_desc)\r
+               , muxer_(in_format_desc.fps, frame_factory, out_format_desc, filter)\r
+               , audio_cadence_(out_format_desc.audio_cadence)\r
+               , sync_buffer_(out_format_desc.audio_cadence.size())\r
                , frame_factory_(frame_factory)\r
        {       \r
                flags_ = 0;\r
@@ -128,7 +134,7 @@ public:
                graph_->set_text(print());\r
                diagnostics::register_graph(graph_);\r
                \r
-               auto display_mode = get_display_mode(input_, format_desc_.format, bmdFormat8BitYUV, bmdVideoInputFlagDefault);\r
+               auto display_mode = get_display_mode(input_, in_format_desc.format, bmdFormat8BitYUV, bmdVideoInputFlagDefault);\r
                \r
                // NOTE: bmdFormat8BitARGB is currently not supported by any decklink card. (2011-05-08)\r
                if(FAILED(input_->EnableVideoInput(display_mode, bmdFormat8BitYUV, 0))) \r
@@ -136,7 +142,7 @@ public:
                                                                        << msg_info(print() + L" Could not enable video input.")\r
                                                                        << boost::errinfo_api_function("EnableVideoInput"));\r
 \r
-               if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, format_desc_.audio_channels))) \r
+               if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, static_cast<int>(in_format_desc.audio_channels)))) \r
                        BOOST_THROW_EXCEPTION(caspar_exception() \r
                                                                        << msg_info(print() + L" Could not enable audio input.")\r
                                                                        << boost::errinfo_api_function("EnableAudioInput"));\r
@@ -179,7 +185,7 @@ public:
 \r
                try\r
                {\r
-                       graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);\r
+                       graph_->set_value("tick-time", tick_timer_.elapsed()*out_format_desc_.fps*0.5);\r
                        tick_timer_.restart();\r
 \r
                        frame_timer_.restart();\r
@@ -198,8 +204,8 @@ public:
                        av_frame->format                        = PIX_FMT_UYVY422;\r
                        av_frame->width                         = video->GetWidth();\r
                        av_frame->height                        = video->GetHeight();\r
-                       av_frame->interlaced_frame      = format_desc_.field_mode != core::field_mode::progressive;\r
-                       av_frame->top_field_first       = format_desc_.field_mode == core::field_mode::upper ? 1 : 0;\r
+                       av_frame->interlaced_frame      = in_format_desc_.field_mode != core::field_mode::progressive;\r
+                       av_frame->top_field_first       = in_format_desc_.field_mode == core::field_mode::upper ? 1 : 0;\r
                                \r
                        std::shared_ptr<core::audio_buffer> audio_buffer;\r
 \r
@@ -208,7 +214,7 @@ public:
                        {\r
                                auto sample_frame_count = audio->GetSampleFrameCount();\r
                                auto audio_data = reinterpret_cast<int32_t*>(bytes);\r
-                               audio_buffer = std::make_shared<core::audio_buffer>(audio_data, audio_data + sample_frame_count*format_desc_.audio_channels);\r
+                               audio_buffer = std::make_shared<core::audio_buffer>(audio_data, audio_data + sample_frame_count*out_format_desc_.audio_channels);\r
                        }\r
                        else                    \r
                                audio_buffer = std::make_shared<core::audio_buffer>(audio_cadence_.front(), 0);\r
@@ -237,7 +243,7 @@ public:
                                        graph_->set_tag("dropped-frame");\r
                        }\r
                        \r
-                       graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+                       graph_->set_value("frame-time", frame_timer_.elapsed()*out_format_desc_.fps*0.5);\r
 \r
                        graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity()));      \r
                }\r
@@ -266,7 +272,7 @@ public:
        \r
        std::wstring print() const\r
        {\r
-               return model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"|" + format_desc_.name + L"]";\r
+               return model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"|" + in_format_desc_.name + L"]";\r
        }\r
 };\r
        \r
@@ -274,10 +280,14 @@ class decklink_producer_proxy : public core::frame_producer
 {              \r
        std::unique_ptr<decklink_producer>      producer_;\r
        const uint32_t                                          length_;\r
-       core::draw_frame        last_frame_;\r
+       core::draw_frame                                        last_frame_;\r
        executor                                                        executor_;\r
 public:\r
-       explicit decklink_producer_proxy(const spl::shared_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
+       explicit decklink_producer_proxy(const core::video_format_desc& in_format_desc,\r
+                                                                        const spl::shared_ptr<core::frame_factory>& frame_factory, \r
+                                                                        const core::video_format_desc& out_format_desc, \r
+                                                                        int device_index,\r
+                                                                        const std::wstring& filter_str, uint32_t length)\r
                : executor_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
                , length_(length)\r
                , last_frame_(core::draw_frame::empty())\r
@@ -285,7 +295,7 @@ public:
                executor_.invoke([=]\r
                {\r
                        CoInitialize(nullptr);\r
-                       producer_.reset(new decklink_producer(format_desc, device_index, frame_factory, filter_str));\r
+                       producer_.reset(new decklink_producer(in_format_desc, device_index, frame_factory, out_format_desc, filter_str));\r
                });\r
        }\r
 \r
@@ -338,7 +348,7 @@ public:
        }\r
 };\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& out_format_desc, const std::vector<std::wstring>& params)\r
 {\r
        if(params.empty() || !boost::iequals(params[0], "decklink"))\r
                return core::frame_producer::empty();\r
@@ -349,15 +359,15 @@ spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core
        \r
        auto filter_str         = get_param(L"FILTER", params);         \r
        auto length                     = get_param(L"LENGTH", params, std::numeric_limits<uint32_t>::max());   \r
-       auto format_desc        = core::video_format_desc(get_param(L"FORMAT", params, L"INVALID"));\r
+       auto in_format_desc = core::video_format_desc(get_param(L"FORMAT", params, L"INVALID"));\r
        \r
        boost::replace_all(filter_str, L"DEINTERLACE", L"YADIF=0:-1");\r
        boost::replace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1");\r
        \r
-       if(format_desc.format == core::video_format::invalid)\r
-               format_desc = frame_factory->video_format_desc();\r
+       if(in_format_desc.format == core::video_format::invalid)\r
+               in_format_desc = out_format_desc;\r
                        \r
-       return spl::make_shared<decklink_producer_proxy>(frame_factory, format_desc, device_index, filter_str, length);\r
+       return spl::make_shared<decklink_producer_proxy>(in_format_desc, frame_factory, out_format_desc, device_index, filter_str, length);\r
 }\r
 \r
 }}
\ No newline at end of file
index 2cd91a42b7707c20b985f76d421200dde60ebbee..8aa88fe6595163a0ec0fdcebcd325a835851382a 100644 (file)
@@ -28,6 +28,6 @@
 \r
 namespace caspar { namespace decklink {\r
        \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 }}\r
index dd6648fb0be41999d087abced3e56ec6c14fb1ad..e49518cd035909ab8a107f526d3fb1b9aecbcf8c 100644 (file)
@@ -25,7 +25,7 @@
 \r
 #include "ffmpeg_consumer.h"\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/mixer/audio/audio_util.h>\r
 #include <core/consumer/frame_consumer.h>\r
 #include <core/video_format.h>\r
@@ -224,11 +224,8 @@ public:
 \r
        ~ffmpeg_consumer()\r
        {    \r
-               executor_.stop();\r
-               executor_.join();\r
-\r
-               file_write_executor_.stop();\r
-               file_write_executor_.join();\r
+               executor_.wait();\r
+               file_write_executor_.wait();\r
                \r
                LOG_ON_ERROR2(av_write_trailer(oc_.get()), "[ffmpeg_consumer]");\r
                \r
@@ -369,28 +366,28 @@ public:
                });\r
        }\r
 \r
-       std::shared_ptr<AVFrame> convert_video_frame(const spl::shared_ptr<const core::data_frame>& frame, AVCodecContext* c)\r
+       std::shared_ptr<AVFrame> convert_video_frame(core::const_frame frame, AVCodecContext* c)\r
        {\r
                if(!sws_) \r
                {\r
-                       sws_.reset(sws_getContext(format_desc_.width, format_desc_.height, PIX_FMT_BGRA, c->width, c->height, c->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr), sws_freeContext);\r
+                       sws_.reset(sws_getContext(static_cast<int>(format_desc_.width), static_cast<int>(format_desc_.height), PIX_FMT_BGRA, c->width, c->height, c->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr), sws_freeContext);\r
                        if (sws_ == nullptr) \r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Cannot initialize the conversion context"));\r
                }\r
 \r
                std::shared_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free);\r
-               avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), const_cast<uint8_t*>(frame->image_data().begin()), PIX_FMT_BGRA, format_desc_.width, format_desc_.height);\r
+               avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), const_cast<uint8_t*>(frame.image_data().begin()), PIX_FMT_BGRA, static_cast<int>(format_desc_.width), static_cast<int>(format_desc_.height));\r
                                \r
                std::shared_ptr<AVFrame> local_av_frame(avcodec_alloc_frame(), av_free);\r
-               picture_buf_.resize(avpicture_get_size(c->pix_fmt, format_desc_.width, format_desc_.height));\r
-               avpicture_fill(reinterpret_cast<AVPicture*>(local_av_frame.get()), picture_buf_.data(), c->pix_fmt, format_desc_.width, format_desc_.height);\r
+               picture_buf_.resize(avpicture_get_size(c->pix_fmt, static_cast<int>(format_desc_.width), static_cast<int>(format_desc_.height)));\r
+               avpicture_fill(reinterpret_cast<AVPicture*>(local_av_frame.get()), picture_buf_.data(), c->pix_fmt, static_cast<int>(format_desc_.width), static_cast<int>(format_desc_.height));\r
 \r
                sws_scale(sws_.get(), av_frame->data, av_frame->linesize, 0, c->height, local_av_frame->data, local_av_frame->linesize);\r
 \r
                return local_av_frame;\r
        }\r
   \r
-       std::shared_ptr<AVPacket> encode_video_frame(const spl::shared_ptr<const core::data_frame>& frame)\r
+       std::shared_ptr<AVPacket> encode_video_frame(core::const_frame frame)\r
        { \r
                auto c = video_st_->codec;\r
  \r
@@ -425,11 +422,11 @@ public:
                return nullptr;\r
        }\r
                \r
-       std::shared_ptr<AVPacket> encode_audio_frame(const spl::shared_ptr<const core::data_frame>& frame)\r
+       std::shared_ptr<AVPacket> encode_audio_frame(core::const_frame frame)\r
        {                       \r
                auto c = audio_st_->codec;\r
 \r
-               auto audio_data = core::audio_32_to_16(frame->audio_data());\r
+               auto audio_data = core::audio_32_to_16(frame.audio_data());\r
                \r
                spl::shared_ptr<AVPacket> pkt(new AVPacket, [](AVPacket* p)\r
                {\r
@@ -450,7 +447,7 @@ public:
                return pkt;\r
        }\r
                 \r
-       void send(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void send(core::const_frame& frame)\r
        {\r
                executor_.begin_invoke([=]\r
                {               \r
@@ -497,7 +494,7 @@ public:
                consumer_.reset(new ffmpeg_consumer(u8(filename_), format_desc, options_));\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {\r
                consumer_->send(frame);\r
                return true;\r
index 3e77b04741d7d1913d1f3fbe0834000053d845f6..714b56395f7cf25df4275465e351bf53cf8f3de7 100644 (file)
@@ -87,10 +87,16 @@ struct ffmpeg_producer : public core::frame_producer
        core::draw_frame                                                        last_frame_;\r
        \r
 public:\r
-       explicit ffmpeg_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, uint32_t start, uint32_t length) \r
+       explicit ffmpeg_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, \r
+                                                        const core::video_format_desc& format_desc, \r
+                                                        const std::wstring& filename, \r
+                                                        const std::wstring& filter, \r
+                                                        bool loop, \r
+                                                        uint32_t start, \r
+                                                        uint32_t length) \r
                : filename_(filename)\r
                , frame_factory_(frame_factory)         \r
-               , format_desc_(frame_factory->video_format_desc())\r
+               , format_desc_(format_desc)\r
                , input_(graph_, filename_, loop, start, length)\r
                , fps_(read_fps(*input_.context(), format_desc_.fps))\r
                , start_(start)\r
@@ -120,7 +126,7 @@ public:
 \r
                try\r
                {\r
-                       audio_decoder_.reset(new audio_decoder(input_.context(), frame_factory->video_format_desc()));\r
+                       audio_decoder_.reset(new audio_decoder(input_.context(), format_desc_));\r
                        audio_decoder_->subscribe(event_subject_);\r
                        CASPAR_LOG(info) << print() << L" " << audio_decoder_->print();\r
                }\r
@@ -137,7 +143,7 @@ public:
                if(!video_decoder_ && !audio_decoder_)\r
                        BOOST_THROW_EXCEPTION(averror_stream_not_found() << msg_info("No streams found"));\r
 \r
-               muxer_.reset(new frame_muxer(fps_, frame_factory, filter));\r
+               muxer_.reset(new frame_muxer(fps_, frame_factory, format_desc_, filter));\r
 \r
                CASPAR_LOG(info) << print() << L" Initialized";\r
        }\r
@@ -339,7 +345,7 @@ public:
        }\r
 };\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {              \r
        auto filename = probe_stem(env::media_folder() + L"\\" + params.at(0));\r
 \r
@@ -354,7 +360,7 @@ spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core
        boost::replace_all(filter_str, L"DEINTERLACE", L"YADIF=0:-1");\r
        boost::replace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1");\r
        \r
-       return spl::make_shared<ffmpeg_producer>(frame_factory, filename, filter_str, loop, start, length);\r
+       return spl::make_shared_ptr(std::make_shared<ffmpeg_producer>(frame_factory, format_desc, filename, filter_str, loop, start, length));\r
 }\r
 \r
 }}
\ No newline at end of file
index 1c695188e68d57940e3656c7ecdb875325e581da..626baa5279ea9c8fd98b2e080b1d9b1d58590e11 100644 (file)
@@ -23,6 +23,9 @@
 \r
 #include <common/spl/memory.h>\r
 \r
+#include <core/producer/frame_producer.h>\r
+#include <core/video_format.h>\r
+\r
 #include <string>\r
 #include <vector>\r
 \r
@@ -37,6 +40,6 @@ class frame_factory;
        \r
 namespace ffmpeg {\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 }}
\ No newline at end of file
index f2a5c6fe7ce5a2edec0e233fba83e5ff085e7cc4..4cf4e62ade9f5493ee9827dd6bc50db065174576 100644 (file)
@@ -31,7 +31,7 @@
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/pixel_format.h>\r
 #include <core/frame/frame_factory.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <common/env.h>\r
 #include <common/except.h>\r
@@ -67,27 +67,27 @@ namespace caspar { namespace ffmpeg {
        \r
 struct frame_muxer::impl : boost::noncopyable\r
 {      \r
-       std::queue<std::queue<spl::unique_ptr<data_frame>>>             video_streams_;\r
-       std::queue<core::audio_buffer>                                                  audio_streams_;\r
-       std::queue<draw_frame>                                                                  frame_buffer_;\r
-       display_mode                                                                                    display_mode_;\r
-       const double                                                                                    in_fps_;\r
-       const video_format_desc                                                                 format_desc_;\r
-       bool                                                                                                    auto_transcode_;\r
-       bool                                                                                                    auto_deinterlace_;\r
+       std::queue<std::queue<core::mutable_frame>>             video_streams_;\r
+       std::queue<core::audio_buffer>                                  audio_streams_;\r
+       std::queue<draw_frame>                                                  frame_buffer_;\r
+       display_mode                                                                    display_mode_;\r
+       const double                                                                    in_fps_;\r
+       const video_format_desc                                                 format_desc_;\r
+       bool                                                                                    auto_transcode_;\r
+       bool                                                                                    auto_deinterlace_;\r
        \r
-       std::vector<int>                                                                                audio_cadence_;\r
+       std::vector<int>                                                                audio_cadence_;\r
                        \r
-       spl::shared_ptr<core::frame_factory>                                    frame_factory_;\r
+       spl::shared_ptr<core::frame_factory>                    frame_factory_;\r
        \r
-       filter                                                                                                  filter_;\r
-       const std::wstring                                                                              filter_str_;\r
-       bool                                                                                                    force_deinterlacing_;\r
+       filter                                                                                  filter_;\r
+       const std::wstring                                                              filter_str_;\r
+       bool                                                                                    force_deinterlacing_;\r
                \r
-       impl(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter_str)\r
+       impl(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::wstring& filter_str)\r
                : display_mode_(display_mode::invalid)\r
                , in_fps_(in_fps)\r
-               , format_desc_(frame_factory->video_format_desc())\r
+               , format_desc_(format_desc)\r
                , auto_transcode_(env::properties().get(L"configuration.auto-transcode", true))\r
                , auto_deinterlace_(env::properties().get(L"configuration.auto-deinterlace", true))\r
                , audio_cadence_(format_desc_.audio_cadence)\r
@@ -95,7 +95,7 @@ struct frame_muxer::impl : boost::noncopyable
                , filter_str_(filter_str)\r
                , force_deinterlacing_(false)\r
        {\r
-               video_streams_.push(std::queue<spl::unique_ptr<data_frame>>());\r
+               video_streams_.push(std::queue<core::mutable_frame>());\r
                audio_streams_.push(core::audio_buffer());\r
                \r
                // Note: Uses 1 step rotated cadence for 1001 modes (1602, 1602, 1601, 1602, 1601)\r
@@ -110,7 +110,7 @@ struct frame_muxer::impl : boost::noncopyable
                \r
                if(video_frame == flush_video())\r
                {       \r
-                       video_streams_.push(std::queue<spl::unique_ptr<data_frame>>());\r
+                       video_streams_.push(std::queue<core::mutable_frame>());\r
                }\r
                else if(video_frame == empty_video())\r
                {\r
@@ -144,7 +144,7 @@ struct frame_muxer::impl : boost::noncopyable
                                if(video_frame->format == PIX_FMT_GRAY8 && format == CASPAR_PIX_FMT_LUMA)\r
                                        av_frame->format = format;\r
 \r
-                               video_streams_.back().push(make_data_frame(this, av_frame, frame_factory_->video_format_desc().fps, frame_factory_, flags));\r
+                               video_streams_.back().push(make_frame(this, av_frame, format_desc_.fps, frame_factory_, flags));\r
                        }\r
                }\r
 \r
@@ -230,7 +230,7 @@ struct frame_muxer::impl : boost::noncopyable
                        return false;\r
                                \r
                auto frame1                             = pop_video();\r
-               frame1->audio_data()    = pop_audio();\r
+               frame1.audio_data()     = pop_audio();\r
 \r
                switch(display_mode_)\r
                {\r
@@ -254,7 +254,7 @@ struct frame_muxer::impl : boost::noncopyable
                        }\r
                case display_mode::duplicate:   \r
                        {\r
-                               boost::range::push_back(frame1->audio_data(), pop_audio());\r
+                               boost::range::push_back(frame1.audio_data(), pop_audio());\r
 \r
                                auto draw_frame = core::draw_frame(std::move(frame1));\r
                                frame_buffer_.push(draw_frame);\r
@@ -275,7 +275,7 @@ struct frame_muxer::impl : boost::noncopyable
                return try_pop(result);\r
        }\r
        \r
-       spl::unique_ptr<core::data_frame> pop_video()\r
+       core::mutable_frame pop_video()\r
        {\r
                auto frame = std::move(video_streams_.front().front());\r
                video_streams_.front().pop();           \r
@@ -317,7 +317,7 @@ struct frame_muxer::impl : boost::noncopyable
                        \r
                        if((frame->height != 480 || format_desc_.height != 486) && // don't deinterlace for NTSC DV\r
                                        display_mode_ == display_mode::simple && mode != core::field_mode::progressive && format_desc_.field_mode != core::field_mode::progressive && \r
-                                       frame->height != static_cast<int>(format_desc_.height))\r
+                                       frame->height != format_desc_.height)\r
                        {\r
                                display_mode_ = display_mode::deinterlace_bob_reinterlace; // The frame will most likely be scaled, we need to deinterlace->reinterlace \r
                        }\r
@@ -350,7 +350,7 @@ struct frame_muxer::impl : boost::noncopyable
                                filter_.push(frame);\r
                                auto av_frame = filter_.poll();\r
                                if(av_frame)                                                    \r
-                                       video_streams_.back().push(make_data_frame(this, spl::make_shared_ptr(av_frame), frame_factory_->video_format_desc().fps, frame_factory_, 0));\r
+                                       video_streams_.back().push(make_frame(this, spl::make_shared_ptr(av_frame), format_desc_.fps, frame_factory_, 0));\r
                        }\r
                        filter_ = filter(filter_str);\r
                        CASPAR_LOG(info) << L"[frame_muxer] " << display_mode_ << L" " << print_mode(frame->width, frame->height, in_fps_, frame->interlaced_frame > 0);\r
@@ -380,8 +380,8 @@ struct frame_muxer::impl : boost::noncopyable
        }\r
 };\r
 \r
-frame_muxer::frame_muxer(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
-       : impl_(new impl(in_fps, frame_factory, filter)){}\r
+frame_muxer::frame_muxer(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::wstring& filter)\r
+       : impl_(new impl(in_fps, frame_factory, format_desc, filter)){}\r
 void frame_muxer::push(const std::shared_ptr<AVFrame>& video_frame, int flags){impl_->push(video_frame, flags);}\r
 void frame_muxer::push(const std::shared_ptr<core::audio_buffer>& audio_samples){return impl_->push(audio_samples);}\r
 bool frame_muxer::try_pop(core::draw_frame& result){return impl_->try_pop(result);}\r
index b540df9c7e618d8a2fc3c4cf9b6af89cdc78dc47..1a5e5578b6358fa9c368a1448018de03f7b9a5a5 100644 (file)
@@ -27,6 +27,7 @@
 #include <common/spl/memory.h>\r
 \r
 #include <core/mixer/audio/audio_mixer.h>\r
+#include <core/video_format.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
@@ -35,7 +36,7 @@
 struct AVFrame;\r
 \r
 FORWARD2(caspar, core, struct pixel_format_desc);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class frame);\r
 FORWARD2(caspar, core, class frame_factory);\r
 FORWARD2(caspar, core, class draw_frame);\r
 \r
@@ -44,7 +45,7 @@ namespace caspar { namespace ffmpeg {
 class frame_muxer : boost::noncopyable\r
 {\r
 public:\r
-       frame_muxer(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter = L"");\r
+       frame_muxer(double in_fps, const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::wstring& filter = L"");\r
        \r
        void push(const std::shared_ptr<AVFrame>& video_frame, int flags = 0);\r
        void push(const std::shared_ptr<core::audio_buffer>& audio_samples);\r
index 8be19c0b8273204a551dce2c74233fa32529522d..82f5e661ea81e9dc48a3950e2404ac91df2fa730 100644 (file)
@@ -33,7 +33,7 @@
 \r
 #include <core/frame/frame_transform.h>\r
 #include <core/frame/frame_factory.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/producer/frame_producer.h>\r
 \r
 #include <common/except.h>\r
@@ -171,7 +171,7 @@ int make_alpha_format(int format)
        }\r
 }\r
 \r
-spl::unique_ptr<core::data_frame> make_data_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags)\r
+core::mutable_frame make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags)\r
 {                      \r
        static tbb::concurrent_unordered_map<int, tbb::concurrent_queue<std::shared_ptr<SwsContext>>> sws_contexts_;\r
        \r
@@ -231,8 +231,8 @@ spl::unique_ptr<core::data_frame> make_data_frame(const void* tag, const spl::sh
                avcodec_get_frame_defaults(av_frame.get());                     \r
                if(target_pix_fmt == PIX_FMT_BGRA)\r
                {\r
-                       auto size = avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write->image_data(0).begin(), PIX_FMT_BGRA, width, height);\r
-                       CASPAR_VERIFY(size == write->image_data(0).size()); \r
+                       auto size = avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write.image_data(0).begin(), PIX_FMT_BGRA, width, height);\r
+                       CASPAR_VERIFY(size == write.image_data(0).size()); \r
                }\r
                else\r
                {\r
@@ -240,7 +240,7 @@ spl::unique_ptr<core::data_frame> make_data_frame(const void* tag, const spl::sh
                        av_frame->height = height;\r
                        for(int n = 0; n < target_desc.planes.size(); ++n)\r
                        {\r
-                               av_frame->data[n]               = write->image_data(n).begin();\r
+                               av_frame->data[n]               = write.image_data(n).begin();\r
                                av_frame->linesize[n]   = target_desc.planes[n].linesize;\r
                        }\r
                }\r
@@ -257,12 +257,12 @@ spl::unique_ptr<core::data_frame> make_data_frame(const void* tag, const spl::sh
                for(int n = 0; n < static_cast<int>(desc.planes.size()); ++n)\r
                {\r
                        auto plane            = desc.planes[n];\r
-                       auto result           = write->image_data(n).begin();\r
+                       auto result           = write.image_data(n).begin();\r
                        auto decoded          = decoded_frame->data[n];\r
                        auto decoded_linesize = decoded_frame->linesize[n];\r
                        \r
                        CASPAR_ASSERT(decoded);\r
-                       CASPAR_ASSERT(write->image_data(n).begin());\r
+                       CASPAR_ASSERT(write.image_data(n).begin());\r
 \r
                        // Copy line by line since ffmpeg sometimes pads each line.\r
                        tbb::affinity_partitioner ap;\r
@@ -277,7 +277,7 @@ spl::unique_ptr<core::data_frame> make_data_frame(const void* tag, const spl::sh
        }\r
 }\r
 \r
-spl::shared_ptr<AVFrame> make_av_frame(caspar::core::data_frame& frame)\r
+spl::shared_ptr<AVFrame> make_av_frame(core::mutable_frame& frame)\r
 {\r
        std::array<uint8_t*, 4> data = {};\r
        for(int n = 0; n < frame.pixel_format_desc().planes.size(); ++n)\r
index 4288a8e8aafbb0e7e4cc5e40a48e1f9a17890f3c..87310f9d430d7533297ada7547de5e70c73c1ba7 100644 (file)
@@ -38,8 +38,7 @@ struct AVRational;
 struct AVCodecContext;\r
 \r
 FORWARD2(caspar, core, struct pixel_format_desc);\r
-FORWARD2(caspar, core, class data_frame);\r
-FORWARD2(caspar, core, class data_frame);\r
+FORWARD2(caspar, core, class mutable_frame);\r
 FORWARD2(caspar, core, class frame_factory);\r
 \r
 namespace caspar { namespace ffmpeg {\r
@@ -55,8 +54,8 @@ static const int CASPAR_PIX_FMT_LUMA = 10; // Just hijack some unual pixel forma
 \r
 core::field_mode                                       get_mode(const AVFrame& frame);\r
 int                                                                    make_alpha_format(int format); // NOTE: Be careful about CASPAR_PIX_FMT_LUMA, change it to PIX_FMT_GRAY8 if you want to use the frame inside some ffmpeg function.\r
-spl::unique_ptr<core::data_frame>      make_data_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags);\r
-spl::shared_ptr<AVFrame>                       make_av_frame(caspar::core::data_frame& frame);\r
+core::mutable_frame                    make_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, double fps, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags);\r
+spl::shared_ptr<AVFrame>                       make_av_frame(core::mutable_frame& frame);\r
 spl::shared_ptr<AVFrame>                       make_av_frame(std::array<uint8_t*, 4> data, const core::pixel_format_desc& pix_desc);\r
 \r
 core::pixel_format_desc                                pixel_format_desc(PixelFormat pix_fmt, int width, int height);\r
index dac404547ffdd780d15a11b58192d12715c0be59..bfdcfa91a93bc7148ed8f16dac1dd606b1250440 100644 (file)
@@ -55,9 +55,9 @@ FlashAxContainer::~FlashAxContainer()
 }\r
 \r
 \r
-///////////////////\r
+/////////\r
 // IObjectWithSite\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)\r
 {\r
        ATLTRACE(_T("IObjectWithSite::SetSite\n"));\r
@@ -76,9 +76,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)
        return hr;\r
 }\r
 \r
-///////////////////\r
+/////////\r
 // IOleClientSite\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject()\r
 {\r
        ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));\r
@@ -130,9 +130,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout()
        return S_OK;\r
 }\r
 \r
-///////////////////\r
+/////////\r
 // IOleInPlaceSite\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd)\r
 {\r
        ATLTRACE(_T("IOleInPlaceSite::GetWindow\n"));\r
@@ -233,9 +233,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect)
 }\r
 \r
 \r
-/////////////////////\r
+//////////\r
 // IOleInPlaceSiteEx\r
-/////////////////////\r
+//////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags)\r
 {\r
        // should only be called once the first time control is inplace-activated\r
@@ -272,9 +272,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate()
 }\r
 \r
 \r
-/////////////////////////////\r
+//////////////\r
 // IOleInPlaceSiteWindowless\r
-/////////////////////////////\r
+//////////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate()\r
 {\r
        ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n"));\r
@@ -360,9 +360,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM
        return S_OK;\r
 }\r
 \r
-///////////////////\r
+/////////\r
 // IOleControlSite\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged()\r
 {\r
        ATLTRACE(_T("IOleControlSite::OnControlInfoChanged"));\r
@@ -409,9 +409,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame()
 }\r
 \r
 \r
-///////////////////\r
+/////////\r
 // IAdviseSink\r
-///////////////////\r
+/////////\r
 void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed)\r
 {\r
        ATLTRACE(_T("IAdviseSink::OnDataChange\n"));\r
@@ -448,9 +448,9 @@ DEFINE_GUID2(IID_IDirectDraw3,0x618f8ad4,0x8b7a,0x11d0,0x8f,0xcc,0x0,0xc0,0x4f,0
 DEFINE_GUID2(IID_IDirectDraw4,0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5);\r
 DEFINE_GUID2(IID_IDirectDraw7,0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);\r
 \r
-///////////////////\r
+/////////\r
 // IServiceProvider\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj) \r
 {\r
 //     ATLTRACE(_T("IServiceProvider::QueryService\n"));\r
@@ -494,9 +494,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID r
 }\r
 \r
 \r
-///////////////////\r
+/////////\r
 // ITimerService\r
-///////////////////\r
+/////////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)\r
 {\r
        ATLTRACE(_T("ITimerService::CreateTimer\n"));\r
@@ -526,9 +526,9 @@ HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguid
        return S_OK;\r
 }\r
 \r
-///////////\r
+//////\r
 // ITimer\r
-///////////\r
+//////\r
 HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie)\r
 {\r
        ATLTRACE(_T("Timer::Advise\n"));\r
index ebee8324fed049c97f61433268ce7b32cb4688a3..1e6086866894983beb8cde886a53526fcfd8f018 100644 (file)
@@ -146,7 +146,7 @@ cg_proxy create_cg_proxy(const spl::shared_ptr<core::video_channel>& video_chann
        {\r
                if(flash_producer->name() != L"flash")\r
                {\r
-                       flash_producer = flash::create_producer(video_channel->frame_factory(), boost::assign::list_of<std::wstring>());        \r
+                       flash_producer = flash::create_producer(video_channel->frame_factory(), video_channel->video_format_desc(), boost::assign::list_of<std::wstring>());    \r
                        video_channel->stage().load(render_layer, flash_producer); \r
                        video_channel->stage().play(render_layer);\r
                }\r
@@ -160,7 +160,7 @@ cg_proxy create_cg_proxy(const spl::shared_ptr<core::video_channel>& video_chann
        return cg_proxy(std::move(flash_producer));\r
 }\r
 \r
-spl::shared_ptr<core::frame_producer> create_ct_producer(const spl::shared_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params) \r
+spl::shared_ptr<core::frame_producer> create_ct_producer(const spl::shared_ptr<core::frame_factory> frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params) \r
 {\r
        std::wstring filename = env::media_folder() + L"\\" + params[0] + L".ct";\r
        if(!boost::filesystem::exists(filename))\r
@@ -170,7 +170,7 @@ spl::shared_ptr<core::frame_producer> create_ct_producer(const spl::shared_ptr<c
        path = boost::filesystem3::complete(path);\r
        filename = path.wstring();\r
 \r
-       auto flash_producer = flash::create_producer(frame_factory, boost::assign::list_of<std::wstring>());    \r
+       auto flash_producer = flash::create_producer(frame_factory, format_desc, boost::assign::list_of<std::wstring>());       \r
        auto producer = flash_producer;\r
        cg_proxy(producer).add(0, filename, 1);\r
 \r
index 9fdb0b13f067f5e2943fbc3e8e850ee5a65412e7..4803d816ca95ffa1e738a56e0fc97a2f250f5f66 100644 (file)
@@ -58,6 +58,6 @@ private:
 };\r
 cg_proxy create_cg_proxy(const spl::shared_ptr<core::video_channel>& video_channel, int layer_index = cg_proxy::DEFAULT_LAYER);\r
 \r
-spl::shared_ptr<core::frame_producer> create_ct_producer(const spl::shared_ptr<core::frame_factory> frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_ct_producer(const spl::shared_ptr<core::frame_factory> frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 }}
\ No newline at end of file
index 4fc153317a233c4d255600458f3d486ea737a4a9..d9412fc7bf5bdfd69dc3e985bc55defd106959ae 100644 (file)
@@ -31,7 +31,7 @@
 \r
 #include <core/video_format.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/pixel_format.h>\r
@@ -292,7 +292,7 @@ public:
                        desc.planes.push_back(core::pixel_format_desc::plane(width_, height_, 4));\r
                        auto frame = frame_factory_->create_frame(this, desc, fps(), core::field_mode::progressive);\r
 \r
-                       A_memcpy(frame->image_data(0).begin(), bmp_.data(), width_*height_*4);\r
+                       A_memcpy(frame.image_data(0).begin(), bmp_.data(), width_*height_*4);\r
                        head_ = core::draw_frame(std::move(frame));     \r
                }               \r
                                                                                \r
@@ -323,6 +323,7 @@ struct flash_producer : public core::frame_producer
 {      \r
        const std::wstring                                                              filename_;      \r
        const spl::shared_ptr<core::frame_factory>              frame_factory_;\r
+       const core::video_format_desc                                   format_desc_;\r
        const int                                                                               width_;\r
        const int                                                                               height_;\r
        const int                                                                               buffer_size_;\r
@@ -340,12 +341,13 @@ struct flash_producer : public core::frame_producer
 \r
        executor                                                                                executor_;      \r
 public:\r
-       flash_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int width, int height) \r
+       flash_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::wstring& filename, int width, int height) \r
                : filename_(filename)           \r
                , frame_factory_(frame_factory)\r
-               , width_(width > 0 ? width : frame_factory->video_format_desc().width)\r
-               , height_(height > 0 ? height : frame_factory->video_format_desc().height)\r
-               , buffer_size_(env::properties().get(L"configuration.flash.buffer-depth", frame_factory_->video_format_desc().fps > 30.0 ? 4 : 2))\r
+               , format_desc_(format_desc)\r
+               , width_(width > 0 ? width : format_desc.width)\r
+               , height_(height > 0 ? height : format_desc.height)\r
+               , buffer_size_(env::properties().get(L"configuration.flash.buffer-depth", format_desc.fps > 30.0 ? 4 : 2))\r
                , last_frame_(core::draw_frame::empty())\r
                , executor_(L"flash_producer")\r
        {       \r
@@ -447,21 +449,19 @@ public:
                        frame_buffer_.push(core::draw_frame::empty());\r
 \r
                if(frame_buffer_.empty())\r
-               {\r
-                       auto format_desc = frame_factory_->video_format_desc();\r
-                                       \r
+               {                                       \r
                        tick();\r
                        auto frame = renderer_->render();\r
 \r
-                       if(abs(renderer_->fps()/2.0 - format_desc.fps) < 2.0) // flash == 2 * format -> interlace\r
+                       if(abs(renderer_->fps()/2.0 - format_desc_.fps) < 2.0) // flash == 2 * format -> interlace\r
                        {                                       \r
                                tick();\r
-                               if(format_desc.field_mode != core::field_mode::progressive)\r
-                                       frame = core::draw_frame::interlace(frame, renderer_->render(), format_desc.field_mode);\r
+                               if(format_desc_.field_mode != core::field_mode::progressive)\r
+                                       frame = core::draw_frame::interlace(frame, renderer_->render(), format_desc_.field_mode);\r
                                \r
                                frame_buffer_.push(frame);\r
                        }\r
-                       else if(abs(renderer_->fps() - format_desc.fps/2.0) < 2.0) // format == 2 * flash -> duplicate\r
+                       else if(abs(renderer_->fps() - format_desc_.fps/2.0) < 2.0) // format == 2 * flash -> duplicate\r
                        {\r
                                frame_buffer_.push(frame);\r
                                frame_buffer_.push(frame);\r
@@ -483,16 +483,16 @@ public:
        }\r
 };\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {\r
-       auto template_host = get_template_host(frame_factory->video_format_desc());\r
+       auto template_host = get_template_host(format_desc);\r
        \r
        auto filename = env::template_folder() + L"\\" + template_host.filename;\r
        \r
        if(!boost::filesystem::exists(filename))\r
                BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(u8(filename)));      \r
 \r
-       return spl::make_shared<flash_producer>(frame_factory, filename, template_host.width, template_host.height);\r
+       return spl::make_shared<flash_producer>(frame_factory, format_desc, filename, template_host.width, template_host.height);\r
 }\r
 \r
 std::wstring find_template(const std::wstring& template_name)\r
index e1c813581d543ead76ceca164fdba35803f7b084..ff0d72907a12890bae40694260003c156bb6f0c3 100644 (file)
@@ -30,7 +30,7 @@
 \r
 namespace caspar { namespace flash {\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 std::wstring find_template(const std::wstring& templateName);\r
 \r
index 2214c87801134c1c315cbd1cf350bff2a49e048a..9424750630864f0e6d0a3648545583c2ae4167ec 100644 (file)
@@ -28,7 +28,7 @@
 \r
 #include <core/consumer/frame_consumer.h>\r
 #include <core/video_format.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <boost/date_time/posix_time/posix_time.hpp>\r
 #include <boost/thread.hpp>\r
@@ -53,7 +53,7 @@ public:
        {\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {                               \r
                boost::thread async([frame]\r
                {\r
@@ -61,8 +61,8 @@ public:
                        {\r
                                auto filename = u8(env::data_folder()) +  boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time()) + ".png";\r
 \r
-                               auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Allocate(frame->width(), frame->height(), 32), FreeImage_Unload);\r
-                               A_memcpy(FreeImage_GetBits(bitmap.get()), frame->image_data().begin(), frame->image_data().size());\r
+                               auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Allocate(static_cast<int>(frame.width()), static_cast<int>(frame.height()), 32), FreeImage_Unload);\r
+                               A_memcpy(FreeImage_GetBits(bitmap.get()), frame.image_data().begin(), frame.image_data().size());\r
                                FreeImage_FlipVertical(bitmap.get());\r
                                FreeImage_Save(FIF_PNG, bitmap.get(), filename.c_str(), 0);\r
                        }\r
index 29ed59fb45503a2407ee5b9126bb17967c6a9745..ca9d013158d302bbcd2c81e049f335801b1c2664 100644 (file)
@@ -25,7 +25,7 @@
 \r
 #include <core/video_format.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/pixel_format.h>\r
@@ -59,7 +59,7 @@ struct image_producer : public core::frame_producer
                desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4));\r
                auto frame = frame_factory->create_frame(this, desc);\r
 \r
-               std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data(0).size(), frame->image_data(0).begin());\r
+               std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data(0).size(), frame.image_data(0).begin());\r
                frame_ = core::draw_frame(std::move(frame));\r
 \r
                CASPAR_LOG(info) << print() << L" Initialized";\r
@@ -96,7 +96,7 @@ struct image_producer : public core::frame_producer
        }\r
 };\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L".png")(L".tga")(L".bmp")(L".jpg")(L".jpeg")(L".gif")(L".tiff")(L".tif")(L".jp2")(L".jpx")(L".j2k")(L".j2c");\r
        std::wstring filename = env::media_folder() + L"\\" + params[0];\r
index aac1f755a57a4b59251cc7b3c6a7b5f28142da14..cd5cede62673836004c621ba8bb13d75506f9038 100644 (file)
@@ -28,6 +28,6 @@
 \r
 namespace caspar { namespace image {\r
 \r
-spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 }}
\ No newline at end of file
index 29a7858d84f12616270182567c35c90cfbc07809..5d138593645e50f5bb8fd6ad77e4d8feb426902d 100644 (file)
@@ -25,7 +25,7 @@
 \r
 #include <core/video_format.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/frame_transform.h>\r
@@ -50,23 +50,23 @@ namespace caspar { namespace image {
                \r
 struct image_scroll_producer : public core::frame_producer\r
 {      \r
-       const std::wstring                                                              filename_;\r
+       const std::wstring                              filename_;\r
        std::vector<core::draw_frame>   frames_;\r
-       core::video_format_desc                                                 format_desc_;\r
-       int                                                                                             width_;\r
-       int                                                                                             height_;\r
+       core::video_format_desc                 format_desc_;\r
+       int                                                             width_;\r
+       int                                                             height_;\r
 \r
-       int                                                                                             delta_;\r
-       int                                                                                             speed_;\r
+       int                                                             delta_;\r
+       int                                                             speed_;\r
 \r
-       std::array<double, 2>                                                   start_offset_;\r
+       std::array<double, 2>                   start_offset_;\r
 \r
        core::draw_frame                                last_frame_;\r
 \r
-       explicit image_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int speed) \r
+       explicit image_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::wstring& filename, int speed) \r
                : filename_(filename)\r
                , delta_(0)\r
-               , format_desc_(frame_factory->video_format_desc())\r
+               , format_desc_(format_desc)\r
                , speed_(speed)\r
                , last_frame_(core::draw_frame::empty())\r
        {\r
@@ -79,7 +79,7 @@ struct image_scroll_producer : public core::frame_producer
                height_ = FreeImage_GetHeight(bitmap.get());\r
 \r
                auto bytes = FreeImage_GetBits(bitmap.get());\r
-               int count = width_*height_*4;\r
+               auto count = width_*height_*4;\r
 \r
                if(height_ > format_desc_.height)\r
                {\r
@@ -89,15 +89,15 @@ struct image_scroll_producer : public core::frame_producer
                                desc.planes.push_back(core::pixel_format_desc::plane(width_, format_desc_.height, 4));\r
                                auto frame = frame_factory->create_frame(reinterpret_cast<void*>(rand()), desc);\r
 \r
-                               if(count >= frame->image_data(0).size())\r
+                               if(count >= frame.image_data(0).size())\r
                                {       \r
-                                       std::copy_n(bytes + count - frame->image_data(0).size(), frame->image_data(0).size(), frame->image_data(0).begin());\r
-                                       count -= static_cast<int>(frame->image_data(0).size());\r
+                                       std::copy_n(bytes + count - frame.image_data(0).size(), frame.image_data(0).size(), frame.image_data(0).begin());\r
+                                       count -= static_cast<int>(frame.image_data(0).size());\r
                                }\r
                                else\r
                                {\r
-                                       memset(frame->image_data(0).begin(), 0, frame->image_data(0).size());   \r
-                                       std::copy_n(bytes, count, frame->image_data(0).begin() + format_desc_.size - count);\r
+                                       memset(frame.image_data(0).begin(), 0, frame.image_data(0).size());     \r
+                                       std::copy_n(bytes, count, frame.image_data(0).begin() + format_desc_.size - count);\r
                                        count = 0;\r
                                }\r
                        \r
@@ -119,20 +119,20 @@ struct image_scroll_producer : public core::frame_producer
                                core::pixel_format_desc desc = core::pixel_format::bgra;\r
                                desc.planes.push_back(core::pixel_format_desc::plane(format_desc_.width, height_, 4));\r
                                auto frame = frame_factory->create_frame(reinterpret_cast<void*>(rand()), desc);\r
-                               if(count >= frame->image_data(0).size())\r
+                               if(count >= frame.image_data(0).size())\r
                                {       \r
                                        for(int y = 0; y < height_; ++y)\r
-                                               std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, format_desc_.width*4, frame->image_data(0).begin() + y * format_desc_.width*4);\r
+                                               std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, format_desc_.width*4, frame.image_data(0).begin() + y * format_desc_.width*4);\r
                                        \r
                                        ++i;\r
-                                       count -= static_cast<int>(frame->image_data(0).size());\r
+                                       count -= static_cast<int>(frame.image_data(0).size());\r
                                }\r
                                else\r
                                {\r
-                                       memset(frame->image_data(0).begin(), 0, frame->image_data(0).size());   \r
-                                       int width2 = width_ % format_desc_.width;\r
+                                       memset(frame.image_data(0).begin(), 0, frame.image_data(0).size());     \r
+                                       auto width2 = width_ % format_desc_.width;\r
                                        for(int y = 0; y < height_; ++y)\r
-                                               std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, width2*4, frame->image_data(0).begin() + y * format_desc_.width*4);\r
+                                               std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, width2*4, frame.image_data(0).begin() + y * format_desc_.width*4);\r
 \r
                                        count = 0;\r
                                }\r
@@ -230,7 +230,7 @@ struct image_scroll_producer : public core::frame_producer
        }\r
 };\r
 \r
-spl::shared_ptr<core::frame_producer> create_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+spl::shared_ptr<core::frame_producer> create_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg")(L"gif")(L"tiff")(L"tif")(L"jp2")(L"jpx")(L"j2k")(L"j2c");\r
        std::wstring filename = env::media_folder() + L"\\" + params[0];\r
@@ -254,7 +254,7 @@ spl::shared_ptr<core::frame_producer> create_scroll_producer(const spl::shared_p
        if(speed == 0)\r
                return core::frame_producer::empty();\r
 \r
-       return spl::make_shared<image_scroll_producer>(frame_factory, filename + L"." + *ext, speed);\r
+       return spl::make_shared<image_scroll_producer>(frame_factory, format_desc, filename + L"." + *ext, speed);\r
 }\r
 \r
 }}
\ No newline at end of file
index 9ed547f20d0d69088d629159c0a2e6fbbd1b9b15..7a0978691f26f8dfb830c60e50b996185f1f2785 100644 (file)
@@ -28,6 +28,6 @@
 \r
 namespace caspar { namespace image {\r
 \r
-spl::shared_ptr<core::frame_producer> create_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+spl::shared_ptr<core::frame_producer> create_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, const std::vector<std::wstring>& params);\r
 \r
 }}
\ No newline at end of file
index c401e973a061fe52eb0961279128dd920b2fd275..9c39c68f98641fb64914831c6917e0e721f70f17 100644 (file)
@@ -32,7 +32,7 @@
 #include <core/mixer/audio/audio_mixer.h>\r
 #include <core/video_format.h>\r
 \r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <SFML/Audio/SoundStream.hpp>\r
 \r
@@ -95,9 +95,9 @@ public:
                }\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {                       \r
-               input_.push(std::make_shared<audio_buffer_16>(core::audio_32_to_16(frame->audio_data())));\r
+               input_.push(std::make_shared<audio_buffer_16>(core::audio_32_to_16(frame.audio_data())));\r
                return true;\r
        }\r
        \r
index cfa0b79baa850e4a6a92824f8062aa80b54915a6..b3b318103b42818cdc4c02e089fe0e1617160c18 100644 (file)
@@ -27,7 +27,7 @@
 #include <core/frame/draw_frame.h>\r
 #include <core/frame/frame_factory.h>\r
 #include <core/frame/pixel_format.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 #include <common/except.h>\r
 #include <common/diagnostics/graph.h>\r
 \r
 namespace caspar { namespace reroute {\r
 //             \r
-//class reroute_producer : public reactive::observer<spl::shared_ptr<const core::data_frame>>\r
+//class reroute_producer : public reactive::observer<spl::shared_ptr<const core::frame>>\r
 //                                        , public core::frame_producer\r
 //{\r
 //     const spl::shared_ptr<diagnostics::graph>                                                                       graph_;\r
 //     const spl::shared_ptr<core::frame_factory>                                                                      frame_factory_;\r
 //     \r
-//     tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>>          input_buffer_;\r
+//     tbb::concurrent_bounded_queue<std::shared_ptr<const core::frame>>               input_buffer_;\r
 //     std::queue<core::draw_frame>                                                                                            frame_buffer_;\r
 //     uint64_t                                                                                                                                        frame_number_;\r
 //\r
@@ -73,7 +73,7 @@ namespace caspar { namespace reroute {
 //     \r
 //     // observable\r
 //\r
-//     void on_next(const spl::shared_ptr<const core::data_frame>& frame)\r
+//     void on_next(const spl::shared_ptr<const core::frame>& frame)\r
 //     {\r
 //             if(!input_buffer_.try_push(frame))\r
 //                     graph_->set_tag("dropped-frame");\r
@@ -90,7 +90,7 @@ namespace caspar { namespace reroute {
 //                     return last_frame_ = frame;\r
 //             }\r
 //             \r
-//             std::shared_ptr<const core::data_frame> read_frame;\r
+//             std::shared_ptr<const core::frame> read_frame;\r
 //             if(!input_buffer_.try_pop(read_frame))\r
 //             {\r
 //                     graph_->set_tag("late-frame");\r
index 67ab7d8ea39f0fc71a1d92ad1fa37ed38a62288c..d80f7610adc97d50b0ce65f29bf251b2a7183125 100644 (file)
@@ -26,7 +26,7 @@
 \r
 #include <core/frame/frame_factory.h>\r
 #include <core/producer/frame_producer.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 \r
 FORWARD2(caspar, core, class video_channel);\r
 \r
index 17915bc1c5c07a0dfa6f4de3f79ae0fda779100c..446dfa30d8afe73faa6a2a79d207835e8529151d 100644 (file)
@@ -34,7 +34,7 @@
 #include <ffmpeg/producer/filter/filter.h>\r
 \r
 #include <core/video_format.h>\r
-#include <core/frame/data_frame.h>\r
+#include <core/frame/frame.h>\r
 #include <core/consumer/frame_consumer.h>\r
 \r
 #include <boost/timer.hpp>\r
@@ -121,20 +121,20 @@ struct screen_consumer : boost::noncopyable
                        \r
        float                                   width_;\r
        float                                   height_;        \r
-       unsigned int                    screen_x_;\r
-       unsigned int                    screen_y_;\r
-       unsigned int                    screen_width_;\r
-       unsigned int                    screen_height_;\r
-       int                                             square_width_;\r
-       int                                             square_height_;                         \r
+       int                             screen_x_;\r
+       int                             screen_y_;\r
+       int                             screen_width_;\r
+       int                             screen_height_;\r
+       int                             square_width_;\r
+       int                             square_height_;                         \r
        \r
        sf::Window                              window_;\r
        \r
        spl::shared_ptr<diagnostics::graph>     graph_;\r
-       boost::timer                                    perf_timer_;\r
-       boost::timer                                    tick_timer_;\r
+       boost::timer                                            perf_timer_;\r
+       boost::timer                                            tick_timer_;\r
 \r
-       tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>>  frame_buffer_;\r
+       tbb::concurrent_bounded_queue<core::const_frame>        frame_buffer_;\r
 \r
        boost::thread                   thread_;\r
        tbb::atomic<bool>               is_running_;\r
@@ -197,7 +197,7 @@ public:
        ~screen_consumer()\r
        {\r
                is_running_ = false;\r
-               frame_buffer_.try_push(core::data_frame::empty());\r
+               frame_buffer_.try_push(core::const_frame::empty());\r
                thread_.join();\r
        }\r
 \r
@@ -286,11 +286,11 @@ public:
                                                        is_running_ = false;\r
                                        }\r
                        \r
-                                       std::shared_ptr<const core::data_frame> frame;\r
+                                       auto frame = core::const_frame::empty();\r
                                        frame_buffer_.pop(frame);\r
                                        \r
                                        perf_timer_.restart();\r
-                                       render(spl::make_shared_ptr(frame));\r
+                                       render(frame);\r
                                        graph_->set_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5);    \r
 \r
                                        window_.Display();\r
@@ -328,13 +328,13 @@ public:
                return av_frame;\r
        }\r
 \r
-       void render(const spl::shared_ptr<const core::data_frame>& frame)\r
+       void render(core::const_frame frame)\r
        {                       \r
-               if(static_cast<int>(frame->image_data().size()) != format_desc_.size)\r
+               if(static_cast<int>(frame.image_data().size()) != format_desc_.size)\r
                        return;\r
                                        \r
                auto av_frame = get_av_frame();\r
-               av_frame->data[0] = const_cast<uint8_t*>(frame->image_data().begin());\r
+               av_frame->data[0] = const_cast<uint8_t*>(frame.image_data().begin());\r
 \r
                filter_.push(av_frame);\r
                auto frames = filter_.poll_all();\r
@@ -390,7 +390,7 @@ public:
                std::rotate(pbos_.begin(), pbos_.begin() + 1, pbos_.end());\r
        }\r
 \r
-       bool send(const spl::shared_ptr<const core::data_frame>& frame)\r
+       bool send(core::const_frame frame)\r
        {\r
                if(!frame_buffer_.try_push(frame))\r
                        graph_->set_tag("dropped-frame");\r
@@ -478,7 +478,7 @@ public:
                consumer_.reset(new screen_consumer(config_, format_desc, channel_index));\r
        }\r
        \r
-       virtual bool send(const spl::shared_ptr<const core::data_frame>& frame) override\r
+       virtual bool send(core::const_frame frame) override\r
        {\r
                return consumer_->send(frame);\r
        }\r
index 6293841f4d58e0c5fa353b3266ace10ef7d6b347..8f62d463dbc092c183f709d000cba4e3c248e04b 100644 (file)
@@ -636,7 +636,7 @@ bool LoadCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(GetChannel()->frame_factory(), _parameters);         \r
+               auto pFP = create_producer(GetChannel()->frame_factory(), GetChannel()->video_format_desc(), _parameters);              \r
                GetChannel()->stage().load(GetLayerIndex(), pFP, true);\r
        \r
                SetReplyString(TEXT("202 LOAD OK\r\n"));\r
@@ -742,7 +742,7 @@ bool LoadbgCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(GetChannel()->frame_factory(), _parameters);\r
+               auto pFP = create_producer(GetChannel()->frame_factory(), GetChannel()->video_format_desc(), _parameters);\r
                if(pFP == frame_producer::empty())\r
                        BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? _parameters[0] : L""));\r
 \r
index b7660e7658b8e9bfd84a12660441c157ab628012..78fad5f79e3975e7a74d1e0ff27b7644a58f03ac 100644 (file)
@@ -36,7 +36,7 @@
 \r
 namespace caspar { namespace protocol { namespace cii {\r
 \r
-/////////////////\r
+////////\r
 // MediaCommand\r
 void MediaCommand::Setup(const std::vector<std::wstring>& parameters) \r
 {\r
@@ -49,7 +49,7 @@ void MediaCommand::Execute()
 }\r
 \r
 \r
-/////////////////\r
+////////\r
 // WriteCommand\r
 void WriteCommand::Setup(const std::vector<std::wstring>& parameters)\r
 {\r
@@ -82,7 +82,7 @@ void WriteCommand::Execute()
 }\r
 \r
 \r
-//////////////////////\r
+//////////\r
 // ImagestoreCommand\r
 void ImagestoreCommand::Setup(const std::vector<std::wstring>& parameters) \r
 {\r
@@ -96,7 +96,7 @@ void ImagestoreCommand::Execute()
 }\r
 \r
 \r
-//////////////////////\r
+//////////\r
 // MiscellaneousCommand\r
 void MiscellaneousCommand::Setup(const std::vector<std::wstring>& parameters)\r
 {\r
@@ -160,7 +160,7 @@ void MiscellaneousCommand::Execute()
 }\r
 \r
 \r
-///////////////////\r
+/////////\r
 // KeydataCommand\r
 void KeydataCommand::Execute() \r
 {\r
index b8f8ae84742efbdd01f191b4e46cc549641e2027..691dd371662d694d6238ac8f7a642ae8092b663f 100644 (file)
@@ -184,7 +184,7 @@ void CIIProtocolStrategy::WriteTemplateData(const std::wstring& templateName, co
                return;\r
        }\r
        \r
-       auto producer = flash::create_producer(this->GetChannel()->frame_factory(), boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
+       auto producer = flash::create_producer(this->GetChannel()->frame_factory(), this->GetChannel()->video_format_desc(), boost::assign::list_of(env::template_folder()+TEXT("CG.fth")));\r
 \r
        std::wstringstream flashParam;\r
        flashParam << TEXT("<invoke name=\"Add\" returntype=\"xml\"><arguments><number>1</number><string>") << currentProfile_ << '/' <<  templateName << TEXT("</string><number>0</number><true/><string> </string><string><![CDATA[ ") << xmlData << TEXT(" ]]></string></arguments></invoke>");\r
@@ -217,7 +217,7 @@ void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename)
        transition.type = transition_type::mix;\r
        transition.duration = 12;\r
 \r
-       auto pFP = create_producer(GetChannel()->frame_factory(), filename);\r
+       auto pFP = create_producer(GetChannel()->frame_factory(), GetChannel()->video_format_desc(), filename);\r
        auto pTransition = create_transition_producer(GetChannel()->video_format_desc().field_mode, pFP, transition);\r
 \r
        try\r
index c493d9ced62303b93d02651b26037dbc38dccac3..d1a248d88cecd15ef627ded3a7f2294506ad6cb6 100644 (file)
@@ -32,7 +32,7 @@
 \r
 //#define OSC_HOST_BIG_ENDIAN 1\r
 \r
-///*\r
+//*\r
 //    Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined\r
 //\r
 //    If you know a way to enhance the detection below for Linux and/or MacOSX\r
 //\r
 //#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN)\r
 //\r
-//// you can define one of the above symbols from the command line\r
-//// then you don't have to edit this file.\r
+// you can define one of the above symbols from the command line\r
+// then you don't have to edit this file.\r
 //\r
 //#elif defined(__WIN32__) || defined(WIN32) || defined(WINCE)\r
 //\r
-//// assume that __WIN32__ is only defined on little endian systems\r
+// assume that __WIN32__ is only defined on little endian systems\r
 //\r
 //#define OSC_HOST_LITTLE_ENDIAN 1\r
 //#undef OSC_HOST_BIG_ENDIAN\r
index 9946c55c391debeb40a0f0a5b1cfcd615e41e7d6..1ea754bd1a466f658de9c35d4d42690ffa8b5861 100644 (file)
@@ -22,7 +22,7 @@
  \r
 // AsyncEventServer.cpp: impl of the AsyncEventServer class.\r
 //\r
-//////////////////////////////////////////////////////////////////////\r
+////////////////////////////////\r
 \r
 #include "../stdafx.h"\r
 \r
@@ -43,7 +43,7 @@ namespace caspar { namespace IO {
 #define CASPAR_MAXIMUM_SOCKET_CLIENTS  (MAXIMUM_WAIT_OBJECTS-1)        \r
 \r
 long AsyncEventServer::instanceCount_ = 0;\r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer constructor\r
 // PARAMS: port(TCP-port the server should listen to)\r
 // COMMENT: Initializes the WinSock2 library\r
@@ -61,7 +61,7 @@ AsyncEventServer::AsyncEventServer(const spl::shared_ptr<IProtocolStrategy>& pPr
        InterlockedIncrement(&instanceCount_);\r
 }\r
 \r
-/////////////////////////////\r
+//////////////\r
 // AsyncEventServer destructor\r
 AsyncEventServer::~AsyncEventServer() {\r
        Stop();\r
@@ -75,7 +75,7 @@ void AsyncEventServer::SetClientDisconnectHandler(ClientDisconnectEvent handler)
        socketInfoCollection_.onSocketInfoRemoved = handler;\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::Start\r
 // RETURNS: true at successful startup\r
 bool AsyncEventServer::Start() {\r
@@ -215,7 +215,7 @@ bool AsyncEventServer::OnUnhandledException(const std::exception& ex) throw() {
        return bDoRestart;\r
 }\r
 \r
-///////////////////////////////\r
+//////////////\r
 // AsyncEventServer:Stop\r
 // COMMENT: Shuts down\r
 void AsyncEventServer::Stop()\r
@@ -232,14 +232,14 @@ void AsyncEventServer::Stop()
        socketInfoCollection_.Clear();\r
 }\r
 \r
-////////////////////////////////////////////////////////////////////\r
+///////////////////////////////\r
 //\r
 // MESSAGE HANDLERS   \r
 //\r
-////////////////////////////////////////////////////////////////////\r
+///////////////////////////////\r
 \r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::OnAccept\r
 // PARAMS: ...\r
 // COMMENT: Called when a new client connects\r
@@ -336,7 +336,7 @@ bool ConvertMultiByteToWideChar(UINT codePage, char* pSource, int sourceLength,
        return (charsWritten > 0);\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::OnRead\r
 // PARAMS: ...\r
 // COMMENT: Called then something arrives on the socket that has to be read\r
@@ -376,7 +376,7 @@ bool AsyncEventServer::OnRead(SocketInfoPtr& pSI) {
        return false;\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::OnWrite\r
 // PARAMS: ...\r
 // COMMENT: Called when the socket is ready to send more data\r
@@ -457,7 +457,7 @@ void AsyncEventServer::DoSend(SocketInfo& socketInfo) {
        }\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::OnClose\r
 // PARAMS: ...\r
 // COMMENT: Called when a client disconnects / is disconnected\r
@@ -467,7 +467,7 @@ void AsyncEventServer::OnClose(SocketInfoPtr& pSI) {
        socketInfoCollection_.RemoveSocketInfo(pSI);\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::OnError\r
 // PARAMS: ...\r
 // COMMENT: Called when an errorcode is recieved\r
@@ -482,7 +482,7 @@ void AsyncEventServer::OnError(HANDLE waitEvent, int errorCode) {
        }\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::DisconnectClient\r
 // PARAMS: ...\r
 // COMMENT: The client is removed from the actual client-list when an FD_CLOSE notification is recieved\r
@@ -492,7 +492,7 @@ void AsyncEventServer::DisconnectClient(SocketInfo& socketInfo) {
                OnError(socketInfo.event_, result);\r
 }\r
 \r
-//////////////////////////////\r
+//////////////\r
 // AsyncEventServer::LogSocketError\r
 void AsyncEventServer::LogSocketError(const TCHAR* pStr, int socketError) {\r
        if(socketError == 0)\r
@@ -502,9 +502,9 @@ void AsyncEventServer::LogSocketError(const TCHAR* pStr, int socketError) {
 }\r
 \r
 \r
-//////////////////////////////\r
+//////////////\r
 //  SocketInfoCollection\r
-//////////////////////////////\r
+//////////////\r
 \r
 AsyncEventServer::SocketInfoCollection::SocketInfoCollection() : bDirty_(false) {\r
 }\r
index 6436f36082b3dd5af500315c80f63b4da43c34b8..eee4dfa0766b522317e22687e9fe338060aa7eab 100644 (file)
@@ -21,7 +21,7 @@
 \r
  \r
 // AsyncEventServer.h: interface for the AsyncServer class.\r
-//////////////////////////////////////////////////////////////////////\r
+////////////////////////////////\r
 \r
 #if !defined(AFX_ASYNCEVENTSERVER_H__0BFA29CB_BE4C_46A0_9CAE_E233ED27A8EC__INCLUDED_)\r
 #define AFX_ASYNCEVENTSERVER_H__0BFA29CB_BE4C_46A0_9CAE_E233ED27A8EC__INCLUDED_\r
index ecc27fc34df45805e111fe12856fc38c167bc02e..8f9cfed8567465b62b1edfeeb1666bd1a1aebc9c 100644 (file)
@@ -17,7 +17,6 @@
       <consumers>\r
         <screen>\r
         </screen>\r
-        <decklink></decklink>\r
       </consumers>\r
     </channel>\r
   </channels>\r
index 493340622a49bd170b320af6f6c7e2e64addc7bf..a797f34d2d1e738eb8e385ad44c7bfbb65001fcb 100644 (file)
@@ -161,6 +161,111 @@ LONG WINAPI UserUnhandledExceptionFilter(EXCEPTION_POINTERS* info)
     return EXCEPTION_EXECUTE_HANDLER;\r
 }\r
 \r
+void run()\r
+{\r
+       // Create server object which initializes channels, protocols and controllers.\r
+       server caspar_server;\r
+                               \r
+       auto server = spl::make_shared<protocol::osc::server>(5253);\r
+       caspar_server.subscribe(server);\r
+                                               \r
+       //auto console_obs = reactive::make_observer([](const monitor::event& e)\r
+       //{\r
+       //      std::stringstream str;\r
+       //      str << e;\r
+       //      CASPAR_LOG(trace) << str.str().c_str();\r
+       //});\r
+\r
+       //caspar_server.subscribe(console_obs);\r
+                                               \r
+       // Create a amcp parser for console commands.\r
+       protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.channels());\r
+\r
+       // Create a dummy client which prints amcp responses to console.\r
+       auto console_client = std::make_shared<IO::ConsoleClientInfo>();\r
+                       \r
+       std::wstring wcmd;\r
+       while(true)\r
+       {\r
+               std::getline(std::wcin, wcmd); // TODO: It's blocking...\r
+                               \r
+               boost::to_upper(wcmd);\r
+\r
+               if(wcmd == L"EXIT" || wcmd == L"Q" || wcmd == L"QUIT" || wcmd == L"BYE")\r
+                       break;\r
+                               \r
+               // This is just dummy code for testing.\r
+               if(wcmd.substr(0, 1) == L"1")\r
+                       wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" SLIDE 100 LOOP \r\nPLAY 1-1";\r
+               else if(wcmd.substr(0, 1) == L"2")\r
+                       wcmd = L"MIXER 1-0 VIDEO IS_KEY 1";\r
+               else if(wcmd.substr(0, 1) == L"3")\r
+                       wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1";\r
+               else if(wcmd.substr(0, 1) == L"4")\r
+                       wcmd = L"PLAY 1-1 DV FILTER yadif=1:-1 LOOP";\r
+               else if(wcmd.substr(0, 1) == L"5")\r
+               {\r
+                       auto file = wcmd.substr(2, wcmd.length()-1);\r
+                       wcmd = L"PLAY 1-1 " + file + L" LOOP\r\n" \r
+                                       L"PLAY 1-2 " + file + L" LOOP\r\n" \r
+                                       L"PLAY 1-3 " + file + L" LOOP\r\n"\r
+                                       L"PLAY 2-1 " + file + L" LOOP\r\n" \r
+                                       L"PLAY 2-2 " + file + L" LOOP\r\n" \r
+                                       L"PLAY 2-3 " + file + L" LOOP\r\n";\r
+               }\r
+               else if(wcmd.substr(0, 1) == L"7")\r
+               {\r
+                       wcmd = L"";\r
+                       wcmd += L"CLEAR 1\r\n";\r
+                       wcmd += L"MIXER 1 CLEAR\r\n";\r
+                       wcmd += L"PLAY 1-0 GREEN\r\n";\r
+                       wcmd += L"PLAY 1-1 BLUE\r\n";\r
+                       wcmd += L"CG 1-2 ADD 1 ECS_TEST 1\r\n";\r
+                       wcmd += L"MIXER 1-2 FILL 0 -1 1 2\r\n";\r
+               }\r
+               else if(wcmd.substr(0, 1) == L"8")\r
+               {\r
+                       wcmd = L"";\r
+                       wcmd += L"MIXER 1-1 FILL 0.0 0.5 1.0 1.0 500 linear DEFER\r\n";\r
+                       wcmd += L"MIXER 1-2 FILL 0.0 0.0 1.0 1.0 500 linear DEFER\r\n";\r
+                       wcmd += L"MIXER 1 COMMIT\r\n";\r
+               }\r
+               else if(wcmd.substr(0, 1) == L"X")\r
+               {\r
+                       int num = 0;\r
+                       std::wstring file;\r
+                       try\r
+                       {\r
+                               num = boost::lexical_cast<int>(wcmd.substr(1, 2));\r
+                               file = wcmd.substr(4, wcmd.length()-1);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               num = boost::lexical_cast<int>(wcmd.substr(1, 1));\r
+                               file = wcmd.substr(3, wcmd.length()-1);\r
+                       }\r
+\r
+                       int n = 0;\r
+                       int num2 = num;\r
+                       while(num2 > 0)\r
+                       {\r
+                               num2 >>= 1;\r
+                               n++;\r
+                       }\r
+\r
+                       wcmd = L"MIXER 1 GRID " + boost::lexical_cast<std::wstring>(n);\r
+\r
+                       for(int i = 1; i <= num; ++i)\r
+                               wcmd += L"\r\nPLAY 1-" + boost::lexical_cast<std::wstring>(i) + L" " + file + L" LOOP";// + L" SLIDE 100 LOOP";\r
+               }\r
+\r
+               wcmd += L"\r\n";\r
+               amcp.Parse(wcmd.c_str(), static_cast<int>(wcmd.length()), console_client);\r
+       }       \r
+       Sleep(1000);\r
+       CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";\r
+}\r
+\r
 int main(int argc, wchar_t* argv[])\r
 {      \r
        SetUnhandledExceptionFilter(UserUnhandledExceptionFilter);\r
@@ -234,110 +339,9 @@ int main(int argc, wchar_t* argv[])
                boost::property_tree::xml_writer_settings<wchar_t> w(' ', 3);\r
                boost::property_tree::write_xml(str, env::properties(), w);\r
                CASPAR_LOG(info) << L"casparcg.config:\n-----------------------------------------\n" << str.str().c_str() << L"-----------------------------------------";\r
-                               \r
-               {\r
-                       // Create server object which initializes channels, protocols and controllers.\r
-                       server caspar_server;\r
-                               \r
-                       auto server = spl::make_shared<protocol::osc::server>(5253);\r
-                       caspar_server.subscribe(server);\r
-                                               \r
-                       //auto console_obs = reactive::make_observer([](const monitor::event& e)\r
-                       //{\r
-                       //      std::stringstream str;\r
-                       //      str << e;\r
-                       //      CASPAR_LOG(trace) << str.str().c_str();\r
-                       //});\r
-\r
-                       //caspar_server.subscribe(console_obs);\r
-                                               \r
-                       // Create a amcp parser for console commands.\r
-                       protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.channels());\r
-\r
-                       // Create a dummy client which prints amcp responses to console.\r
-                       auto console_client = std::make_shared<IO::ConsoleClientInfo>();\r
-                       \r
-                       std::wstring wcmd;\r
-                       while(true)\r
-                       {\r
-                               std::getline(std::wcin, wcmd); // TODO: It's blocking...\r
-                               \r
-                               boost::to_upper(wcmd);\r
-\r
-                               if(wcmd == L"EXIT" || wcmd == L"Q" || wcmd == L"QUIT" || wcmd == L"BYE")\r
-                                       break;\r
-                               \r
-                               // This is just dummy code for testing.\r
-                               if(wcmd.substr(0, 1) == L"1")\r
-                                       wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" SLIDE 100 LOOP \r\nPLAY 1-1";\r
-                               else if(wcmd.substr(0, 1) == L"2")\r
-                                       wcmd = L"MIXER 1-0 VIDEO IS_KEY 1";\r
-                               else if(wcmd.substr(0, 1) == L"3")\r
-                                       wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1";\r
-                               else if(wcmd.substr(0, 1) == L"4")\r
-                                       wcmd = L"PLAY 1-1 DV FILTER yadif=1:-1 LOOP";\r
-                               else if(wcmd.substr(0, 1) == L"5")\r
-                               {\r
-                                       auto file = wcmd.substr(2, wcmd.length()-1);\r
-                                       wcmd = L"PLAY 1-1 " + file + L" LOOP\r\n" \r
-                                                       L"PLAY 1-2 " + file + L" LOOP\r\n" \r
-                                                       L"PLAY 1-3 " + file + L" LOOP\r\n"\r
-                                                       L"PLAY 2-1 " + file + L" LOOP\r\n" \r
-                                                       L"PLAY 2-2 " + file + L" LOOP\r\n" \r
-                                                       L"PLAY 2-3 " + file + L" LOOP\r\n";\r
-                               }\r
-                               else if(wcmd.substr(0, 1) == L"7")\r
-                               {\r
-                                       wcmd = L"";\r
-                                       wcmd += L"CLEAR 1\r\n";\r
-                                       wcmd += L"MIXER 1 CLEAR\r\n";\r
-                                       wcmd += L"PLAY 1-0 GREEN\r\n";\r
-                                       wcmd += L"PLAY 1-1 BLUE\r\n";\r
-                                       wcmd += L"CG 1-2 ADD 1 ECS_TEST 1\r\n";\r
-                                       wcmd += L"MIXER 1-2 FILL 0 -1 1 2\r\n";\r
-                               }\r
-                               else if(wcmd.substr(0, 1) == L"8")\r
-                               {\r
-                                       wcmd = L"";\r
-                                       wcmd += L"MIXER 1-1 FILL 0.0 0.5 1.0 1.0 500 linear DEFER\r\n";\r
-                                       wcmd += L"MIXER 1-2 FILL 0.0 0.0 1.0 1.0 500 linear DEFER\r\n";\r
-                                       wcmd += L"MIXER 1 COMMIT\r\n";\r
-                               }\r
-                               else if(wcmd.substr(0, 1) == L"X")\r
-                               {\r
-                                       int num = 0;\r
-                                       std::wstring file;\r
-                                       try\r
-                                       {\r
-                                               num = boost::lexical_cast<int>(wcmd.substr(1, 2));\r
-                                               file = wcmd.substr(4, wcmd.length()-1);\r
-                                       }\r
-                                       catch(...)\r
-                                       {\r
-                                               num = boost::lexical_cast<int>(wcmd.substr(1, 1));\r
-                                               file = wcmd.substr(3, wcmd.length()-1);\r
-                                       }\r
-\r
-                                       int n = 0;\r
-                                       int num2 = num;\r
-                                       while(num2 > 0)\r
-                                       {\r
-                                               num2 >>= 1;\r
-                                               n++;\r
-                                       }\r
-\r
-                                       wcmd = L"MIXER 1 GRID " + boost::lexical_cast<std::wstring>(n);\r
-\r
-                                       for(int i = 1; i <= num; ++i)\r
-                                               wcmd += L"\r\nPLAY 1-" + boost::lexical_cast<std::wstring>(i) + L" " + file + L" LOOP";// + L" SLIDE 100 LOOP";\r
-                               }\r
-\r
-                               wcmd += L"\r\n";\r
-                               amcp.Parse(wcmd.c_str(), static_cast<int>(wcmd.length()), console_client);\r
-                       }       \r
-               }\r
-               Sleep(500);\r
-               CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";\r
+               \r
+               run();\r
+               \r
                system("pause");        \r
        }\r
        catch(boost::property_tree::file_parser_error&)\r
index 7b54f2d88690a560fc6061881cae4794b9b78125..cb6e9fd131ab327576299b3a5d8a5903840bcea6 100644 (file)
Binary files a/shell/shell.rc and b/shell/shell.rc differ