]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 9 Dec 2010 20:28:45 +0000 (20:28 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 9 Dec 2010 20:28:45 +0000 (20:28 +0000)
55 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/gl/shader_program.cpp [new file with mode: 0644]
common/gl/shader_program.h [new file with mode: 0644]
common/utility/string_convert.h
core/consumer/bluefish/bluefish_consumer.cpp
core/consumer/bluefish/bluefish_consumer.h
core/consumer/decklink/decklink_consumer.cpp
core/consumer/decklink/decklink_consumer.h
core/consumer/frame_consumer.h
core/consumer/frame_consumer_device.cpp
core/consumer/oal/oal_consumer.cpp
core/consumer/oal/oal_consumer.h
core/consumer/ogl/ogl_consumer.cpp
core/consumer/ogl/ogl_consumer.h
core/core.vcxproj
core/core.vcxproj.filters
core/processor/composite_frame.cpp
core/processor/composite_frame.h
core/processor/frame.cpp [deleted file]
core/processor/frame.h [deleted file]
core/processor/frame_processor_device.cpp
core/processor/frame_processor_device.h
core/processor/frame_renderer.cpp
core/processor/frame_renderer.h
core/processor/frame_shader.cpp
core/processor/frame_shader.h
core/processor/fwd.h [new file with mode: 0644]
core/processor/gpu_frame.h [new file with mode: 0644]
core/processor/read_frame.cpp [new file with mode: 0644]
core/processor/read_frame.h [new file with mode: 0644]
core/processor/transform_frame.cpp [new file with mode: 0644]
core/processor/transform_frame.h [new file with mode: 0644]
core/processor/write_frame.cpp [new file with mode: 0644]
core/processor/write_frame.h [new file with mode: 0644]
core/producer/color/color_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/video/video_transformer.cpp
core/producer/ffmpeg/video/video_transformer.h
core/producer/flash/FlashAxContainer.h
core/producer/flash/cg_producer.cpp
core/producer/flash/cg_producer.h
core/producer/flash/ct_producer.cpp
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/frame_producer.h
core/producer/frame_producer_device.cpp
core/producer/image/image_loader.cpp
core/producer/image/image_producer.cpp
core/producer/image/image_scroll_producer.cpp
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
core/producer/transition/transition_producer.h
shell/caspar.config

index b98536fe799dae013c74273632b86526f215f559..061afd3eadb8c8d1a1e9dae70f49669c3dd5267b 100644 (file)
@@ -98,6 +98,7 @@
     <ClInclude Include="exception\exceptions.h" />\r
     <ClInclude Include="exception\win32_exception.h" />\r
     <ClInclude Include="gl\frame_buffer_object.h" />\r
+    <ClInclude Include="gl\shader_program.h" />\r
     <ClInclude Include="gl\utility.h" />\r
     <ClInclude Include="gl\pixel_buffer_object.h" />\r
     <ClInclude Include="io\AsyncEventServer.h" />\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
+    <ClCompile Include="gl\shader_program.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
     <ClCompile Include="io\AsyncEventServer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
index c3cdb151b9e47abfe95de73dcc85782c1b5aaec1..ed7ee1db9e55afed553a359edc560f407bc5e627 100644 (file)
@@ -55,6 +55,9 @@
     <ClCompile Include="gl\pixel_buffer_object.cpp">\r
       <Filter>Source\gl</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="gl\shader_program.cpp">\r
+      <Filter>Source\gl</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="stdafx.h">\r
     <ClInclude Include="compiler\vs\disable_silly_warnings.h">\r
       <Filter>Source\compiler\vs</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="gl\shader_program.h">\r
+      <Filter>Source\gl</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/common/gl/shader_program.cpp b/common/gl/shader_program.cpp
new file mode 100644 (file)
index 0000000..44b5abf
--- /dev/null
@@ -0,0 +1,98 @@
+#include "../StdAfx.h"\r
+\r
+#include "shader_program.h"\r
+\r
+#include "../exception/exceptions.h"\r
+#include "utility.h"\r
+\r
+#include <Glee.h>\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+namespace caspar { namespace common { namespace gl {\r
+\r
+shader_program& shader_program::operator=(shader_program&& other) \r
+{\r
+       program_ = other.program_; \r
+       other.program_ = 0; \r
+       return *this;\r
+}\r
+\r
+shader_program::shader_program(const std::string& vertex_source_str, const std::string& fragment_source_str) : program_(0)\r
+{\r
+       GLint success;\r
+       \r
+       const char* vertex_source = vertex_source_str.c_str();\r
+                                               \r
+       auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
+                                       \r
+       GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
+       GL(glCompileShaderARB(vertex_shader));\r
+\r
+       GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
+       if (success == GL_FALSE)\r
+       {\r
+               char info[2048];\r
+               GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
+               GL(glDeleteObjectARB(vertex_shader));\r
+               std::stringstream str;\r
+               str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
+               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+       }\r
+                       \r
+       const char* fragment_source = fragment_source_str.c_str();\r
+                                               \r
+       auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
+                                       \r
+       GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
+       GL(glCompileShaderARB(fragmemt_shader));\r
+\r
+       GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
+       if (success == GL_FALSE)\r
+       {\r
+               char info[2048];\r
+               GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
+               GL(glDeleteObjectARB(fragmemt_shader));\r
+               std::stringstream str;\r
+               str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
+               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+       }\r
+                       \r
+       program_ = glCreateProgramObjectARB();\r
+                       \r
+       GL(glAttachObjectARB(program_, vertex_shader));\r
+       GL(glAttachObjectARB(program_, fragmemt_shader));\r
+\r
+       GL(glLinkProgramARB(program_));\r
+                       \r
+       GL(glDeleteObjectARB(vertex_shader));\r
+       GL(glDeleteObjectARB(fragmemt_shader));\r
+\r
+       GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
+       if (success == GL_FALSE)\r
+       {\r
+               char info[2048];\r
+               GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
+               GL(glDeleteObjectARB(program_));\r
+               std::stringstream str;\r
+               str << "Failed to link shader program:" << std::endl << info << std::endl;\r
+               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
+       }\r
+       GL(glUseProgramObjectARB(program_));\r
+       glUniform1i(glGetUniformLocation(program_, "plane[0]"), 0);\r
+       glUniform1i(glGetUniformLocation(program_, "plane[1]"), 1);\r
+       glUniform1i(glGetUniformLocation(program_, "plane[2]"), 2);\r
+       glUniform1i(glGetUniformLocation(program_, "plane[3]"), 3);\r
+}\r
+\r
+shader_program::~shader_program()\r
+{\r
+       glDeleteProgram(program_);\r
+}\r
+\r
+void shader_program::use()\r
+{      \r
+       GL(glUseProgramObjectARB(program_));            \r
+}\r
+\r
+}}}
\ No newline at end of file
diff --git a/common/gl/shader_program.h b/common/gl/shader_program.h
new file mode 100644 (file)
index 0000000..fc4c6f0
--- /dev/null
@@ -0,0 +1,29 @@
+\r
+#include <Glee.h>\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+#include <memory>\r
+\r
+namespace caspar { namespace common { namespace gl {\r
+               \r
+class shader_program : boost::noncopyable\r
+{\r
+public:\r
+       shader_program() : program_(0){}\r
+       shader_program(shader_program&& other) : program_(other.program_){}\r
+       shader_program& operator=(shader_program&& other);\r
+\r
+       shader_program(const std::string& vertex_source_str, const std::string& fragment_source_str);\r
+       ~shader_program();\r
+\r
+       void use();\r
+\r
+       GLuint program() { return program_; }\r
+       \r
+private:\r
+       GLuint program_;\r
+};\r
+typedef std::shared_ptr<shader_program> shader_program_ptr;\r
+\r
+}}}
\ No newline at end of file
index 7d4fc695acff934265a39d744fbb809deaf00b09..a31d40c6ae8864dd4b5a0353519a7b328ecad26e 100644 (file)
@@ -5,7 +5,7 @@
 #include <string>\r
 #include <sstream>\r
 #include <boost/lexical_cast.hpp>\r
-       \r
+          \r
 namespace caspar { namespace common {\r
 \r
 inline std::wstring widen(const std::string& str, const std::locale& locale = std::locale())\r
@@ -27,7 +27,7 @@ inline std::wstring widen(const std::wstring& str, const std::locale&)
 #pragma warning(push)\r
 #pragma warning(disable : 4244)\r
 #endif\r
-       \r
+          \r
 inline std::string narrow(const std::wstring& str, const std::locale& locale = std::locale())\r
 {\r
        std::stringstream sstr;\r
@@ -37,7 +37,7 @@ inline std::string narrow(const std::wstring& str, const std::locale& locale = s
                sstr << ctfacet.narrow(str[i], 0) ;\r
        return sstr.str() ;\r
 }\r
-       \r
+          \r
 inline std::string narrow(const std::string& str, const std::locale&)\r
 {\r
        return str ;\r
index b57afd737bb4e55fdd6549cb147a3d247b4911f6..ae7da5c88135a2695b1764887524f7ece2a6749d 100644 (file)
@@ -28,7 +28,7 @@
 #include "exception.h"\r
 #include "memory.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 \r
 #include <boost/thread.hpp>\r
 \r
@@ -137,9 +137,9 @@ struct consumer::implementation
 \r
                enable_video_output();\r
                                                \r
-               page_locked_buffer::reserve_working_size(MAX_HANC_BUFFER_SIZE * 3);             \r
-               for(int n = 0; n < 3; ++n)\r
-                       hanc_buffers_.push_back(std::make_shared<page_locked_buffer>(MAX_HANC_BUFFER_SIZE));\r
+               page_locked_buffer::reserve_working_size(MAX_HANC_BUFFER_SIZE * hanc_buffers_.size());          \r
+               for(size_t n = 0; n < hanc_buffers_.size(); ++n)\r
+                       hanc_buffers_[n] = std::make_shared<page_locked_buffer>(MAX_HANC_BUFFER_SIZE);\r
 \r
                frame_buffer_.set_capacity(1);\r
                thread_ = boost::thread([=]{run();});\r
@@ -149,7 +149,7 @@ struct consumer::implementation
 \r
        ~implementation()\r
        {\r
-               frame_buffer_.push(nullptr),\r
+               frame_buffer_.push(nullptr);\r
                thread_.join();\r
 \r
                disable_video_output();\r
@@ -172,38 +172,36 @@ struct consumer::implementation
                        CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");          \r
        }\r
 \r
-       void display(const frame_ptr& frame)\r
+       void display(const consumer_frame& frame)\r
        {\r
-               if(frame == nullptr)\r
-                       return;\r
-\r
                if(exception_ != nullptr)\r
                        std::rethrow_exception(exception_);\r
 \r
-               frame_buffer_.push(frame);\r
+               frame_buffer_.push(std::make_shared<consumer_frame>(frame));\r
        }\r
 \r
-       void do_display(consframe_ptr& frame)\r
+       void do_display(consumer_frame_ptr& frame)\r
        {\r
                try\r
                {\r
-                       auto hanc = hanc_buffers_[current_id_];         \r
-                       current_id_ = (current_id_+1) % hanc_buffers_.size();           \r
+                       auto hanc = hanc_buffers_.front();              \r
+                       std::rotate(hanc_buffers_.begin(), hanc_buffers_.begin() + 1, hanc_buffers_.end());\r
                        \r
                        static size_t audio_samples = 1920;\r
                        static size_t audio_nchannels = 2;\r
                        static std::vector<short> silence(audio_samples*audio_nchannels*2, 0);\r
 \r
-                       auto& frame_audio_data = frame->get_audio_data().empty() ? silence : frame->get_audio_data();\r
 \r
                        unsigned long fieldCount = 0;\r
                        sdk_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
                                \r
                        if(embed_audio_)\r
                        {               \r
-                               encode_hanc(reinterpret_cast<BLUE_UINT32*>(hanc->data()), frame_audio_data.data(), audio_samples, audio_nchannels);\r
+                               auto& frame_audio_data = frame->audio_data().empty() ? silence : frame->audio_data();\r
 \r
-                               sdk_->system_buffer_write_async(frame->data().begin(), \r
+                               encode_hanc(reinterpret_cast<BLUE_UINT32*>(hanc->data()), const_cast<short*>(frame_audio_data.data()), audio_samples, audio_nchannels);\r
+                                                               \r
+                               sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->data().begin()), \r
                                                                                                 frame->data().size(), \r
                                                                                                 nullptr, \r
                                                                                                 BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
@@ -213,14 +211,12 @@ struct consumer::implementation
                                                                                                 nullptr,                 \r
                                                                                                 BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_HANC));\r
 \r
-                               transferring_frame_ = frame;\r
-\r
                                if(BLUE_FAIL(sdk_->render_buffer_update(BlueBuffer_Image_HANC(current_id_))))\r
                                        CASPAR_LOG(trace) << TEXT("BLUEFISH: render_buffer_update failed");\r
                        }\r
                        else\r
                        {\r
-                               sdk_->system_buffer_write_async(frame->data().begin(),\r
+                               sdk_->system_buffer_write_async(const_cast<unsigned char*>(frame->data().begin()),\r
                                                                                                 frame->data().size(), \r
                                                                                                 nullptr,                 \r
                                                                                                 BlueImage_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
@@ -228,6 +224,8 @@ struct consumer::implementation
                                if(BLUE_FAIL(sdk_->render_buffer_update(BlueBuffer_Image(current_id_))))\r
                                        CASPAR_LOG(trace) << TEXT("BLUEFISH: render_buffer_update failed");\r
                        }\r
+\r
+                       transferring_frame_ = frame;\r
                }\r
                catch(...)\r
                {\r
@@ -268,9 +266,10 @@ struct consumer::implementation
                {\r
                        try\r
                        {\r
-                               frame_ptr frame;\r
+                               consumer_frame_ptr frame;\r
                                frame_buffer_.pop(frame);\r
-                               if(frame == nullptr)\r
+\r
+                               if(!frame)\r
                                        return;\r
 \r
                                do_display(frame);\r
@@ -289,7 +288,7 @@ struct consumer::implementation
        \r
        std::exception_ptr exception_;\r
        boost::thread thread_;\r
-       tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<consumer_frame_ptr> frame_buffer_;\r
        \r
        unsigned long   mem_fmt_;\r
        unsigned long   upd_fmt_;\r
@@ -297,15 +296,15 @@ struct consumer::implementation
        unsigned long   res_fmt_; \r
        unsigned long   engine_mode_;\r
 \r
-       frame_ptr transferring_frame_;\r
+       consumer_frame_ptr transferring_frame_;\r
 \r
-       std::vector<page_locked_buffer_ptr> hanc_buffers_;\r
+       std::array<page_locked_buffer_ptr, 3> hanc_buffers_;\r
        int current_id_;\r
        bool embed_audio_;\r
 };\r
 \r
 consumer::consumer(const video_format_desc& format_desc, unsigned int device_index, bool embed_audio) : impl_(new implementation(format_desc, device_index, embed_audio)){}    \r
-void consumer::display(const frame_ptr& frame){impl_->display(frame);}\r
+void consumer::display(const consumer_frame& frame){impl_->display(frame);}\r
 \r
 }}}\r
 \r
index 558791ff35186771cd2a31a64a814bc6b656ade8..15f3231f65ee908d42031d7751a31003c960dc75 100644 (file)
@@ -29,7 +29,7 @@ class consumer : public frame_consumer
 public:\r
        consumer(const video_format_desc& format_desc, unsigned int deviceIndex, bool embed_audio = false);\r
        \r
-       virtual void display(const frame_ptr&);         \r
+       virtual void display(const consumer_frame&);            \r
        virtual bool has_sync_clock() const {return true;}\r
 private:\r
        struct implementation;\r
index 6f8dd180b607de66bbcc996ce21752ea6a914765..8d3b916a177651f375a47b5c8a344a497aa9851f 100644 (file)
@@ -62,7 +62,6 @@ struct decklink_consumer::Implementation
        ~Implementation()\r
        {\r
                input_.push(nullptr);\r
-\r
                thread_.join();\r
 \r
                if(output_) \r
@@ -76,25 +75,22 @@ struct decklink_consumer::Implementation
                }\r
        }\r
        \r
-       void display(const frame_ptr& frame)\r
+       void display(const consumer_frame& frame)\r
        {\r
-               if(frame == nullptr)\r
-                       return;         \r
-\r
                if(exception_ != nullptr)\r
                        std::rethrow_exception(exception_);\r
 \r
-               input_.push(frame);\r
+               input_.push(std::make_shared<consumer_frame>(frame));\r
        }\r
                \r
-       void do_display(const frame_ptr& input_frame)\r
+       void do_display(const consumer_frame& input_frame)\r
        {\r
                try\r
                {\r
                        auto& output_frame = reserved_frames_[current_index_];\r
                        current_index_ = (++current_index_) % reserved_frames_.size();\r
                \r
-                       std::copy(input_frame->data().begin(), input_frame->data().end(), static_cast<char*>(output_frame.first));\r
+                       std::copy(input_frame.data().begin(), input_frame.data().end(), static_cast<char*>(output_frame.first));\r
                                \r
                        if(FAILED(output_->DisplayVideoFrameSync(output_frame.second)))\r
                                CASPAR_LOG(error) << L"DECKLINK: Failed to display frame.";\r
@@ -117,12 +113,13 @@ struct decklink_consumer::Implementation
                {\r
                        try\r
                        {       \r
-                               frame_ptr frame;\r
+                               consumer_frame_ptr frame;\r
                                input_.pop(frame);\r
-                               if(frame == nullptr)\r
+                               \r
+                               if(!frame)\r
                                        return;\r
 \r
-                               do_display(frame);\r
+                               do_display(*frame);\r
                        }\r
                        catch(...)\r
                        {\r
@@ -207,13 +204,13 @@ struct decklink_consumer::Implementation
 \r
        std::exception_ptr      exception_;\r
        boost::thread           thread_;\r
-       tbb::concurrent_bounded_queue<frame_ptr> input_;\r
+       tbb::concurrent_bounded_queue<consumer_frame_ptr> input_;\r
 };\r
 \r
 decklink_consumer::decklink_consumer(const video_format_desc& format_desc, bool internalKey) : pImpl_(new Implementation(format_desc, internalKey))\r
 {}\r
 \r
-void decklink_consumer::display(const frame_ptr& frame)\r
+void decklink_consumer::display(const consumer_frame& frame)\r
 {\r
        pImpl_->display(frame);\r
 }\r
index f19b1967c7ed6d036146488ea7077ccf16ff53c3..16b8249d0fc6b3f8e49863f2e5b50b82b85e0022 100644 (file)
@@ -30,7 +30,7 @@ class decklink_consumer : public frame_consumer
 public:\r
        explicit decklink_consumer(const video_format_desc& format_desc, bool internalKey = false);\r
        \r
-       virtual void display(const frame_ptr&);\r
+       virtual void display(const consumer_frame&);\r
        virtual bool has_sync_clock() const {return false;}\r
 private:\r
        struct Implementation;\r
index 47de96aaf502f32a70bab7e4477da8f33708dda9..786ff684b8b6912f4f1d2bd3666412cbad304bff 100644 (file)
@@ -20,7 +20,7 @@
 #pragma once\r
 \r
 #include "../format/video_format.h"\r
-#include "../processor/frame.h"\r
+#include "../processor/read_frame.h"\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
@@ -32,8 +32,8 @@ struct frame_consumer : boost::noncopyable
 {\r
        virtual ~frame_consumer() {}\r
 \r
-       virtual void prepare(const frame_ptr&){}\r
-       virtual void display(const frame_ptr&){}\r
+       virtual void prepare(const consumer_frame&){}\r
+       virtual void display(const consumer_frame&){}\r
        virtual bool has_sync_clock() const {return false;}\r
 };\r
 typedef std::shared_ptr<frame_consumer> frame_consumer_ptr;\r
index c1f551a60bae07e1d02011f6deaf8f359822754a..f588d83175d62c0a221c2389d8f70cd8b987b599 100644 (file)
@@ -7,7 +7,7 @@
 #include "frame_consumer_device.h"\r
 \r
 #include "../format/video_format.h"\r
-#include "../processor/frame.h"\r
+#include "../processor/write_frame.h"\r
 #include "../processor/frame_processor_device.h"\r
 \r
 #include <tbb/concurrent_queue.h>\r
@@ -62,7 +62,6 @@ public:
                //}\r
 \r
                needs_clock_ = !std::any_of(consumers.begin(), consumers.end(), std::mem_fn(&frame_consumer::has_sync_clock));\r
-               frame_buffer_.set_capacity(3);\r
                is_running_ = true;\r
                display_thread_ = boost::thread([=]{run();});\r
        }\r
@@ -83,16 +82,12 @@ public:
                {\r
                        if(needs_clock_)\r
                                clock.synchronize();\r
-                       \r
-                       frame_ptr frame;\r
-                       while((frame == nullptr || frame == frame::empty()) && is_running_)                     \r
-                               frame_processor_->receive(frame);\r
-                       \r
-                       display_frame(frame);                   \r
+                                               \r
+                       display_frame(frame_processor_->receive());                     \r
                }\r
        }\r
 \r
-       void display_frame(const frame_ptr& frame)\r
+       void display_frame(const consumer_frame& frame)\r
        {\r
                BOOST_FOREACH(const frame_consumer_ptr& consumer, consumers_)\r
                {\r
@@ -125,12 +120,11 @@ public:
                }\r
        }\r
 \r
-       std::deque<frame_ptr> prepared_frames_;\r
+       std::deque<consumer_frame> prepared_frames_;\r
                \r
        boost::thread display_thread_;\r
 \r
        tbb::atomic<bool> is_running_;\r
-       tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
 \r
        bool needs_clock_;\r
        std::vector<frame_consumer_ptr> consumers_;\r
index 61ff47923ec5d3f313e81e8cdc1405cf6b989fda..938edaf7ffb14bc1ee2824c19923c862f49db158 100644 (file)
@@ -22,7 +22,7 @@
 \r
 #include "oal_consumer.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../format/video_format.h"\r
 \r
 #include <SFML/Audio.hpp>\r
@@ -45,11 +45,11 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
                Stop();\r
        }\r
        \r
-       void push(const frame_ptr& frame)\r
+       void push(const consumer_frame& frame)\r
        {\r
                // NOTE: tbb::concurrent_queue does not have rvalue support. \r
                // Use shared_ptr to emulate move semantics\r
-               input_.push(std::make_shared<std::vector<short>>(std::move(frame->get_audio_data()))); \r
+               input_.push(frame.audio_data()); \r
                \r
                if(GetStatus() != Playing && input_.size() > 2)\r
                        Play();\r
@@ -65,7 +65,7 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
        {\r
                static std::vector<short> silence(1920*2, 0);\r
                \r
-               std::shared_ptr<std::vector<short>> audio_data;\r
+               std::vector<short> audio_data;\r
                \r
                if(!input_.try_pop(audio_data))\r
                {\r
@@ -80,14 +80,14 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
                        underrun_count_ = 0;\r
                }\r
                        \r
-               if(audio_data->empty())\r
+               if(audio_data.empty())\r
                {       \r
                        data.Samples = silence.data();\r
                        data.NbSamples = silence.size();\r
                }\r
                else\r
                {\r
-                       container_.push_back(std::move(*audio_data));\r
+                       container_.push_back(std::move(audio_data));\r
                        data.Samples = container_.back().data();\r
                        data.NbSamples = container_.back().size();\r
                }\r
@@ -96,9 +96,9 @@ struct consumer::implementation : public sf::SoundStream, boost::noncopyable
 \r
        long underrun_count_;\r
        boost::circular_buffer<std::vector<short>> container_;\r
-       tbb::concurrent_bounded_queue<std::shared_ptr<std::vector<short>>> input_;\r
+       tbb::concurrent_bounded_queue<std::vector<short>> input_;\r
 };\r
 \r
 consumer::consumer(const video_format_desc&) : impl_(new implementation()){}\r
-void consumer::prepare(const frame_ptr& frame){impl_->push(frame);}\r
+void consumer::prepare(const consumer_frame& frame){impl_->push(frame);}\r
 }}}\r
index 4ba0b8a7ed879620e8036986f073c56dc93e91c2..6bfd844860741bb52c5d274fa8b83d6b046e82c3 100644 (file)
@@ -28,7 +28,7 @@ class consumer : public frame_consumer
 public:        \r
        explicit consumer(const video_format_desc& format_desc);\r
        \r
-       virtual void prepare(const frame_ptr& frame);\r
+       virtual void prepare(const consumer_frame& frame);\r
        virtual bool has_sync_clock() const {return true;}\r
 private:\r
        struct implementation;\r
index e85d9389fad168ca85f52cfcab98f4a9144b4481..c8b090e479590c90968e3d9f7bf467e0461df3e1 100644 (file)
@@ -23,7 +23,7 @@
 #include "ogl_consumer.h"\r
 \r
 #include "../../format/video_format.h"\r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../../common/gl/utility.h"\r
 #include "../../../common/gl/pixel_buffer_object.h"\r
 \r
@@ -87,7 +87,7 @@ struct consumer::implementation : boost::noncopyable
        \r
        ~implementation()\r
        {\r
-               frame_buffer_.push(nullptr),\r
+               frame_buffer_.push(nullptr);\r
                thread_.join();\r
        }\r
 \r
@@ -156,13 +156,13 @@ struct consumer::implementation : boost::noncopyable
                return std::make_pair(width, height);\r
        }\r
 \r
-       void render(const frame_ptr& frame)\r
+       void render(const consumer_frame& frame)\r
        {               \r
                index_ = (index_ + 1) % 2;\r
                int next_index = (index_ + 1) % 2;\r
                                \r
                auto ptr = pbos_[index_].end_write();\r
-               std::copy_n(frame->data().begin(), frame->data().size(), reinterpret_cast<char*>(ptr));\r
+               std::copy_n(frame.data().begin(), frame.data().size(), reinterpret_cast<char*>(ptr));\r
 \r
                GL(glClear(GL_COLOR_BUFFER_BIT));       \r
                pbos_[next_index].bind_texture();                               \r
@@ -176,42 +176,40 @@ struct consumer::implementation : boost::noncopyable
                pbos_[next_index].begin_write();\r
        }\r
                        \r
-       void display(const frame_ptr& frame)\r
+       void display(const consumer_frame& frame)\r
        {\r
-               if(frame == nullptr)\r
-                       return;         \r
-\r
                if(exception_ != nullptr)\r
                        std::rethrow_exception(exception_);\r
 \r
-               frame_buffer_.push(frame);\r
+               frame_buffer_.push(std::make_shared<consumer_frame>(frame));\r
        }\r
 \r
        void run()\r
        {                       \r
                init();\r
                                \r
-               frame_ptr frame;\r
-               do\r
+               while(true)\r
                {\r
                        try\r
                        {               \r
+                               consumer_frame_ptr frame;\r
                                frame_buffer_.pop(frame);\r
-                               if(frame != nullptr)\r
-                               {\r
-                                       sf::Event e;\r
-                                       while(window_.GetEvent(e)){}\r
-                                       window_.SetActive();\r
-                                       render(frame);\r
-                                       window_.Display();\r
-                               }\r
+\r
+                               if(!frame)\r
+                                       return;\r
+\r
+                               sf::Event e;\r
+                               while(window_.GetEvent(e)){}\r
+                               window_.SetActive();\r
+                               render(*frame);\r
+                               window_.Display();\r
+                               \r
                        }\r
                        catch(...)\r
                        {\r
                                exception_ = std::current_exception();\r
                        }\r
                }               \r
-               while(frame != nullptr);\r
        }               \r
 \r
        float wratio_;\r
@@ -234,12 +232,12 @@ struct consumer::implementation : boost::noncopyable
 \r
        std::exception_ptr exception_;\r
        boost::thread thread_;\r
-       tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<consumer_frame_ptr> frame_buffer_;\r
 \r
        sf::Window window_;\r
 };\r
 \r
 consumer::consumer(const video_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed)\r
 : impl_(new implementation(format_desc, screen_index, stretch, windowed)){}\r
-void consumer::display(const frame_ptr& frame){impl_->display(frame);}\r
+void consumer::display(const consumer_frame& frame){impl_->display(frame);}\r
 }}}\r
index 2c16e7576ae56acda47aaa270d3c594f8610044c..6fbe02c80bd4d042c1bdaf555a01052d7d817ff3 100644 (file)
@@ -38,7 +38,7 @@ class consumer : public frame_consumer
 public:        \r
        explicit consumer(const video_format_desc& format_desc, unsigned int screen_index = 0, stretch stretch = stretch::fill, bool windowed = false);\r
        \r
-       virtual void display(const frame_ptr& frame);\r
+       virtual void display(const consumer_frame& frame);\r
        virtual bool has_sync_clock() const {return false;}\r
 private:\r
        struct implementation;\r
index 4bfc45a148aa8f494c560e7881a161e1ca1a22f6..8961b49e244a9b0ac6935df017b4e0393976e0c4 100644 (file)
     <ClInclude Include="format\pixel_format.h" />\r
     <ClInclude Include="format\video_format.h" />\r
     <ClInclude Include="processor\composite_frame.h" />\r
-    <ClInclude Include="processor\frame.h" />\r
     <ClInclude Include="processor\frame_processor_device.h" />\r
     <ClInclude Include="processor\frame_renderer.h" />\r
     <ClInclude Include="processor\frame_shader.h" />\r
+    <ClInclude Include="processor\fwd.h" />\r
+    <ClInclude Include="processor\gpu_frame.h" />\r
+    <ClInclude Include="processor\read_frame.h" />\r
+    <ClInclude Include="processor\transform_frame.h" />\r
+    <ClInclude Include="processor\write_frame.h" />\r
     <ClInclude Include="producer\color\color_producer.h" />\r
     <ClInclude Include="producer\ffmpeg\audio\audio_decoder.h" />\r
     <ClInclude Include="producer\ffmpeg\ffmpeg_producer.h" />\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
-    <ClCompile Include="processor\frame.cpp">\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
-    </ClCompile>\r
     <ClCompile Include="processor\frame_processor_device.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
+    <ClCompile Include="processor\read_frame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="processor\transform_frame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
+    <ClCompile Include="processor\write_frame.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
     <ClCompile Include="producer\color\color_producer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
index 6457345a3c73dab533961c017f39ba97203a1d30..5e4b339a87e86408cfa1a2d29534bd6f8974989c 100644 (file)
@@ -79,6 +79,9 @@
     <Filter Include="Source\channel\format">\r
       <UniqueIdentifier>{f19ced4f-4ad2-4c0a-b51f-50e89909d669}</UniqueIdentifier>\r
     </Filter>\r
+    <Filter Include="Source\channel\processor\frame">\r
+      <UniqueIdentifier>{deed18de-67bf-4bb9-9f5e-565af7ab64eb}</UniqueIdentifier>\r
+    </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="StdAfx.h">\r
     <ClInclude Include="processor\frame_processor_device.h">\r
       <Filter>Source\channel\processor</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="processor\frame.h">\r
-      <Filter>Source\channel\processor</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="processor\composite_frame.h">\r
-      <Filter>Source\channel\processor</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="processor\frame_shader.h">\r
       <Filter>Source\channel\processor\renderer</Filter>\r
     </ClInclude>\r
     <ClInclude Include="consumer\decklink\util.h">\r
       <Filter>Source\channel\consumer\decklink</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="processor\write_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="processor\read_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="processor\composite_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="processor\transform_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="processor\fwd.h">\r
+      <Filter>Source\channel\processor</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="processor\gpu_frame.h">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="StdAfx.cpp">\r
     <ClCompile Include="processor\frame_processor_device.cpp">\r
       <Filter>Source\channel\processor</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="processor\frame.cpp">\r
-      <Filter>Source\channel\processor</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="processor\composite_frame.cpp">\r
-      <Filter>Source\channel\processor</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="processor\frame_renderer.cpp">\r
       <Filter>Source\channel\processor\renderer</Filter>\r
     </ClCompile>\r
     <ClCompile Include="consumer\decklink\decklink_consumer.cpp">\r
       <Filter>Source\channel\consumer\decklink</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="processor\read_frame.cpp">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="processor\write_frame.cpp">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="processor\composite_frame.cpp">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="processor\transform_frame.cpp">\r
+      <Filter>Source\channel\processor\frame</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Midl Include="consumer\decklink\DeckLinkAPI_v7_3.idl">\r
index 79d06bccbe729bd3fff5c066f3a3477dbb5aaf8e..9800f92948809844b1b05a19c72bcab869fea12d 100644 (file)
@@ -1,6 +1,7 @@
 #include "../StdAfx.h"\r
 \r
 #include "composite_frame.h"\r
+#include "transform_frame.h"\r
 #include "../../common/gl/utility.h"\r
 \r
 #include <boost/range/algorithm.hpp>\r
@@ -15,100 +16,89 @@ namespace caspar { namespace core {
        \r
 struct composite_frame::implementation : boost::noncopyable\r
 {      \r
-       implementation(composite_frame* self, const std::vector<frame_ptr>& frames) : self_(self)\r
-       {\r
-               boost::range::transform(frames, std::back_inserter(frames_), std::static_pointer_cast<internal_frame, frame>);\r
-               prepare();\r
-       }\r
-\r
-       implementation(composite_frame* self, const frame_ptr& frame1, const frame_ptr& frame2) : self_(self)\r
-       {\r
-               frames_.push_back(std::static_pointer_cast<internal_frame>(frame1));\r
-               frames_.push_back(std::static_pointer_cast<internal_frame>(frame2));\r
-               prepare();\r
-       }\r
-\r
-       void prepare()\r
+       implementation(const std::vector<gpu_frame_ptr>& frames) : frames_(frames)\r
        {\r
                boost::range::remove_erase(frames_, nullptr);\r
-               boost::range::remove_erase(frames_, frame::empty());\r
-               boost::for_each(frames_, [&](const frame_ptr& frame)\r
-               {\r
-                       if(self_->get_audio_data().empty())\r
-                               self_->get_audio_data() = std::move(frame->get_audio_data());\r
-                       else\r
-                       {\r
-                               tbb::parallel_for\r
-                               (\r
-                                       tbb::blocked_range<size_t>(0, frame->get_audio_data().size()),\r
-                                       [&](const tbb::blocked_range<size_t>& r)\r
-                                       {\r
-                                               for(size_t n = r.begin(); n < r.end(); ++n)\r
-                                                       self_->get_audio_data()[n] = static_cast<short>(static_cast<int>(self_->get_audio_data()[n]) + static_cast<int>(frame->get_audio_data()[n]) & 0xFFFF);  \r
-                                       }\r
-                               );\r
-                       }\r
-               });\r
        }\r
-\r
+       \r
        void begin_write()\r
        {\r
-               boost::range::for_each(frames_, std::mem_fn(&internal_frame::begin_write));             \r
+               boost::range::for_each(frames_, std::mem_fn(&gpu_frame::begin_write));          \r
        }\r
 \r
        void end_write()\r
        {\r
-               boost::range::for_each(frames_, std::mem_fn(&internal_frame::end_write));                               \r
+               boost::range::for_each(frames_, std::mem_fn(&gpu_frame::end_write));                            \r
        }\r
        \r
-       void begin_read()\r
-       {       \r
-               boost::range::for_each(frames_, std::mem_fn(&internal_frame::begin_read));              \r
-       }\r
-\r
-       void end_read()\r
+       void draw(frame_shader& shader)\r
        {\r
-               boost::range::for_each(frames_, std::mem_fn(&internal_frame::end_read));        \r
+               for(size_t n = 0; n < frames_.size(); ++n)\r
+                       frames_[n]->draw(shader);\r
        }\r
-\r
-       void draw(frame_shader& shader)\r
+                       \r
+       std::vector<short>& audio_data()\r
        {\r
-               glPushMatrix();\r
-               glTranslated(self_->get_render_transform().pos.get<0>()*2.0, self_->get_render_transform().pos.get<1>()*2.0, 0.0);\r
-               boost::range::for_each(frames_, std::bind(&internal_frame::draw, std::placeholders::_1, shader));\r
-               glPopMatrix();\r
+               if(!audio_data_.empty() || frames_.empty())\r
+                       return audio_data_;\r
+                       \r
+               audio_data_.resize(1920*2, 0);\r
+                               \r
+               for(size_t n = 0; n < frames_.size(); ++n)\r
+               {\r
+                       auto frame = frames_[n];\r
+                       tbb::parallel_for\r
+                       (\r
+                               tbb::blocked_range<size_t>(0, frame->audio_data().size()),\r
+                               [&](const tbb::blocked_range<size_t>& r)\r
+                               {\r
+                                       for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
+                                               audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + static_cast<int>(frame->audio_data()[n])) & 0xFFFF);                                            \r
+                               }\r
+                       );\r
+               }\r
+\r
+               return audio_data_;\r
        }\r
        \r
-       composite_frame* self_;\r
-       std::vector<internal_frame_ptr> frames_;\r
+       std::vector<gpu_frame_ptr> frames_;\r
+       std::vector<short> audio_data_;\r
 };\r
 \r
 #if defined(_MSC_VER)\r
 #pragma warning (disable : 4355) // 'this' : used in base member initializer list\r
 #endif\r
 \r
-composite_frame::composite_frame(const std::vector<frame_ptr>& frames) : internal_frame(pixel_format_desc()), impl_(new implementation(this, frames)){}\r
-composite_frame::composite_frame(const frame_ptr& frame1, const frame_ptr& frame2) : internal_frame(pixel_format_desc()), impl_(new implementation(this, frame1, frame2)){}\r
+composite_frame::composite_frame(const std::vector<gpu_frame_ptr>& frames) : impl_(new implementation(frames)){}\r
+composite_frame::composite_frame(const gpu_frame_ptr& frame1, const gpu_frame_ptr& frame2)\r
+{\r
+       std::vector<gpu_frame_ptr> frames;\r
+       frames.push_back(frame1);\r
+       frames.push_back(frame2);\r
+       impl_.reset(new implementation(frames));\r
+}\r
+\r
 void composite_frame::begin_write(){impl_->begin_write();}\r
 void composite_frame::end_write(){impl_->end_write();} \r
-void composite_frame::begin_read(){impl_->begin_read();}\r
-void composite_frame::end_read(){impl_->end_read();}\r
 void composite_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
+std::vector<short>& composite_frame::audio_data(){return impl_->audio_data();}\r
+const std::vector<short>& composite_frame::audio_data() const{return impl_->audio_data();}\r
 \r
-frame_ptr composite_frame::interlace(const frame_ptr& frame1, const frame_ptr& frame2, video_mode::type mode)\r
+composite_frame_ptr composite_frame::interlace(const gpu_frame_ptr& frame1, const gpu_frame_ptr& frame2, video_mode::type mode)\r
 {                      \r
-       auto result = std::make_shared<composite_frame>(frame1, frame2);\r
+       auto my_frame1 = std::make_shared<transform_frame>(frame1);\r
+       auto my_frame2 = std::make_shared<transform_frame>(frame2);\r
        if(mode == video_mode::upper)\r
        {\r
-               frame1->get_render_transform().mode = video_mode::upper;\r
-               frame2->get_render_transform().mode = video_mode::lower;\r
+               my_frame1->video_mode(video_mode::upper);\r
+               my_frame2->video_mode(video_mode::lower);\r
        }\r
        else\r
        {\r
-               frame1->get_render_transform().mode = video_mode::lower;\r
-               frame2->get_render_transform().mode = video_mode::upper;\r
+               my_frame1->video_mode(video_mode::lower);\r
+               my_frame2->video_mode(video_mode::upper);\r
        }\r
-       return result;\r
+       return std::make_shared<composite_frame>(my_frame1, my_frame2);\r
 }\r
 \r
 }}
\ No newline at end of file
index ff3c79837f96fe72404564b87d0c952218f9980d..6aa924472cde23d147d7c5b0b2398c05a18c4287 100644 (file)
@@ -1,28 +1,32 @@
 #pragma once\r
 \r
-#include "frame.h"\r
+#include "gpu_frame.h"\r
+\r
+#include "../format/video_format.h"\r
 \r
 #include <memory>\r
 #include <algorithm>\r
 \r
 namespace caspar { namespace core {\r
        \r
-class composite_frame : public internal_frame\r
+class composite_frame : public gpu_frame\r
 {\r
 public:\r
-       composite_frame(const std::vector<frame_ptr>& container);\r
-       composite_frame(const frame_ptr& frame1, const frame_ptr& frame2);\r
+       composite_frame(const std::vector<gpu_frame_ptr>& frames);\r
+       composite_frame(const gpu_frame_ptr& frame1, const gpu_frame_ptr& frame2);\r
 \r
-       static frame_ptr interlace(const frame_ptr& frame1,     const frame_ptr& frame2, video_mode::type mode);\r
+       static std::shared_ptr<composite_frame> interlace(const gpu_frame_ptr& frame1, const gpu_frame_ptr& frame2, video_mode::type mode);\r
        \r
-private:\r
+       virtual const std::vector<short>& audio_data() const;\r
+\r
+protected:     \r
+       virtual std::vector<short>& audio_data();\r
 \r
        virtual void begin_write();\r
        virtual void end_write();\r
-       virtual void begin_read();\r
-       virtual void end_read();\r
        virtual void draw(frame_shader& shader);\r
 \r
+private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
diff --git a/core/processor/frame.cpp b/core/processor/frame.cpp
deleted file mode 100644 (file)
index b6de157..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "../StdAfx.h"\r
-\r
-#include "frame.h"\r
-#include "../format/pixel_format.h"\r
-#include "../../common/gl/utility.h"\r
-#include "../../common/gl/pixel_buffer_object.h"\r
-\r
-#include <boost/range/algorithm.hpp>\r
-\r
-namespace caspar { namespace core {\r
-       \r
-GLubyte progressive_pattern[] = {\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
-       0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
-       \r
-GLubyte upper_pattern[] = {\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
-               \r
-GLubyte lower_pattern[] = {\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
-                                                                                                                                                                                                                                                                                                               \r
-struct internal_frame::implementation : boost::noncopyable\r
-{\r
-       implementation(const pixel_format_desc& desc) : desc_(desc)\r
-       {                       \r
-               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
-\r
-               for(size_t n = 0; n < desc_.planes.size(); ++n)\r
-               {\r
-                       if(desc_.planes[n].size == 0)\r
-                               break;\r
-\r
-                       GLuint format = [&]() -> GLuint\r
-                       {\r
-                               switch(desc_.planes[n].channels)\r
-                               {\r
-                               case 1: return GL_LUMINANCE;\r
-                               case 2: return GL_LUMINANCE_ALPHA;\r
-                               case 3: return GL_BGR;\r
-                               case 4: return GL_BGRA;\r
-                               default: BOOST_THROW_EXCEPTION(out_of_range() << msg_info("1-4 channels are supported") << arg_name_info("desc.planes.channels")); \r
-                               }\r
-                       }();\r
-\r
-                       pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(desc_.planes[n].width, desc_.planes[n].height, format));\r
-                       pbo_.back()->is_smooth(true);\r
-               }\r
-               end_write();\r
-       }\r
-       \r
-       void begin_write()\r
-       {\r
-               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
-               boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_write));\r
-       }\r
-\r
-       void end_write()\r
-       {\r
-               boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_write));\r
-       }\r
-       \r
-       void begin_read()\r
-       {       \r
-               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
-               boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_read));\r
-       }\r
-\r
-       void end_read()\r
-       {\r
-               boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_read));\r
-       }\r
-\r
-       void draw(frame_shader& shader)\r
-       {\r
-               shader.use(desc_);\r
-               glPushMatrix();\r
-               glTranslated(transform_.pos.get<0>()*2.0, transform_.pos.get<1>()*2.0, 0.0);\r
-               glColor4d(1.0, 1.0, 1.0, transform_.alpha);\r
-\r
-               if(transform_.mode == video_mode::progressive)\r
-                       glPolygonStipple(progressive_pattern);\r
-               else if(transform_.mode == video_mode::upper)\r
-                       glPolygonStipple(upper_pattern);\r
-               else if(transform_.mode == video_mode::lower)\r
-                       glPolygonStipple(lower_pattern);\r
-\r
-               for(size_t n = 0; n < pbo_.size(); ++n)\r
-               {\r
-                       glActiveTexture(GL_TEXTURE0+n);\r
-                       pbo_[n]->bind_texture();\r
-               }\r
-               glBegin(GL_QUADS);\r
-                       glTexCoord2d(transform_.uv.get<0>(), transform_.uv.get<3>()); glVertex2d(-1.0, -1.0);\r
-                       glTexCoord2d(transform_.uv.get<2>(), transform_.uv.get<3>()); glVertex2d( 1.0, -1.0);\r
-                       glTexCoord2d(transform_.uv.get<2>(), transform_.uv.get<1>()); glVertex2d( 1.0,  1.0);\r
-                       glTexCoord2d(transform_.uv.get<0>(), transform_.uv.get<1>()); glVertex2d(-1.0,  1.0);\r
-               glEnd();\r
-               glPopMatrix();\r
-       }\r
-\r
-       unsigned char* data(size_t index)\r
-       {\r
-               return static_cast<unsigned char*>(pixel_data_[index]);\r
-       }\r
-\r
-       void reset()\r
-       {\r
-               audio_data_.clear();\r
-               transform_ = render_transform();\r
-               end_write();\r
-       }\r
-\r
-       std::vector<common::gl::pixel_buffer_object_ptr> pbo_;\r
-       std::array<void*, 4> pixel_data_;       \r
-       std::vector<short> audio_data_;\r
-       \r
-       const pixel_format_desc desc_;\r
-       internal_frame::render_transform transform_;\r
-};\r
-       \r
-std::shared_ptr<frame>& frame::empty()\r
-{\r
-       static auto empty_frame = std::shared_ptr<frame>(new internal_frame(pixel_format_desc()));\r
-       return empty_frame;\r
-}\r
-\r
-internal_frame::internal_frame(const pixel_format_desc& desc) : impl_(new implementation(desc)){}\r
-void internal_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
-void internal_frame::begin_write(){impl_->begin_write();}\r
-void internal_frame::end_write(){impl_->end_write();}  \r
-void internal_frame::begin_read(){impl_->begin_read();}\r
-void internal_frame::end_read(){impl_->end_read();}\r
-boost::iterator_range<unsigned char*> internal_frame::data(size_t index)\r
-{\r
-       auto ptr = static_cast<unsigned char*>(impl_->pixel_data_[index]);\r
-       return boost::iterator_range<unsigned char*>(ptr, ptr+impl_->desc_.planes[index].size);\r
-}\r
-\r
-std::vector<short>& internal_frame::get_audio_data() { return impl_->audio_data_; }\r
-void internal_frame::reset(){impl_->reset();}\r
-internal_frame::render_transform& internal_frame::get_render_transform() { return impl_->transform_;}\r
-}}
\ No newline at end of file
diff --git a/core/processor/frame.h b/core/processor/frame.h
deleted file mode 100644 (file)
index 5284e42..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once\r
-\r
-#include "frame_shader.h"\r
-\r
-#include "../format/video_format.h"\r
-#include "../format/pixel_format.h"\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-#include <boost/noncopyable.hpp>\r
-#include <boost/tuple/tuple.hpp>\r
-#include <boost/range/iterator_range.hpp>\r
-\r
-#include <vector>\r
-\r
-namespace caspar { namespace core {\r
-       \r
-class frame : boost::noncopyable\r
-{\r
-public:\r
-       \r
-       struct render_transform\r
-       {\r
-               render_transform() : alpha(1.0), pos(boost::make_tuple(0.0, 0.0)), uv(boost::make_tuple(0.0, 1.0, 1.0, 0.0)), mode(video_mode::progressive){}\r
-               double alpha;\r
-               boost::tuple<double, double> pos;\r
-               boost::tuple<double, double, double, double> uv;\r
-               video_mode::type mode; \r
-       };\r
-\r
-       virtual ~frame(){}\r
-                       \r
-       virtual boost::iterator_range<unsigned char*> data(size_t index = 0) = 0;\r
-                               \r
-       virtual std::vector<short>& get_audio_data() = 0;\r
-       const std::vector<short>& get_audio_data() const { const_cast<frame*>(this)->get_audio_data();}\r
-       \r
-       virtual render_transform& get_render_transform() = 0;\r
-       const render_transform& get_render_transform() const  { const_cast<frame*>(this)->get_render_transform();}\r
-       \r
-       static std::shared_ptr<frame>& empty();\r
-};\r
-typedef std::shared_ptr<frame> frame_ptr;\r
-       \r
-class internal_frame : public frame\r
-{\r
-public:\r
-       explicit internal_frame(const pixel_format_desc& desc);\r
-       \r
-       virtual boost::iterator_range<unsigned char*> data(size_t index = 0);\r
-\r
-       virtual std::vector<short>& get_audio_data();\r
-       virtual core::frame::render_transform& get_render_transform();\r
-\r
-       virtual void reset();\r
-               \r
-       virtual void begin_write();\r
-       virtual void end_write();\r
-       virtual void begin_read();\r
-       virtual void end_read();\r
-\r
-       virtual void draw(frame_shader& shader);\r
-\r
-private:\r
-       struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<internal_frame> internal_frame_ptr;\r
-\r
-\r
-}}
\ No newline at end of file
index 0878d36dfa49a2480b2c8413fe8da0e054e8e006..f21e8f9e5ad65bbded509f43c135913ea4c2e0da 100644 (file)
@@ -3,7 +3,8 @@
 #include "frame_processor_device.h"\r
 \r
 #include "frame_renderer.h"\r
-#include "frame.h"\r
+#include "write_frame.h"\r
+#include "read_frame.h"\r
 #include "composite_frame.h"\r
 \r
 #include "../format/video_format.h"\r
@@ -28,7 +29,7 @@ namespace caspar { namespace core {
        \r
 struct frame_processor_device::implementation : boost::noncopyable\r
 {      \r
-       implementation(frame_processor_device* self, const video_format_desc& format_desc) : fmt_(format_desc), underrun_count_(0)\r
+       implementation(const video_format_desc& format_desc) : fmt_(format_desc), underrun_count_(0)\r
        {               \r
                output_.set_capacity(3);\r
                executor_.start();\r
@@ -37,7 +38,7 @@ struct frame_processor_device::implementation : boost::noncopyable
                        ogl_context_.reset(new sf::Context());\r
                        ogl_context_->SetActive(true);\r
 \r
-                       renderer_.reset(new frame_renderer(*self, format_desc));\r
+                       renderer_.reset(new frame_renderer(format_desc));\r
                });\r
        }\r
 \r
@@ -46,20 +47,15 @@ struct frame_processor_device::implementation : boost::noncopyable
                executor_.stop(); // Wait for executor before destroying anything.\r
        }\r
        \r
-       void clear()\r
-       {\r
-               output_.clear();\r
-       }\r
-\r
-       frame_ptr create_frame(const pixel_format_desc& desc)\r
+       write_frame_ptr create_frame(const pixel_format_desc& desc)\r
        {\r
                auto pool = &frame_pools_[desc];\r
                \r
-               internal_frame_ptr my_frame;\r
+               write_frame_ptr my_frame;\r
                if(!pool->try_pop(my_frame))            \r
-                       my_frame = executor_.invoke([&]{return std::shared_ptr<internal_frame>(new internal_frame(desc));});            \r
+                       my_frame = executor_.invoke([&]{return std::shared_ptr<write_frame>(new write_frame(desc));});          \r
                \r
-               return internal_frame_ptr(my_frame.get(), [=](frame*)\r
+               return write_frame_ptr(my_frame.get(), [=](write_frame*)\r
                {\r
                        executor_.begin_invoke([=]\r
                        {\r
@@ -69,18 +65,18 @@ struct frame_processor_device::implementation : boost::noncopyable
                });\r
        }\r
                \r
-       void send(const frame_ptr& input_frame)\r
+       void send(const gpu_frame_ptr& input_frame)\r
        {                       \r
                if(input_frame == nullptr)\r
                        return;\r
                                \r
-               auto future = executor_.begin_invoke([=]{return renderer_->render(std::static_pointer_cast<internal_frame>(input_frame));});    \r
+               auto future = executor_.begin_invoke([=]{return renderer_->render(input_frame);});      \r
                output_.push(std::move(future)); // Blocks\r
        }\r
 \r
-       void receive(frame_ptr& output_frame)\r
+       consumer_frame receive()\r
        {\r
-               boost::shared_future<internal_frame_ptr> future;\r
+               boost::shared_future<consumer_frame> future;\r
 \r
                if(!output_.try_pop(future))\r
                {\r
@@ -95,33 +91,28 @@ struct frame_processor_device::implementation : boost::noncopyable
                        underrun_count_ = 0;\r
                }\r
 \r
-               output_frame = future.get();\r
+               return future.get();\r
        }\r
                                        \r
        std::unique_ptr<sf::Context> ogl_context_;\r
+       std::unique_ptr<frame_renderer> renderer_;\r
        \r
        common::executor executor_;     \r
-\r
-       std::unique_ptr<frame_renderer> renderer_;\r
                                \r
-       tbb::concurrent_bounded_queue<boost::shared_future<internal_frame_ptr>> output_;        \r
-       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<internal_frame_ptr>, std::hash<pixel_format_desc>> frame_pools_;\r
+       tbb::concurrent_bounded_queue<boost::shared_future<consumer_frame>> output_;    \r
+       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<write_frame_ptr>, std::hash<pixel_format_desc>> frame_pools_;\r
        \r
        video_format_desc fmt_;\r
        long underrun_count_;\r
 };\r
        \r
-#if defined(_MSC_VER)\r
-#pragma warning (disable : 4355) // 'this' : used in base member initializer list\r
-#endif\r
+frame_processor_device::frame_processor_device(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+void frame_processor_device::send(const gpu_frame_ptr& frame){impl_->send(frame);}\r
+consumer_frame frame_processor_device::receive(){return impl_->receive();}\r
+const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_; }\r
 \r
-frame_processor_device::frame_processor_device(const video_format_desc& format_desc) : impl_(new implementation(this, format_desc)){}\r
-frame_ptr frame_processor_device::create_frame(const  pixel_format_desc& desc){return impl_->create_frame(desc);}\r
-void frame_processor_device::send(const frame_ptr& frame){impl_->send(frame);}\r
-void frame_processor_device::receive(frame_ptr& frame){impl_->receive(frame);}\r
-const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_;}\r
-\r
-frame_ptr frame_processor_device::create_frame(size_t width, size_t height)\r
+write_frame_ptr frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }               \r
+write_frame_ptr frame_processor_device::create_frame(size_t width, size_t height)\r
 {\r
        // Create bgra frame\r
        pixel_format_desc desc;\r
@@ -130,7 +121,7 @@ frame_ptr frame_processor_device::create_frame(size_t width, size_t height)
        return create_frame(desc);\r
 }\r
                        \r
-frame_ptr frame_processor_device::create_frame()\r
+write_frame_ptr frame_processor_device::create_frame()\r
 {\r
        // Create bgra frame with output resolution\r
        pixel_format_desc desc;\r
@@ -138,5 +129,5 @@ frame_ptr frame_processor_device::create_frame()
        desc.planes.push_back(pixel_format_desc::plane(get_video_format_desc().width, get_video_format_desc().height, 4));\r
        return create_frame(desc);\r
 }\r
-void frame_processor_device::clear(){impl_->clear();}\r
+\r
 }}
\ No newline at end of file
index 7be445855543887dd8ea90e504b104ae4c0a847b..6383ca94e27d81c943ddda8abe290d02157d9af3 100644 (file)
@@ -22,8 +22,9 @@
 #include <memory>\r
 #include <vector>\r
 \r
+#include "fwd.h"\r
+\r
 #include "../format/video_format.h"\r
-#include "../processor/frame.h"\r
 #include "../consumer/frame_consumer_device.h"\r
 \r
 namespace caspar { namespace core {\r
@@ -33,13 +34,12 @@ class frame_processor_device : boost::noncopyable
 public:\r
        frame_processor_device(const video_format_desc& format_desc);\r
                \r
-       void send(const frame_ptr& frame);\r
-       void receive(frame_ptr& frame);\r
-       void clear();\r
+       void send(const gpu_frame_ptr& frame);\r
+       consumer_frame receive();\r
        \r
-       frame_ptr create_frame(const pixel_format_desc& desc);          \r
-       frame_ptr create_frame(size_t width, size_t height);                    \r
-       frame_ptr create_frame();\r
+       write_frame_ptr create_frame(const pixel_format_desc& desc);            \r
+       write_frame_ptr create_frame(size_t width, size_t height);                      \r
+       write_frame_ptr create_frame();\r
        \r
        const video_format_desc& get_video_format_desc() const;\r
 private:\r
index 4f97c4ffb3ea4af3c3dc17117be6d2ec1f880d98..142feece5d33eda4f0188ce3692f925a2cf2f60b 100644 (file)
@@ -2,10 +2,11 @@
 \r
 #include "frame_renderer.h"\r
 \r
-#include "../processor/frame.h"\r
+#include "frame_shader.h"\r
+#include "write_frame.h"\r
+#include "read_frame.h"\r
 \r
 #include "../format/video_format.h"\r
-#include "../processor/frame_processor_device.h"\r
 \r
 #include "../../common/exception/exceptions.h"\r
 #include "../../common/gl/utility.h"\r
@@ -24,12 +25,9 @@ namespace caspar { namespace core {
        \r
 struct frame_renderer::implementation : boost::noncopyable\r
 {      \r
-       implementation(frame_processor_device& frame_processor, const video_format_desc& format_desc) \r
-               : frame_processor_(frame_processor), index_(0), shader_(format_desc), fbo_(format_desc.width, format_desc.height)\r
+       implementation(const video_format_desc& format_desc) : shader_(format_desc), format_desc_(format_desc),\r
+               reading_(new read_frame(0, 0)), writing_(new write_frame(pixel_format_desc())), drawing_(new write_frame(pixel_format_desc())), fbo_(format_desc.width, format_desc.height)\r
        {       \r
-               auto empty = std::make_shared<internal_frame>(pixel_format_desc());\r
-               output_frame_ = empty;\r
-               std::fill(writing_.begin(), writing_.end(), empty);\r
                GL(glEnable(GL_POLYGON_STIPPLE));\r
                GL(glEnable(GL_TEXTURE_2D));\r
                GL(glEnable(GL_BLEND));\r
@@ -38,60 +36,71 @@ struct frame_renderer::implementation : boost::noncopyable
                GL(glViewport(0, 0, format_desc.width, format_desc.height));\r
        }\r
                                \r
-       internal_frame_ptr render(const internal_frame_ptr& frame)\r
+       consumer_frame render(const gpu_frame_ptr& frame)\r
        {\r
                if(frame == nullptr)\r
                        return nullptr;\r
 \r
                try\r
                {\r
-                       index_ = (index_ + 1) % 2;\r
-                       int next_index = (index_ + 1) % 2;\r
+                       drawing_ = writing_;\r
+                       writing_ = frame;\r
                        \r
-                       // 1. Write from page-locked system memory to video memory.\r
-                       frame->begin_write();\r
-                       writing_[index_] = frame;               \r
+                       // Write from page-locked system memory to video memory.\r
+                       writing_->begin_write();\r
                                \r
-                       // 3. Map video memory to page-locked system memory.\r
-                       output_frame_->end_read();\r
+                       //  Map video memory to page-locked system memory.\r
+                       reading_->end_read(); // Note: This frame has already been sent, it is assumed that there is external buffering of atleast 2 frames.\r
                        \r
                        // Clear framebuffer.\r
                        GL(glClear(GL_COLOR_BUFFER_BIT));       \r
 \r
-                       // 2. Draw to framebuffer\r
-                       writing_[next_index]->draw(shader_);\r
+                       // Draw to framebuffer\r
+                       drawing_->draw(shader_);\r
                                \r
                        // Create an output frame\r
-                       output_frame_ = std::static_pointer_cast<internal_frame>(frame_processor_.create_frame());\r
+                       reading_ = create_output_frame();\r
                        \r
                        // Read from framebuffer into page-locked memory.\r
-                       output_frame_->begin_read();\r
-                       output_frame_->get_audio_data() = std::move(writing_[next_index]->get_audio_data());\r
+                       reading_->begin_read();\r
+                       reading_->audio_data() = std::move(drawing_->audio_data());\r
                        \r
                        // Return frames to pool.\r
-                       //writing_[next_index]->end_write(); // Is done in frame->reset();\r
-                       writing_[next_index] = nullptr;\r
+                       // Note: end_write is done in writing_fram::reset();\r
+                       drawing_ = nullptr;\r
                }\r
                catch(...)\r
                {\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
 \r
-               return output_frame_;\r
+               return reading_;\r
        }\r
 \r
-       size_t index_;\r
+       read_frame_ptr create_output_frame()\r
+       {\r
+               read_frame_ptr frame;\r
+               if(!frame_pool_.try_pop(frame))         \r
+                       frame.reset(new read_frame(format_desc_.width, format_desc_.height));           \r
+               return read_frame_ptr(frame.get(), [=](read_frame*){frame_pool_.push(frame);});\r
+       }\r
 \r
-       internal_frame_ptr output_frame_;                       \r
+       tbb::concurrent_bounded_queue<read_frame_ptr> frame_pool_;\r
 \r
-       frame_processor_device& frame_processor_;\r
+       common::gl::frame_buffer_object fbo_;\r
 \r
-       std::array<internal_frame_ptr, 2> writing_;\r
+       read_frame_ptr  reading_;       \r
+       gpu_frame_ptr   writing_;\r
+       gpu_frame_ptr   drawing_;\r
        \r
-       common::gl::frame_buffer_object fbo_;\r
        frame_shader shader_;\r
+\r
+       video_format_desc format_desc_;\r
 };\r
        \r
-frame_renderer::frame_renderer(frame_processor_device& frame_processor, const video_format_desc& format_desc) : impl_(new implementation(frame_processor, format_desc)){}\r
-internal_frame_ptr frame_renderer::render(const internal_frame_ptr& frames){ return impl_->render(frames);}\r
+frame_renderer::frame_renderer(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+consumer_frame frame_renderer::render(const gpu_frame_ptr& frame)\r
+{\r
+       return impl_->render(frame);\r
+}\r
 }}
\ No newline at end of file
index 7ea8fe6ed262392088c4e3271ecfdb78cd44b296..c417ba8434de86c448dd2d17206fa4d1a5fc43cd 100644 (file)
@@ -19,7 +19,7 @@
 */\r
 #pragma once\r
 \r
-#include "frame_processor_device.h"\r
+#include "fwd.h"\r
 \r
 #include "../format/video_format.h"\r
 \r
@@ -32,9 +32,9 @@ namespace caspar { namespace core {
 class frame_renderer :  boost::noncopyable\r
 {\r
 public:\r
-       frame_renderer(frame_processor_device& frame_processor, const video_format_desc& format_desc_);\r
+       frame_renderer(const video_format_desc& format_desc_);\r
                \r
-       internal_frame_ptr render(const internal_frame_ptr& frames);\r
+       consumer_frame render(const gpu_frame_ptr& frame);\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index e951725d1143da11f4e550c3c97b9ad05e5b0433..f2989516e6bc9f5b4074e79fe1c3f381457554af 100644 (file)
@@ -4,6 +4,7 @@
 \r
 #include "../../common/exception/exceptions.h"\r
 #include "../../common/gl/utility.h"\r
+#include "../../common/gl/shader_program.h"\r
 \r
 #include <Glee.h>\r
 \r
 #include <unordered_map>\r
 \r
 namespace caspar { namespace core {\r
+               \r
+GLubyte progressive_pattern[] = {\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+       0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
        \r
-class shader_program : boost::noncopyable\r
-{\r
-public:\r
-       shader_program() : program_(0){}\r
-       shader_program(shader_program&& other) : program_(other.program_){}\r
-       shader_program& operator=(shader_program&& other) \r
-       {\r
-               program_ = other.program_; \r
-               other.program_ = 0; \r
-               return *this;\r
-       }\r
-\r
-       shader_program(const std::string& vertex_source_str, const std::string& fragment_source_str) : program_(0)\r
-       {\r
-               GLint success;\r
-\r
-               try\r
-               {               \r
-                       const char* vertex_source = vertex_source_str.c_str();\r
-                                               \r
-                       auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
-                                       \r
-                       GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
-                       GL(glCompileShaderARB(vertex_shader));\r
-\r
-                       GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
-                       if (success == GL_FALSE)\r
-                       {\r
-                               char info[2048];\r
-                               GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
-                               GL(glDeleteObjectARB(vertex_shader));\r
-                               std::stringstream str;\r
-                               str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
-                               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
-                       }\r
-                       \r
-                       const char* fragment_source = fragment_source_str.c_str();\r
-                                               \r
-                       auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
-                                       \r
-                       GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
-                       GL(glCompileShaderARB(fragmemt_shader));\r
-\r
-                       GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
-                       if (success == GL_FALSE)\r
-                       {\r
-                               char info[2048];\r
-                               GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
-                               GL(glDeleteObjectARB(fragmemt_shader));\r
-                               std::stringstream str;\r
-                               str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
-                               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
-                       }\r
-                       \r
-                       program_ = glCreateProgramObjectARB();\r
-                       \r
-                       GL(glAttachObjectARB(program_, vertex_shader));\r
-                       GL(glAttachObjectARB(program_, fragmemt_shader));\r
-\r
-                       GL(glLinkProgramARB(program_));\r
-                       \r
-                       GL(glDeleteObjectARB(vertex_shader));\r
-                       GL(glDeleteObjectARB(fragmemt_shader));\r
-\r
-                       GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
-                       if (success == GL_FALSE)\r
-                       {\r
-                               char info[2048];\r
-                               GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
-                               GL(glDeleteObjectARB(program_));\r
-                               std::stringstream str;\r
-                               str << "Failed to link shader program:" << std::endl << info << std::endl;\r
-                               BOOST_THROW_EXCEPTION(common::gl::gl_error() << msg_info(str.str()));\r
-                       }\r
-                       GL(glUseProgramObjectARB(program_));\r
-                       glUniform1i(glGetUniformLocation(program_, "plane[0]"), 0);\r
-                       glUniform1i(glGetUniformLocation(program_, "plane[1]"), 1);\r
-                       glUniform1i(glGetUniformLocation(program_, "plane[2]"), 2);\r
-                       glUniform1i(glGetUniformLocation(program_, "plane[3]"), 3);\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                       throw;\r
-               }\r
-       }\r
-\r
-       ~shader_program()\r
-       {\r
-               glDeleteProgram(program_);\r
-       }\r
-\r
-       void use()\r
-       {       \r
-               GL(glUseProgramObjectARB(program_));            \r
-       }\r
-\r
-       GLuint program() { return program_; }\r
+GLubyte upper_pattern[] = {\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
+               \r
+GLubyte lower_pattern[] = {\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
        \r
-private:\r
-       GLuint program_;\r
-};\r
-typedef std::shared_ptr<shader_program> shader_program_ptr;\r
-\r
 struct frame_shader::implementation\r
 {\r
-       implementation(const video_format_desc& format_desc) \r
-               : current_(pixel_format::invalid), format_desc_(format_desc)\r
+       implementation(const video_format_desc& format_desc) : current_(pixel_format::invalid), format_desc_(format_desc), alpha_(1.0)\r
        {\r
+               transform_stack_.push(shader_transform());\r
                std::string common_vertex = \r
-                       "uniform sampler2D      plane[4];                                                                                       "\r
-                       "uniform vec4           plane_size[2];                                                                          "\r
-                       "                                                                                                                                               "\r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
-                       //"     vec2 t0 = gl_MultiTexCoord0.xy + plane_size[0].zw*0.5;                          "\r
-                       //"     vec4 x0 = vec4(-1.0, 0.0, 1.0, 2.0)*plane_size[0].z;                            "\r
-                       //"     vec4 y0 = vec4(-1.0, 0.0, 1.0, 2.0)*plane_size[0].w;                            "\r
-                       //"     gl_TexCoord[0] = t0.xyxy + vec4(x0.x, y0.x, x0.y, y0.y);                        "\r
-                       //"     gl_TexCoord[1] = t0.xyxy + vec4(x0.z, y0.x, x0.w, y0.y);                        "\r
-                       //"     gl_TexCoord[2] = t0.xyxy + vec4(x0.x, y0.z, x0.y, y0.w);                        "\r
-                       //"     gl_TexCoord[3] = t0.xyxy + vec4(x0.z, y0.z, x0.w, y0.w);                        "\r
-                       //"                                                                                                                                             "\r
-                       //"     vec2 t1 = gl_MultiTexCoord0.xy + plane_size[1].zw*0.5;                          "\r
-                       //"     vec4 x1 = vec4(-1.0, 0.0, 1.0, 2.0)*plane_size[1].z;                            "\r
-                       //"     vec4 y1 = vec4(-1.0, 0.0, 1.0, 2.0)*plane_size[1].w;                            "\r
-                       //"     gl_TexCoord[4] = t1.xyxy + vec4(x1.x, y1.x, x1.y, y1.y);                        "\r
-                       //"     gl_TexCoord[5] = t1.xyxy + vec4(x1.z, y1.x, x1.w, y1.y);                        "\r
-                       //"     gl_TexCoord[6] = t1.xyxy + vec4(x1.x, y1.z, x1.y, y1.w);                        "\r
-                       //"     gl_TexCoord[7] = t1.xyxy + vec4(x1.z, y1.z, x1.w, y1.w);                        "\r
                        "       gl_TexCoord[0] = gl_MultiTexCoord0;                                                                     "\r
                        "       gl_FrontColor = gl_Color;                                                                                       "\r
                        "       gl_Position = ftransform();                                                                                     "\r
@@ -170,72 +79,8 @@ struct frame_shader::implementation
                        "       return color;                                                                                                           "\r
                        "}                                                                                                                                              "                       \r
                        "                                                                                                                                               ";\r
-                       //"vec4 texture2DNearest(sampler2D sampler, vec4 uv0, vec4 uv1, vec4 uv2, vec4 uv3, vec4 size)"\r
-                       //"{                                                                                                                                            "\r
-                       //"     return texture2D(sampler, uv0.zw);                                                                      "\r
-                       //"}                                                                                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"vec4 texture2DBilinear(sampler2D sampler, vec4 uv0, vec4 uv1, vec4 uv2, vec4 uv3, vec4 size)"\r
-                       //"{                                                                                                                                            "\r
-                       //"     vec2 f = fract(uv0*size.xy);                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"     vec4 t0 = texture2D(sampler, uv0.zw);                                                           "\r
-                       //"     vec4 t1 = texture2D(sampler, uv1.xw);                                                           "\r
-                       //"     vec4 t2 = texture2D(sampler, uv2.zy);                                                           "\r
-                       //"     vec4 t3 = texture2D(sampler, uv3.xy);                                                           "\r
-                       //"                                                                                                                                             "\r
-                       //"     vec4 x0 = mix(t0, t1, f.x);                                                                                     "\r
-                       //"     vec4 x1 = mix(t2, t3, f.x);                                                                                     "\r
-                       //"     return mix(x0, x1, f.y);                                                                                        "\r
-                       //"}                                                                                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"vec4 computeWeights(float x)                                                                                 "\r
-                       //"{                                                                                                                                            "\r
-                       //"     vec4 x1 = x*vec4(1.0, 1.0, -1.0, -1.0) + vec4(1.0, 0.0, 1.0, 2.0);      "\r
-                       //"     vec4 x2 = x1*x1;                                                                                                        "\r
-                       //"     vec4 x3 = x2*x1;                                                                                                        "\r
-                       //"                                                                                                                                             "\r
-                       //"     const float A = -0.75;                                                                                          "       \r
-                       //"     vec4 w;                                                                                                                         "\r
-                       //"     w  = x3 * vec2( A,       A+2.0 ).xyyx;                                                          "\r
-                       //"     w += x2 * vec2(-5.0*A, -(A+3.0)).xyyx;                                                          "\r
-                       //"     w += x1 * vec2( 8.0*A,       0 ).xyyx;                                                          "\r
-                       //"     w +=      vec2(-4.0*A,     1.0 ).xyyx;                                                          "\r
-                       //"     return w;                                                                                                                       "\r
-                       //"}                                                                                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"vec4 cubicFilter(vec4 w, vec4 c0, vec4 c1, vec4 c2, vec4 c3)                 "\r
-                       //"{                                                                                                                                            "\r
-                       //"     return c0*w[0] + c1*w[1] + c2*w[2] + c3*w[3];                                           "\r
-                       //"}                                                                                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"vec4 texture2DBicubic(sampler2D sampler, vec4 uv0, vec4 uv1, vec4 uv2, vec4 uv3, vec4 size)"\r
-                       //"{                                                                                                                                            "\r
-                       //"     vec2 f = fract(uv0*size.xy);                                                                            "\r
-                       //"                                                                                                                                             "\r
-                       //"     vec4 w = computeWeights(f.x);                                                                           "\r
-                       //"     vec4 x0 = cubicFilter(w, texture2D(sampler, uv0.xy),                            "\r
-                       //"                                                      texture2D(sampler, uv0.zy),                            "\r
-                       //"                                                      texture2D(sampler, uv1.xy),                            "\r
-                       //"                                                      texture2D(sampler, uv1.zy));                           "\r
-                       //"     vec4 x1 = cubicFilter(w, texture2D(sampler, uv0.xw),                            "\r
-                       //"                                                      texture2D(sampler, uv0.zw),                            "\r
-                       //"                                                      texture2D(sampler, uv1.xw),                            "\r
-                       //"                                                      texture2D(sampler, uv1.zw));                           "\r
-                       //"     vec4 x2 = cubicFilter(w, texture2D(sampler, uv2.xy),                            "\r
-                       //"                                                      texture2D(sampler, uv2.zy),                            "\r
-                       //"                                                      texture2D(sampler, uv3.xy),                            "\r
-                       //"                                                      texture2D(sampler, uv3.zy));                           "\r
-                       //"     vec4 x3 = cubicFilter(w, texture2D(sampler, uv2.xw),                            "\r
-                       //"                                                      texture2D(sampler, uv2.zw),                            "\r
-                       //"                                                      texture2D(sampler, uv3.xw),                            "\r
-                       //"                                                      texture2D(sampler, uv3.zw));                           "\r
-                       //"                                                                                                                                             "\r
-                       //"     w = computeWeights(f.y);                                                                                        "\r
-                       //"     return cubicFilter(w, x0, x1, x2, x3);                                                          "\r
-                       //"}                                                                                                                                            ";              \r
                        \r
-               shaders_[pixel_format::abgr] = shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::abgr] = common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -243,7 +88,7 @@ struct frame_shader::implementation
                        "       gl_FragColor = abgr.argb * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::argb]= shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::argb]= common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "       \r
                        "{                                                                                                                                              "\r
@@ -251,7 +96,7 @@ struct frame_shader::implementation
                        "       gl_FragColor = argb.grab * gl_Color;                                                            "       \r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::bgra]= shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::bgra]= common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -259,7 +104,7 @@ struct frame_shader::implementation
                        "       gl_FragColor = bgra.rgba * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::rgba] = shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::rgba] = common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -267,7 +112,7 @@ struct frame_shader::implementation
                        "       gl_FragColor = rgba.bgra * gl_Color;                                                            "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::ycbcr] = shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::ycbcr] = common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -278,7 +123,7 @@ struct frame_shader::implementation
                        "       gl_FragColor = ycbcra_to_bgra(y, cb, cr, a) * gl_Color;                 "\r
                        "}                                                                                                                                              ");\r
                \r
-               shaders_[pixel_format::ycbcra] = shader_program(common_vertex, common_fragment +\r
+               shaders_[pixel_format::ycbcra] = common::gl::shader_program(common_vertex, common_fragment +\r
 \r
                        "void main()                                                                                                                    "\r
                        "{                                                                                                                                              "\r
@@ -290,10 +135,41 @@ struct frame_shader::implementation
                        "}                                                                                                                                              ");\r
        }\r
 \r
-       void use(const pixel_format_desc& desc)\r
+       void begin(const shader_transform& transform)\r
+       {\r
+               transform_stack_.push(transform);\r
+\r
+               glPushMatrix();\r
+               alpha_ *= transform_stack_.top().alpha;\r
+               glColor4d(1.0, 1.0, 1.0, alpha_);\r
+               glTranslated(transform_stack_.top().pos.get<0>()*2.0, transform_stack_.top().pos.get<1>()*2.0, 0.0);\r
+\r
+               if(transform.mode == video_mode::upper)\r
+                       glPolygonStipple(upper_pattern);\r
+               else if(transform.mode == video_mode::lower)\r
+                       glPolygonStipple(lower_pattern);\r
+               else\r
+                       glPolygonStipple(progressive_pattern);\r
+       }\r
+               \r
+       void render(const pixel_format_desc& desc)\r
        {\r
                set_pixel_format(desc.pix_fmt);\r
-               set_planes(desc.planes);\r
+\r
+               auto t = transform_stack_.top();\r
+               glBegin(GL_QUADS);\r
+                       glTexCoord2d(0.0, 0.0); glVertex2d(-1.0, -1.0);\r
+                       glTexCoord2d(1.0, 0.0); glVertex2d( 1.0, -1.0);\r
+                       glTexCoord2d(1.0, 1.0); glVertex2d( 1.0,  1.0);\r
+                       glTexCoord2d(0.0, 1.0); glVertex2d(-1.0,  1.0);\r
+               glEnd();\r
+       }\r
+\r
+       void end()\r
+       {\r
+               alpha_ /= transform_stack_.top().alpha;\r
+               glPopMatrix();\r
+               transform_stack_.pop();\r
        }\r
 \r
        void set_pixel_format(pixel_format::type format)\r
@@ -303,33 +179,17 @@ struct frame_shader::implementation
                current_ = format;\r
                shaders_[format].use();\r
        }\r
-\r
-       void set_planes(const std::vector<pixel_format_desc::plane>& planes)\r
-       {\r
-               for(size_t n = 0; n < planes.size() && n < 2; ++n)\r
-                       glUniform4f(glGetUniformLocation(shaders_[current_].program(), std::string("plane_size[" + boost::lexical_cast<std::string>(n) + "]").c_str()), \r
-                               static_cast<float>(planes[n].width), static_cast<float>(planes[n].height), 1.0f/static_cast<float>(planes[n].width), 1.0f/static_cast<float>(planes[n].height));\r
-       }\r
-\r
-       //void set_size(pixel_format_desc& desc)\r
-       //{\r
-       //      for(int n = 0; n < 4; ++n)\r
-       //      {\r
-       //              std::string name = std::string("plane_size[") + boost::lexical_cast<std::string>(n) + "]";\r
-       //              GL(glUniform4f(shaders_[current_].get_location(name), \r
-       //                      static_cast<float>(desc.planes[n].width), \r
-       //                      static_cast<float>(desc.planes[n].height),\r
-       //                      1.0f/static_cast<float>(desc.planes[n].width),\r
-       //                      1.0f/static_cast<float>(desc.planes[n].height)));\r
-       //      }\r
-       //}     \r
+                \r
+       double alpha_;\r
+       std::stack<shader_transform> transform_stack_;\r
 \r
        video_format_desc format_desc_;\r
        pixel_format::type current_;\r
-       std::unordered_map<pixel_format::type, shader_program> shaders_;\r
+       std::unordered_map<pixel_format::type, common::gl::shader_program> shaders_;\r
 };\r
 \r
 frame_shader::frame_shader(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-void frame_shader::use(const pixel_format_desc& desc){impl_->use(desc);}\r
-\r
+void frame_shader::begin(const shader_transform& transform) {impl_->begin(transform);}\r
+void frame_shader::render(const pixel_format_desc& desc){impl_->render(desc);}\r
+void frame_shader::end(){impl_->end();}\r
 }}
\ No newline at end of file
index f31d88d1e46a6448ca383b3f71417e4ffa225a73..5073d3af781f29e55ca37abf6de1630159135943 100644 (file)
@@ -3,17 +3,30 @@
 #include "../format/video_format.h"\r
 #include "../format/pixel_format.h"\r
 \r
+#include <boost/tuple/tuple.hpp>\r
+\r
 #include <memory>\r
 #include <array>\r
 \r
 namespace caspar { namespace core {\r
        \r
+struct shader_transform\r
+{\r
+       shader_transform() : alpha(1.0), pos(boost::make_tuple(0.0, 0.0)), uv(boost::make_tuple(0.0, 1.0, 1.0, 0.0)), mode(video_mode::invalid){}\r
+       double alpha;\r
+       boost::tuple<double, double> pos;\r
+       boost::tuple<double, double, double, double> uv;\r
+       video_mode::type mode; \r
+};\r
+\r
 class frame_shader\r
 {\r
 public:\r
        frame_shader(const video_format_desc& format_desc);\r
-       void use(const pixel_format_desc& image);\r
 \r
+       void begin(const shader_transform& transform);\r
+       void render(const pixel_format_desc& image);\r
+       void end();\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
diff --git a/core/processor/fwd.h b/core/processor/fwd.h
new file mode 100644 (file)
index 0000000..9a25b94
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once\r
+\r
+#include <memory>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+class gpu_frame;\r
+typedef std::shared_ptr<gpu_frame> gpu_frame_ptr;\r
+\r
+class write_frame;\r
+typedef std::shared_ptr<write_frame> write_frame_ptr;\r
+\r
+class transform_frame;\r
+typedef std::shared_ptr<transform_frame> transform_frame_ptr;\r
+\r
+class composite_frame;\r
+typedef std::shared_ptr<composite_frame> composite_frame_ptr;\r
+\r
+class consumer_frame;\r
+\r
+class frame_shader;\r
+typedef std::shared_ptr<frame_shader> frame_shader_ptr;\r
+\r
+class frame_renderer;\r
+typedef std::shared_ptr<frame_renderer> frame_renderer_ptr;\r
+\r
+class frame_processor_device;\r
+typedef std::shared_ptr<frame_processor_device> frame_processor_device_ptr;\r
+}}
\ No newline at end of file
diff --git a/core/processor/gpu_frame.h b/core/processor/gpu_frame.h
new file mode 100644 (file)
index 0000000..39a01bf
--- /dev/null
@@ -0,0 +1,27 @@
+#pragma once\r
+\r
+#include "fwd.h"\r
+\r
+#include "../../common/exception/exceptions.h"\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+#include <memory>\r
+#include <vector>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+class gpu_frame : boost::noncopyable\r
+{      \r
+public:\r
+       virtual const std::vector<short>& audio_data() const = 0;\r
+       virtual std::vector<short>& audio_data() = 0;\r
+       \r
+       virtual void begin_write() = 0;\r
+       virtual void end_write() = 0;\r
+       virtual void draw(frame_shader& shader) = 0;\r
+};\r
+typedef std::shared_ptr<gpu_frame> gpu_frame_ptr;\r
+\r
+\r
+}}
\ No newline at end of file
diff --git a/core/processor/read_frame.cpp b/core/processor/read_frame.cpp
new file mode 100644 (file)
index 0000000..39e1bef
--- /dev/null
@@ -0,0 +1,50 @@
+#include "../StdAfx.h"\r
+\r
+#include "read_frame.h"\r
+#include "../format/pixel_format.h"\r
+#include "../../common/gl/utility.h"\r
+#include "../../common/gl/pixel_buffer_object.h"\r
+\r
+#include <boost/range/algorithm.hpp>\r
+\r
+namespace caspar { namespace core {\r
+                                                                                                                                                                                                                                                                                                                       \r
+struct read_frame::implementation : boost::noncopyable\r
+{\r
+       implementation(size_t width, size_t height) : pixel_data_(nullptr)\r
+       {\r
+               if(width > 2 || height > 2)\r
+                       pbo_.reset(new common::gl::pixel_buffer_object(width, height, GL_BGRA));\r
+       }\r
+               \r
+       void begin_read()\r
+       {       \r
+               if(!pbo_)\r
+                       return;\r
+               pixel_data_ = nullptr;\r
+               pbo_->begin_read();\r
+       }\r
+\r
+       void end_read()\r
+       {\r
+               if(!pbo_)\r
+                       return;\r
+               pixel_data_ = pbo_->end_read();\r
+       }\r
+               \r
+       std::unique_ptr<common::gl::pixel_buffer_object> pbo_;\r
+       void* pixel_data_;      \r
+       std::vector<short> audio_data_;\r
+};\r
+       \r
+read_frame::read_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}\r
+void read_frame::begin_read(){impl_->begin_read();}\r
+void read_frame::end_read(){impl_->end_read();}\r
+const boost::iterator_range<const unsigned char*> read_frame::data() const\r
+{\r
+       auto ptr = static_cast<const unsigned char*>(impl_->pixel_data_);\r
+       return boost::iterator_range<const unsigned char*>(ptr, ptr+impl_->pbo_->size());\r
+}\r
+const std::vector<short>& read_frame::audio_data() const { return impl_->audio_data_; }\r
+std::vector<short>& read_frame::audio_data() { return impl_->audio_data_; }\r
+}}
\ No newline at end of file
diff --git a/core/processor/read_frame.h b/core/processor/read_frame.h
new file mode 100644 (file)
index 0000000..da5af08
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma once\r
+\r
+#include "../format/video_format.h"\r
+#include "../format/pixel_format.h"\r
+\r
+#include <boost/noncopyable.hpp>\r
+#include <boost/range/iterator_range.hpp>\r
+\r
+#include <memory>\r
+#include <vector>\r
+\r
+namespace caspar { namespace core {\r
+\r
+class read_frame : boost::noncopyable\r
+{\r
+public:        \r
+       explicit read_frame(size_t width, size_t height);\r
+\r
+       const boost::iterator_range<const unsigned char*> data() const;\r
+       const std::vector<short>& audio_data() const;\r
+       std::vector<short>& audio_data();\r
+       \r
+       void begin_read();\r
+       void end_read();\r
+\r
+private:\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
+};\r
+typedef std::shared_ptr<read_frame> read_frame_ptr;\r
+               \r
+class consumer_frame\r
+{\r
+public:        \r
+       consumer_frame(const read_frame_ptr& frame) : frame_(frame){}\r
+       const boost::iterator_range<const unsigned char*> data() const {return frame_->data();}\r
+       const std::vector<short>& audio_data() const {return frame_->audio_data();}\r
+       \r
+private:\r
+       read_frame_ptr frame_;\r
+};\r
+typedef std::shared_ptr<consumer_frame> consumer_frame_ptr;\r
+typedef std::unique_ptr<consumer_frame> consumer_frame_uptr;\r
+\r
+}}
\ No newline at end of file
diff --git a/core/processor/transform_frame.cpp b/core/processor/transform_frame.cpp
new file mode 100644 (file)
index 0000000..8709b1f
--- /dev/null
@@ -0,0 +1,81 @@
+#include "../StdAfx.h"\r
+\r
+#include "transform_frame.h"\r
+\r
+#include "frame_shader.h"\r
+\r
+#include "../format/pixel_format.h"\r
+#include "../../common/gl/utility.h"\r
+#include "../../common/gl/pixel_buffer_object.h"\r
+\r
+#include <boost/range/algorithm.hpp>\r
+\r
+#include <tbb/parallel_for.h>\r
+\r
+namespace caspar { namespace core {\r
+                                                                                                                                                                                                                                                                                                               \r
+struct transform_frame::implementation : boost::noncopyable\r
+{\r
+       implementation(const gpu_frame_ptr& frame) : frame_(frame), audio_volume_(255){}\r
+       \r
+       void draw(frame_shader& shader)\r
+       {\r
+               if(!frame_)\r
+                       return;\r
+\r
+               shader.begin(transform_);\r
+               frame_->draw(shader);\r
+               shader.end();\r
+       }\r
+\r
+       std::vector<short>& audio_data()\r
+       {\r
+               if(!audio_data_.empty() || !frame_)\r
+                       return audio_data_;\r
+               \r
+               audio_data_ = frame_->audio_data();\r
+               tbb::parallel_for\r
+               (\r
+                       tbb::blocked_range<size_t>(0, audio_data_.size()),\r
+                       [&](const tbb::blocked_range<size_t>& r)\r
+                       {\r
+                               for(size_t n = r.begin(); n < r.end(); ++n)                                     \r
+                                       audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n])*audio_volume_)>>8);                                               \r
+                       }\r
+               );\r
+               \r
+               return audio_data_;\r
+       }\r
+\r
+       void begin_write()\r
+       {\r
+               if(frame_)\r
+                       frame_->begin_write();\r
+       }\r
+\r
+       void end_write()\r
+       {\r
+               if(frame_)\r
+                       frame_->end_write();\r
+       }\r
+               \r
+       std::vector<short> audio_data_;\r
+       \r
+       shader_transform transform_;\r
+\r
+       unsigned char audio_volume_;\r
+       gpu_frame_ptr frame_;\r
+};\r
+       \r
+transform_frame::transform_frame(const gpu_frame_ptr& frame) : impl_(new implementation(frame)){}\r
+void transform_frame::begin_write(){impl_->begin_write();}\r
+void transform_frame::end_write(){impl_->end_write();} \r
+void transform_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
+void transform_frame::audio_volume(unsigned char volume){impl_->audio_volume_ = volume;}\r
+void transform_frame::translate(double x, double y){impl_->transform_.pos = boost::make_tuple(x, y);}\r
+void transform_frame::texcoord(double left, double top, double right, double bottom){impl_->transform_.uv = boost::make_tuple(left, top, right, bottom);}\r
+void transform_frame::video_mode(video_mode::type mode){impl_->transform_.mode = mode;}\r
+void transform_frame::alpha(double value){impl_->transform_.alpha = value;}\r
+std::vector<short>& transform_frame::audio_data() { return impl_->audio_data(); }\r
+const std::vector<short>& transform_frame::audio_data() const { return impl_->audio_data(); }\r
+}}
\ No newline at end of file
diff --git a/core/processor/transform_frame.h b/core/processor/transform_frame.h
new file mode 100644 (file)
index 0000000..b4c2cc7
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once\r
+\r
+#include "gpu_frame.h"\r
+\r
+#include "../format/video_format.h"\r
+#include "../format/pixel_format.h"\r
+\r
+#include <boost/noncopyable.hpp>\r
+#include <boost/range/iterator_range.hpp>\r
+\r
+#include <memory>\r
+#include <array>\r
+#include <vector>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+class transform_frame : public gpu_frame\r
+{\r
+public:\r
+       explicit transform_frame(const gpu_frame_ptr& frame);\r
+       \r
+       virtual std::vector<short>& audio_data();\r
+       virtual const std::vector<short>& audio_data() const;\r
+\r
+       void audio_volume(unsigned char volume);\r
+       void translate(double x, double y);\r
+       void texcoord(double left, double top, double right, double bottom);\r
+       void video_mode(video_mode::type mode);\r
+       void alpha(double value);\r
+\r
+protected:                     \r
+       virtual void begin_write();\r
+       virtual void end_write();\r
+       virtual void draw(frame_shader& shader);\r
+\r
+private:\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
+};\r
+typedef std::shared_ptr<transform_frame> transform_frame_ptr;\r
+\r
+}}
\ No newline at end of file
diff --git a/core/processor/write_frame.cpp b/core/processor/write_frame.cpp
new file mode 100644 (file)
index 0000000..6fb31a9
--- /dev/null
@@ -0,0 +1,105 @@
+#include "../StdAfx.h"\r
+\r
+#include "write_frame.h"\r
+\r
+#include "frame_shader.h"\r
+\r
+#include "../format/pixel_format.h"\r
+#include "../../common/gl/utility.h"\r
+#include "../../common/gl/pixel_buffer_object.h"\r
+\r
+#include <boost/range/algorithm.hpp>\r
+\r
+namespace caspar { namespace core {\r
+                                                                                                                                                                                                                                                                                                                       \r
+struct write_frame::implementation : boost::noncopyable\r
+{\r
+       implementation(const pixel_format_desc& desc) : desc_(desc)\r
+       {                       \r
+               assert(desc_.planes.size() <= 4);\r
+\r
+               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
+\r
+               for(size_t n = 0; n < desc_.planes.size(); ++n)\r
+               {\r
+                       if(desc_.planes[n].size == 0)\r
+                               break;\r
+\r
+                       GLuint format = [&]() -> GLuint\r
+                       {\r
+                               switch(desc_.planes[n].channels)\r
+                               {\r
+                               case 1: return GL_LUMINANCE;\r
+                               case 2: return GL_LUMINANCE_ALPHA;\r
+                               case 3: return GL_BGR;\r
+                               case 4: return GL_BGRA;\r
+                               default: BOOST_THROW_EXCEPTION(out_of_range() << msg_info("1-4 channels are supported") << arg_name_info("desc.planes.channels")); \r
+                               }\r
+                       }();\r
+\r
+                       pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(desc_.planes[n].width, desc_.planes[n].height, format));\r
+                       pbo_.back()->is_smooth(true);\r
+               }\r
+               end_write();\r
+       }\r
+       \r
+       void begin_write()\r
+       {\r
+               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
+               boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_write));\r
+       }\r
+\r
+       void end_write()\r
+       {\r
+               boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_write));\r
+       }\r
+\r
+       void draw(frame_shader& shader)\r
+       {\r
+               assert(pbo_.size() == desc_.planes.size());\r
+\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+               {\r
+                       glActiveTexture(GL_TEXTURE0+n);\r
+                       pbo_[n]->bind_texture();\r
+               }\r
+               shader.render(desc_);\r
+       }\r
+\r
+       unsigned char* data(size_t index)\r
+       {\r
+               return static_cast<unsigned char*>(pixel_data_[index]);\r
+       }\r
+\r
+       void reset()\r
+       {\r
+               audio_data_.clear();\r
+               end_write();\r
+       }\r
+       \r
+       std::vector<common::gl::pixel_buffer_object_ptr> pbo_;\r
+       std::array<void*, 4> pixel_data_;       \r
+       std::vector<short> audio_data_;\r
+       \r
+       const pixel_format_desc desc_;\r
+};\r
+       \r
+write_frame::write_frame(const pixel_format_desc& desc) : impl_(new implementation(desc)){}\r
+void write_frame::begin_write(){impl_->begin_write();}\r
+void write_frame::end_write(){impl_->end_write();}     \r
+void write_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
+boost::iterator_range<unsigned char*> write_frame::data(size_t index)\r
+{\r
+       auto ptr = static_cast<unsigned char*>(impl_->pixel_data_[index]);\r
+       return boost::iterator_range<unsigned char*>(ptr, ptr+impl_->desc_.planes[index].size);\r
+}\r
+const boost::iterator_range<const unsigned char*> write_frame::data(size_t index) const\r
+{\r
+       auto ptr = static_cast<const unsigned char*>(impl_->pixel_data_[index]);\r
+       return boost::iterator_range<const unsigned char*>(ptr, ptr+impl_->desc_.planes[index].size);\r
+}\r
+\r
+std::vector<short>& write_frame::audio_data() { return impl_->audio_data_; }\r
+const std::vector<short>& write_frame::audio_data() const { return impl_->audio_data_; }\r
+void write_frame::reset(){impl_->reset();}\r
+}}
\ No newline at end of file
diff --git a/core/processor/write_frame.h b/core/processor/write_frame.h
new file mode 100644 (file)
index 0000000..e951894
--- /dev/null
@@ -0,0 +1,47 @@
+#pragma once\r
+\r
+#include "fwd.h"\r
+\r
+#include "gpu_frame.h"\r
+\r
+#include "../format/video_format.h"\r
+#include "../format/pixel_format.h"\r
+\r
+#include <boost/noncopyable.hpp>\r
+#include <boost/tuple/tuple.hpp>\r
+#include <boost/range/iterator_range.hpp>\r
+\r
+#include <memory>\r
+#include <array>\r
+#include <vector>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+class write_frame : public gpu_frame\r
+{\r
+       friend class frame_renderer;\r
+       friend class frame_processor_device;\r
+\r
+public:        \r
+       boost::iterator_range<unsigned char*> data(size_t index = 0);\r
+       const boost::iterator_range<const unsigned char*> data(size_t index = 0) const;\r
+\r
+       virtual std::vector<short>& audio_data();\r
+       virtual const std::vector<short>& audio_data() const;\r
+       \r
+private:\r
+       explicit write_frame(const pixel_format_desc& desc);\r
+\r
+       virtual void reset();\r
+               \r
+       virtual void begin_write();\r
+       virtual void end_write();\r
+       virtual void draw(frame_shader& shader);\r
+\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
+};\r
+typedef std::shared_ptr<write_frame> write_frame_ptr;\r
+\r
+\r
+}}
\ No newline at end of file
index 92e9c4ddefea9aa0e4bf1585d1fac86ca4deb88e..0b448bf842456263cb5dc7f06685393fed44873d 100644 (file)
@@ -67,7 +67,7 @@ class color_producer : public frame_producer
 public:\r
        explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)){}\r
        \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        { \r
                return frame_;\r
        }\r
@@ -84,7 +84,7 @@ public:
                return + L"color_producer. color: " + color_str_;\r
        }\r
 \r
-       frame_ptr frame_;\r
+       gpu_frame_ptr frame_;\r
        unsigned int color_value_;\r
        std::wstring color_str_;\r
 };\r
index 4a952447ea0fcaf3c5bfb0660326f7d9990a541f..e91f111b4f79c6feb845e5f5404b87ea345fb33e 100644 (file)
@@ -79,7 +79,7 @@ public:
                video_transformer_->initialize(frame_processor);\r
        }\r
                \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {\r
                while(ouput_channel_.empty() && !input_->is_eof())\r
                {       \r
@@ -111,7 +111,7 @@ public:
 \r
                                // Return last frame without audio.\r
                                if(last_frame_)\r
-                                       last_frame_->get_audio_data().clear();\r
+                                       last_frame_->audio_data().clear();\r
                                return last_frame_;\r
                        }\r
                        else if(underrun_count_ > 0)\r
@@ -124,11 +124,11 @@ public:
                        {\r
                                if(has_audio_ && video_frame_channel_.front() != nullptr)\r
                                {\r
-                                       video_frame_channel_.front()->get_audio_data() = std::move(audio_chunk_channel_.front());\r
+                                       video_frame_channel_.front()->audio_data() = std::move(audio_chunk_channel_.front());\r
                                        audio_chunk_channel_.pop_front();\r
                                }\r
                                \r
-                               frame_ptr frame = video_frame_channel_.front();\r
+                               gpu_frame_ptr frame = video_frame_channel_.front();\r
                                video_frame_channel_.pop_front();\r
                                ouput_channel_.push(std::move(frame));\r
                        }                               \r
@@ -156,18 +156,18 @@ public:
 \r
        video_decoder_uptr                                      video_decoder_;\r
        video_transformer_uptr                          video_transformer_;\r
-       std::deque<frame_ptr>                           video_frame_channel_;\r
+       std::deque<gpu_frame_ptr>                       video_frame_channel_;\r
        \r
        audio_decoder_ptr                                       audio_decoder_;\r
        std::deque<std::vector<short>>          audio_chunk_channel_;\r
 \r
-       std::queue<frame_ptr>                           ouput_channel_;\r
+       std::queue<gpu_frame_ptr>                       ouput_channel_;\r
        \r
        std::wstring                                            filename_;\r
 \r
        long                                                            underrun_count_;\r
 \r
-       frame_ptr                                                       last_frame_;\r
+       gpu_frame_ptr                                           last_frame_;\r
 };\r
 \r
 frame_producer_ptr create_ffmpeg_producer(const  std::vector<std::wstring>& params)\r
index 9a63cf41f0f45faf7a36a714ab9aa23055bad258..51794294d36b9a57b0cc7b430ce03a84a10eb6f0 100644 (file)
@@ -3,7 +3,8 @@
 #include "video_transformer.h"\r
 \r
 #include "../../../format/video_format.h"\r
-#include "../../../processor/frame.h"\r
+#include "../../../processor/write_frame.h"\r
+#include "../../../processor/transform_frame.h"\r
 #include "../../../processor/frame_processor_device.h"\r
 \r
 #include <tbb/parallel_for.h>\r
@@ -25,7 +26,7 @@ extern "C"
 #pragma warning (pop)\r
 #endif\r
 \r
-namespace caspar { namespace core { namespace ffmpeg{\r
+namespace caspar { namespace core { namespace ffmpeg {\r
        \r
 pixel_format::type get_pixel_format(PixelFormat pix_fmt)\r
 {\r
@@ -103,12 +104,12 @@ struct video_transformer::implementation : boost::noncopyable
                }\r
        }\r
        \r
-       frame_ptr execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
+       gpu_frame_ptr execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
        {                               \r
                if(decoded_frame == nullptr)\r
                        return nullptr;\r
                                \r
-               frame_ptr result_frame;\r
+               write_frame_ptr result_frame;\r
                if(sws_context_ == nullptr)\r
                {\r
                        result_frame = frame_processor_->create_frame(desc_);\r
@@ -139,11 +140,14 @@ struct video_transformer::implementation : boost::noncopyable
 \r
                // TODO: Make generic for all formats and modes.\r
                if(codec_context_->codec_id == CODEC_ID_DVVIDEO) // Move up one field\r
-                       result_frame->get_render_transform().pos = boost::make_tuple(0.0f, 1.0/static_cast<double>(frame_processor_->get_video_format_desc().height));\r
+               {\r
+                       auto transform = std::make_shared<transform_frame>(result_frame);\r
+                       transform->translate(0.0f, 1.0/static_cast<double>(frame_processor_->get_video_format_desc().height));\r
+                       return transform;\r
+               }\r
                \r
                return result_frame;\r
        }\r
-\r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
@@ -161,6 +165,6 @@ struct video_transformer::implementation : boost::noncopyable
 };\r
 \r
 video_transformer::video_transformer(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
-frame_ptr video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
+gpu_frame_ptr video_transformer::execute(const std::shared_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
 void video_transformer::initialize(const frame_processor_device_ptr& frame_processor){impl_->initialize(frame_processor); }\r
 }}}
\ No newline at end of file
index f197f7fe59c505138693f197779541e6dfd5630d..a5e6ece22f5f25ba8504d41fc9b08492bdcadabb 100644 (file)
@@ -13,7 +13,7 @@ class video_transformer : boost::noncopyable
 {\r
 public:\r
        video_transformer(AVCodecContext* codec_context);\r
-       frame_ptr execute(const std::shared_ptr<AVFrame>& video_packet);        \r
+       gpu_frame_ptr execute(const std::shared_ptr<AVFrame>& video_packet);    \r
        void initialize(const frame_processor_device_ptr& frame_processor);\r
 private:\r
        struct implementation;\r
index 996b7e0bae98a66bd0676fc1c956a2f94367d312..0d02d006f18957d3aae0a675c4bfeb54047aa3c6 100644 (file)
@@ -35,7 +35,7 @@
 \r
 #pragma warning(push)\r
 \r
-#include "..\..\processor\frame.h"\r
+#include "..\..\processor\write_frame.h"\r
 #include "..\..\format\video_format.h"\r
 \r
 #include <ocmm.h>\r
index 912be42fd976304fe845960792ad1a468b2c4478..84d714a0aec1d869eebcbe7ce8d885ecd1c23754 100644 (file)
@@ -7,7 +7,7 @@
 #include "cg_producer.h"\r
 #include "flash_producer.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../Server.h"\r
 \r
 #include <boost/filesystem.hpp>\r
@@ -146,7 +146,7 @@ public:
                flash_producer_->param(param.str());\r
        }\r
 \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {\r
                return flash_producer_ ? flash_producer_->render_frame() : nullptr;\r
        }\r
@@ -184,7 +184,7 @@ cg_producer_ptr get_default_cg_producer(const channel_ptr& channel, int render_l
 }\r
 \r
 cg_producer::cg_producer() : impl_(new implementation()){}\r
-frame_ptr cg_producer::render_frame(){return impl_->render_frame();}\r
+gpu_frame_ptr cg_producer::render_frame(){return impl_->render_frame();}\r
 void cg_producer::clear(){impl_->clear();}\r
 void cg_producer::add(int layer, const std::wstring& template_name,  bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
 void cg_producer::remove(int layer){impl_->remove(layer);}\r
index 2b38ba8902484b49156d5bdf9981a5d8a55917d1..5b1ff8084ec7b71d3a2987e5e478db41bdbd2aba 100644 (file)
@@ -13,7 +13,7 @@ public:
 \r
        cg_producer();\r
        \r
-       virtual frame_ptr render_frame();\r
+       virtual gpu_frame_ptr render_frame();\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor);\r
 \r
        void clear();\r
index d777a4798be43bd7f5fca2b01803c3fdd0f6fb61..d71f9b871fcf09e779d093f4b5f43c1e0b0a3a19 100644 (file)
@@ -24,7 +24,7 @@
 \r
 #include "cg_producer.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../server.h"\r
 \r
 #include <boost/assign/list_of.hpp>\r
@@ -37,7 +37,7 @@ struct ct_producer : public cg_producer
 {\r
        ct_producer(const std::wstring& filename) : filename_(filename), initialized_(false){}\r
 \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {\r
                if(!initialized_)\r
                {\r
index 17fb8123473d00914afaa1b2dcdcedb1759ba90c..d0ad54e6bc0a494b29dfc7fd02ffc41a50f76ed7 100644 (file)
@@ -34,7 +34,7 @@
 #include "../../../common/concurrency/executor.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 \r
 #include <boost/assign.hpp>\r
@@ -225,14 +225,14 @@ struct flash_producer::implementation
                        auto format_desc = frame_processor_->get_video_format_desc();\r
                        bool is_progressive = format_desc.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc.fps/2 == 0);\r
 \r
-                       frame_ptr result;\r
+                       gpu_frame_ptr result;\r
 \r
                        if(is_progressive)                                                      \r
                                result = do_render_frame();             \r
                        else\r
                        {\r
-                               frame_ptr frame1 = do_render_frame();\r
-                               frame_ptr frame2 = do_render_frame();\r
+                               gpu_frame_ptr frame1 = do_render_frame();\r
+                               gpu_frame_ptr frame2 = do_render_frame();\r
                                result = composite_frame::interlace(frame1, frame2, format_desc.mode);\r
                        }\r
 \r
@@ -241,7 +241,7 @@ struct flash_producer::implementation
                }\r
        }\r
                \r
-       frame_ptr do_render_frame()\r
+       gpu_frame_ptr do_render_frame()\r
        {\r
                auto format_desc = frame_processor_->get_video_format_desc();\r
 \r
@@ -259,15 +259,16 @@ struct flash_producer::implementation
                return frame;\r
        }\r
                \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {               \r
-               return (frame_buffer_.try_pop(last_frame_) || !is_empty_) && last_frame_ ? last_frame_ : frame::empty();\r
+               return (frame_buffer_.try_pop(last_frame_) || !is_empty_) && last_frame_ ? last_frame_ : empty_;\r
        }\r
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
                auto format_desc = frame_processor_->get_video_format_desc();\r
+               empty_ = frame_processor_->create_frame(pixel_format_desc());\r
                bmp_frame_ = std::make_shared<bitmap>(format_desc.width, format_desc.height);\r
                start(false);\r
        }\r
@@ -279,9 +280,10 @@ struct flash_producer::implementation
        \r
        CComObject<flash::FlashAxContainer>* flashax_container_;\r
                \r
-       tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
+       tbb::concurrent_bounded_queue<gpu_frame_ptr> frame_buffer_;\r
 \r
-       frame_ptr last_frame_;\r
+       gpu_frame_ptr empty_;\r
+       gpu_frame_ptr last_frame_;\r
 \r
        bitmap_ptr current_frame_;\r
        bitmap_ptr bmp_frame_;\r
@@ -297,7 +299,7 @@ struct flash_producer::implementation
 };\r
 \r
 flash_producer::flash_producer(const std::wstring& filename) : impl_(new implementation(this, filename)){}\r
-frame_ptr flash_producer::render_frame(){return impl_->render_frame();}\r
+gpu_frame_ptr flash_producer::render_frame(){return impl_->render_frame();}\r
 void flash_producer::param(const std::wstring& param){impl_->param(param);}\r
 void flash_producer::initialize(const frame_processor_device_ptr& frame_processor) { impl_->initialize(frame_processor);}\r
 std::wstring flash_producer::print() const {return impl_->print();}\r
index c3b428f1e475281cb4d15cda2e8f8367cc0ce7f2..f6618983965ea08b44a35dec9d60811da3813fef 100644 (file)
@@ -38,7 +38,7 @@ public:
 \r
        flash_producer(const std::wstring& filename);\r
 \r
-       virtual frame_ptr render_frame();\r
+       virtual gpu_frame_ptr render_frame();\r
        virtual void initialize(const frame_processor_device_ptr& frame_processor);\r
        virtual std::wstring print() const;\r
 \r
index 020475d3647a5d0c089d415cfa02d7c4dd207085..76485a15b8ffbdf0c1fef5c4a2be3e4c4d0bc9a4 100644 (file)
@@ -19,7 +19,7 @@
 */\r
 #pragma once\r
 \r
-#include "../processor/frame.h"\r
+#include "../processor/write_frame.h"\r
 #include "../processor/frame_processor_device.h"\r
 \r
 #include <boost/noncopyable.hpp>\r
@@ -34,7 +34,7 @@ public:
        virtual ~frame_producer(){}     \r
 \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       /// \fn virtual frame_ptr :::render_frame() = 0;\r
+       /// \fn virtual gpu_frame_ptr :::render_frame() = 0;\r
        ///\r
        /// \brief      Renders a frame.\r
        ///             \r
@@ -42,7 +42,7 @@ public:
        ///\r
        /// \return     The frame. \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual frame_ptr render_frame() = 0;\r
+       virtual gpu_frame_ptr render_frame() = 0;\r
 \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual std::shared_ptr<frame_producer> :::get_following_producer() const\r
index fd8343411ba3d815a6b1f83e9c1dcb7f47dc7e0f..9ebb3e110769af9ead36fd79cca06bfb6975c39b 100644 (file)
@@ -20,9 +20,9 @@
        \r
 namespace caspar { namespace core {\r
        \r
-std::vector<frame_ptr> render_frames(std::map<int, layer>& layers)\r
+std::vector<gpu_frame_ptr> render_frames(std::map<int, layer>& layers)\r
 {      \r
-       std::vector<frame_ptr> frames(layers.size(), nullptr);\r
+       std::vector<gpu_frame_ptr> frames(layers.size(), nullptr);\r
        tbb::parallel_for(tbb::blocked_range<size_t>(0, frames.size()), \r
        [&](const tbb::blocked_range<size_t>& r)\r
        {\r
@@ -45,7 +45,6 @@ struct frame_producer_device::implementation : boost::noncopyable
        ~implementation()\r
        {\r
                is_running_ = false;\r
-               frame_processor_->clear();\r
                render_thread_.join();\r
        }\r
                \r
@@ -58,7 +57,7 @@ struct frame_producer_device::implementation : boost::noncopyable
                {\r
                        try\r
                        {       \r
-                               std::vector<frame_ptr> frames;\r
+                               std::vector<gpu_frame_ptr> frames;\r
                                {\r
                                        tbb::mutex::scoped_lock lock(layers_mutex_);    \r
                                        frames = render_frames(layers_);\r
index 2202fe27c0432eb4e590cf0ad276d5973708f7ee..1c6bdd89f233cb7519a2b5d991518038cbb8d761 100644 (file)
@@ -4,7 +4,7 @@
 \r
 #include "../../../common/exception/Exceptions.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 \r
 #if defined(_MSC_VER)\r
 #pragma warning (disable : 4714) // marked as __forceinline not inlined\r
index 1dfc93530d2c69a8c159ab3ba47f405ad8921ea6..2b22d758bb963b21def2a8725d650f069960b624 100644 (file)
@@ -19,7 +19,7 @@ struct image_producer : public frame_producer
 {\r
        image_producer(const std::wstring& filename) : filename_(filename)      {}\r
        \r
-       frame_ptr render_frame(){return frame_;}\r
+       gpu_frame_ptr render_frame(){return frame_;}\r
 \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
@@ -38,7 +38,7 @@ struct image_producer : public frame_producer
        \r
        frame_processor_device_ptr frame_processor_;\r
        std::wstring filename_;\r
-       frame_ptr frame_;\r
+       gpu_frame_ptr frame_;\r
 };\r
 \r
 frame_producer_ptr create_image_producer(const  std::vector<std::wstring>& params)\r
index b63ed2c07d3bbc0b14c4ba7f9110b97fda8e24bb..90bd88201179ef118faa93e9b4a095ec527ccd99 100644 (file)
@@ -4,7 +4,7 @@
 \r
 #include "image_loader.h"\r
 \r
-#include "../../processor/frame.h"\r
+#include "../../processor/write_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 #include "../../format/video_format.h"\r
 #include "../../processor/frame_processor_device.h"\r
@@ -67,9 +67,9 @@ struct image_scroll_producer : public frame_producer
                        std::copy_n(&pBits[i* width * 4], width * 4, &image_.get()[i * image_width_ * 4]);\r
        }\r
 \r
-       frame_ptr do_render_frame()\r
+       gpu_frame_ptr do_render_frame()\r
        {\r
-               frame_ptr frame = frame_processor_->create_frame(format_desc_.width, format_desc_.height);\r
+               auto frame = frame_processor_->create_frame(format_desc_.width, format_desc_.height);\r
                std::fill(frame->data().begin(), frame->data().end(), 0);\r
 \r
                const int delta_x = direction_ == direction::Left ? speed_ : -speed_;\r
@@ -112,12 +112,12 @@ struct image_scroll_producer : public frame_producer
                return frame;\r
        }\r
                \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {               \r
                if(format_desc_.mode != video_mode::progressive)                                \r
                {\r
-                       frame_ptr frame1;\r
-                       frame_ptr frame2;\r
+                       gpu_frame_ptr frame1;\r
+                       gpu_frame_ptr frame2;\r
                        tbb::parallel_invoke([&]{ frame1 = do_render_frame(); }, [&]{ frame2 = do_render_frame(); });\r
                        return composite_frame::interlace(frame1, frame2, format_desc_.mode);\r
                }                       \r
index 270f8db07a564af3372b5c8fd90c8653b7f9d472..339c3e701d614e0c40f597e7de7073c7165ef4d8 100644 (file)
@@ -22,8 +22,6 @@ struct layer::implementation
                {\r
                        foreground_ = nullptr;  \r
                        last_frame_ = frame_producer->render_frame();\r
-                       if(last_frame_ != nullptr)\r
-                               last_frame_->get_audio_data().clear(); // No audio\r
                }\r
                else if(option == load_option::auto_play)\r
                        play();                 \r
@@ -58,7 +56,7 @@ struct layer::implementation
                last_frame_ = nullptr;\r
        }\r
        \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {               \r
                if(!foreground_ || is_paused_)\r
                        return last_frame_;\r
@@ -92,7 +90,7 @@ struct layer::implementation
        }       \r
                \r
        tbb::atomic<bool>       is_paused_;\r
-       frame_ptr                       last_frame_;\r
+       gpu_frame_ptr                   last_frame_;\r
        frame_producer_ptr      foreground_;\r
        frame_producer_ptr      background_;\r
 };\r
@@ -110,7 +108,7 @@ void layer::play(){impl_->play();}
 void layer::pause(){impl_->pause();}\r
 void layer::stop(){impl_->stop();}\r
 void layer::clear(){impl_->clear();}\r
-frame_ptr layer::render_frame() {return impl_->render_frame();}\r
+gpu_frame_ptr layer::render_frame() {return impl_->render_frame();}\r
 frame_producer_ptr layer::foreground() const { return impl_->foreground_;}\r
 frame_producer_ptr layer::background() const { return impl_->background_;}\r
 }}
\ No newline at end of file
index 0837044820b9339d36565af409a89a5564bbf4af..37bdaa912b961d79d6489a3812f23925bb6d002b 100644 (file)
@@ -32,7 +32,7 @@ public:
        frame_producer_ptr foreground() const;\r
        frame_producer_ptr background() const;\r
 \r
-       frame_ptr render_frame();\r
+       gpu_frame_ptr render_frame();\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index 4b06fdf7fd81239e92b3a09db628110a8baaf341..4c7772f529461a85c1986c096993b55a8722bdc3 100644 (file)
@@ -22,8 +22,8 @@
 #include "transition_producer.h"\r
 \r
 #include "../../format/video_format.h"\r
-#include "../../processor/frame.h"\r
 #include "../../processor/composite_frame.h"\r
+#include "../../processor/transform_frame.h"\r
 #include "../../processor/frame_processor_device.h"\r
 \r
 #include "../../producer/frame_producer_device.h"\r
@@ -51,18 +51,18 @@ struct transition_producer::implementation : boost::noncopyable
                org_source_producer_ = source_producer_ = producer;\r
        }\r
                \r
-       frame_ptr render_frame()\r
+       gpu_frame_ptr render_frame()\r
        {\r
                if(current_frame_ == 0)\r
                        CASPAR_LOG(info) << "Transition started.";\r
 \r
-               frame_ptr result = [&]() -> frame_ptr\r
+               gpu_frame_ptr result = [&]() -> gpu_frame_ptr\r
                {\r
                        if(current_frame_++ >= info_.duration)\r
                                return nullptr;\r
 \r
-                       frame_ptr source;\r
-                       frame_ptr dest;\r
+                       gpu_frame_ptr source;\r
+                       gpu_frame_ptr dest;\r
 \r
                        tbb::parallel_invoke\r
                        (\r
@@ -73,18 +73,18 @@ struct transition_producer::implementation : boost::noncopyable
                        return compose(dest, source);\r
                }();\r
 \r
-               if(result == nullptr)\r
+               if(!result)\r
                        CASPAR_LOG(info) << "Transition ended.";\r
 \r
                return result;\r
        }\r
 \r
-       frame_ptr render_frame(frame_producer_ptr& producer)\r
+       gpu_frame_ptr render_frame(frame_producer_ptr& producer)\r
        {\r
-               if(producer == nullptr)\r
+               if(!producer)\r
                        return nullptr;\r
 \r
-               frame_ptr frame;\r
+               gpu_frame_ptr frame;\r
                try\r
                {\r
                        frame = producer->render_frame();\r
@@ -98,7 +98,7 @@ struct transition_producer::implementation : boost::noncopyable
 \r
                if(frame == nullptr)\r
                {\r
-                       if(producer == nullptr || producer->get_following_producer() == nullptr)\r
+                       if(!producer || !producer->get_following_producer())\r
                                return nullptr;\r
 \r
                        try\r
@@ -118,54 +118,42 @@ struct transition_producer::implementation : boost::noncopyable
                }\r
                return frame;\r
        }\r
-                       \r
-       void set_volume(const frame_ptr& frame, int volume)\r
-       {\r
-               assert(volume >= 0 && volume <= 256);\r
-               std::for_each(frame->get_audio_data().begin(), frame->get_audio_data().end(), [&](int16_t& sample)\r
-               {\r
-                       sample = static_cast<short>((static_cast<int>(sample)*volume)>>8);\r
-               });\r
-       }\r
-               \r
-       frame_ptr compose(frame_ptr dest_frame, frame_ptr src_frame) \r
+                                       \r
+       gpu_frame_ptr compose(gpu_frame_ptr dest_frame, gpu_frame_ptr src_frame) \r
        {       \r
                if(!dest_frame && !src_frame)\r
                        return nullptr;\r
 \r
                if(info_.type == transition::cut)               \r
                        return src_frame;\r
-\r
-               dest_frame = dest_frame ? dest_frame : frame::empty();\r
-               src_frame  = src_frame  ? src_frame  : frame::empty();\r
-                                                               \r
+                                                                               \r
                double alpha = static_cast<double>(current_frame_)/static_cast<double>(info_.duration);\r
-               int volume = static_cast<int>(alpha*256.0);\r
-                               \r
-               tbb::parallel_invoke\r
-               (\r
-                       [&]{set_volume(dest_frame, volume);},\r
-                       [&]{set_volume(src_frame, 256-volume);}\r
-               );\r
+               unsigned char volume = static_cast<unsigned char>(alpha*256.0);\r
+\r
+               auto my_src_frame = std::make_shared<transform_frame>(src_frame);\r
+               auto my_dest_frame = std::make_shared<transform_frame>(dest_frame);\r
+\r
+               my_src_frame->audio_volume(255-volume);\r
+               my_dest_frame->audio_volume(volume);\r
 \r
                double dir = info_.direction == transition_direction::from_left ? 1.0 : -1.0;           \r
                \r
                if(info_.type == transition::mix)\r
-                       dest_frame->get_render_transform().alpha = alpha;               \r
+                       my_dest_frame->alpha(alpha);            \r
                else if(info_.type == transition::slide)                        \r
-                       dest_frame->get_render_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);                      \r
+                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);                        \r
                else if(info_.type == transition::push)\r
                {\r
-                       dest_frame->get_render_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);\r
-                       src_frame->get_render_transform().pos = boost::make_tuple((0.0+alpha)*dir, 0.0);\r
+                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);\r
+                       my_src_frame->translate((0.0+alpha)*dir, 0.0);\r
                }\r
                else if(info_.type == transition::wipe)\r
                {\r
-                       dest_frame->get_render_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);                      \r
-                       dest_frame->get_render_transform().uv = boost::make_tuple((-1.0+alpha)*dir, 1.0, 1.0-(1.0-alpha)*dir, 0.0);                             \r
+                       my_dest_frame->translate((-1.0+alpha)*dir, 0.0);                        \r
+                       my_dest_frame->texcoord((-1.0+alpha)*dir, 1.0, 1.0-(1.0-alpha)*dir, 0.0);                               \r
                }\r
                                                \r
-               return std::make_shared<composite_frame>(src_frame, dest_frame);\r
+               return std::make_shared<composite_frame>(my_src_frame, my_dest_frame);\r
        }\r
                \r
        void initialize(const frame_processor_device_ptr& frame_processor)\r
@@ -192,7 +180,7 @@ struct transition_producer::implementation : boost::noncopyable
 };\r
 \r
 transition_producer::transition_producer(const frame_producer_ptr& dest, const transition_info& info) : impl_(new implementation(dest, info)){}\r
-frame_ptr transition_producer::render_frame(){return impl_->render_frame();}\r
+gpu_frame_ptr transition_producer::render_frame(){return impl_->render_frame();}\r
 frame_producer_ptr transition_producer::get_following_producer() const{return impl_->get_following_producer();}\r
 void transition_producer::set_leading_producer(const frame_producer_ptr& producer) { impl_->set_leading_producer(producer); }\r
 void transition_producer::initialize(const frame_processor_device_ptr& frame_processor) { impl_->initialize(frame_processor);}\r
index e0d6940db51f2ab24372e6b9aa631437f4f48117..ecabd9ec07dec0a631831b8c1717cb72b373ae15 100644 (file)
@@ -62,7 +62,7 @@ class transition_producer : public frame_producer
 public:\r
        transition_producer(const frame_producer_ptr& destination, const transition_info& info);\r
 \r
-       frame_ptr render_frame();\r
+       gpu_frame_ptr render_frame();\r
 \r
        frame_producer_ptr get_following_producer() const;\r
        void set_leading_producer(const frame_producer_ptr& producer);\r
index be89ce7e7cf4330a983d5d728a7c2c772197cd58..4c2f44874c371ebc1e4eb66e01890e52a957cc7c 100644 (file)
@@ -8,7 +8,7 @@
   </paths>\r
   <channels>\r
     <channel>\r
-      <videomode>PAL</videomode>\r
+      <videomode>1080p2500</videomode>\r
       <consumers>\r
         <ogl>\r
           <device>1</device>\r
@@ -17,8 +17,8 @@
         </ogl>\r
         <audio/>\r
         <!--decklink>          \r
-        </decklink-->\r
-        <!--bluefish>\r
+        </decklink>\r
+        <bluefish>\r
           <device>1</device> \r
           <embedded-audio>true</embedded-audio>\r
         </bluefish-->\r