]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2:
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Oct 2010 19:36:37 +0000 (19:36 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Oct 2010 19:36:37 +0000 (19:36 +0000)
- Bluefish refactoring
- Opengl -> Bluefish dma transfer
- GPU interlacing
- Fixed composite gpu frame transition bug
- Frameconsumer video sync clock is not optional
- Optimized memcpy

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

54 files changed:
casparcg.sln
common/common.vcxproj
common/common.vcxproj.filters
common/exception/exceptions.h
common/hardware/cpuid.cpp [deleted file]
common/hardware/cpuid.h [deleted file]
common/image/clear.cpp [deleted file]
common/image/copy.cpp [deleted file]
common/image/copy_field.cpp [deleted file]
common/image/copy_field.h [deleted file]
common/image/image.cpp [deleted file]
common/image/image.h [deleted file]
common/utility/memory.cpp [new file with mode: 0644]
common/utility/memory.h [new file with mode: 0644]
core/caspar.config
core/config.h
core/consumer/bluefish/BlueFishVideoConsumer.cpp [deleted file]
core/consumer/bluefish/BlueFishVideoConsumer.h [deleted file]
core/consumer/bluefish/BluefishException.h [deleted file]
core/consumer/bluefish/BluefishPlaybackStrategy.cpp [deleted file]
core/consumer/bluefish/bluefish_consumer.cpp [new file with mode: 0644]
core/consumer/bluefish/bluefish_consumer.h [moved from common/image/clear.h with 56% similarity]
core/consumer/bluefish/exception.h [moved from common/utility/types.h with 72% similarity]
core/consumer/bluefish/fwd.h [new file with mode: 0644]
core/consumer/bluefish/memory.h [new file with mode: 0644]
core/consumer/bluefish/util.h [new file with mode: 0644]
core/consumer/decklink/DecklinkVideoConsumer.cpp
core/consumer/frame_consumer.h
core/consumer/oal/oal_consumer.cpp [moved from core/consumer/oal/oal_frame_consumer.cpp with 79% similarity]
core/consumer/oal/oal_consumer.h [moved from core/consumer/bluefish/BluefishPlaybackStrategy.h with 64% similarity]
core/consumer/ogl/ogl_consumer.cpp [moved from core/consumer/ogl/ogl_frame_consumer.cpp with 85% similarity]
core/consumer/ogl/ogl_consumer.h [moved from common/image/copy.h with 56% similarity]
core/core.vcxproj
core/core.vcxproj.filters
core/frame/composite_gpu_frame.cpp
core/frame/gpu_frame.cpp
core/frame/gpu_frame.h
core/frame/gpu_frame_processor.cpp
core/producer/ffmpeg/audio/audio_decoder.cpp
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/input.cpp
core/producer/ffmpeg/video/video_deinterlacer.cpp
core/producer/ffmpeg/video/video_transformer.cpp [deleted file]
core/producer/flash/flash_producer.cpp
core/producer/image/image_loader.cpp
core/producer/image/image_producer.cpp
core/producer/image/image_scroll_producer.cpp
core/producer/transition/transition_producer.cpp
core/renderer/render_device.cpp
core/server.cpp
test/test.cpp [new file with mode: 0644]
test/test.vcxproj [new file with mode: 0644]
test/test.vcxproj.filters [new file with mode: 0644]
test/timer.h [new file with mode: 0644]

index 554d62a1128ffb8e37df575b8e5a4aa506fc97e8..b22b6f99646c685e32205a7ba6b8c0fc8ac37e66 100644 (file)
@@ -5,6 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcx
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "core\core.vcxproj", "{79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}"\r
 EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{CE1CD805-3904-4E58-824E-09C027585991}"\r
+EndProject\r
 Global\r
        GlobalSection(SubversionScc) = preSolution\r
                Svn-Managed = True\r
@@ -23,6 +25,10 @@ Global
                {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Debug|Win32.Build.0 = Debug|Win32\r
                {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Release|Win32.ActiveCfg = Release|Win32\r
                {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD}.Release|Win32.Build.0 = Release|Win32\r
+               {CE1CD805-3904-4E58-824E-09C027585991}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {CE1CD805-3904-4E58-824E-09C027585991}.Debug|Win32.Build.0 = Debug|Win32\r
+               {CE1CD805-3904-4E58-824E-09C027585991}.Release|Win32.ActiveCfg = Release|Win32\r
+               {CE1CD805-3904-4E58-824E-09C027585991}.Release|Win32.Build.0 = Release|Win32\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
index ac4fdb01ce4e0067e16677ca2c3359f826f86780..04dea56171715804eb76ddcc8d28bc49abcd3c8f 100644 (file)
@@ -80,6 +80,8 @@
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
       <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
+      <WholeProgramOptimization>false</WholeProgramOptimization>\r
+      <TreatWarningAsError>true</TreatWarningAsError>\r
     </ClCompile>\r
     <Link>\r
       <SubSystem>Windows</SubSystem>\r
     <ClInclude Include="exception\exceptions.h" />\r
     <ClInclude Include="exception\win32_exception.h" />\r
     <ClInclude Include="gl\utility.h" />\r
-    <ClInclude Include="hardware\cpuid.h" />\r
-    <ClInclude Include="image\clear.h" />\r
-    <ClInclude Include="image\copy.h" />\r
-    <ClInclude Include="image\copy_field.h" />\r
-    <ClInclude Include="image\image.h" />\r
     <ClInclude Include="io\AsyncEventServer.h" />\r
     <ClInclude Include="io\ClientInfo.h" />\r
     <ClInclude Include="io\ProtocolStrategy.h" />\r
-    <ClInclude Include="io\SerialPort.h" />\r
     <ClInclude Include="io\SocketInfo.h" />\r
     <ClInclude Include="log\log.h" />\r
     <ClInclude Include="stdafx.h" />\r
     <ClInclude Include="utility\find_file.h" />\r
+    <ClInclude Include="utility\memory.h" />\r
     <ClInclude Include="utility\scope_exit.h" />\r
     <ClInclude Include="utility\string_convert.h" />\r
-    <ClInclude Include="utility\types.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="concurrency\Thread.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="hardware\cpuid.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="image\clear.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="image\copy.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="image\copy_field.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="image\image.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
     </ClCompile>\r
-    <ClCompile Include="io\SerialPort.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\SocketInfo.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="utility\memory.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
index 8f605d951d2c94f5b1f0fba04b027385a337be9e..e4ab23a71320d5932dd193ed851002d66b6d0d0c 100644 (file)
@@ -11,9 +11,6 @@
     <Filter Include="Source\exception">\r
       <UniqueIdentifier>{35ca385e-c4db-4fe7-858b-0a0bb678675f}</UniqueIdentifier>\r
     </Filter>\r
-    <Filter Include="Source\image">\r
-      <UniqueIdentifier>{77be36fb-d4c0-415c-a5be-2cbec333ecbc}</UniqueIdentifier>\r
-    </Filter>\r
     <Filter Include="Source\io">\r
       <UniqueIdentifier>{f4b0d63f-3cb3-4ab4-a6b9-3f249204dd3f}</UniqueIdentifier>\r
     </Filter>\r
@@ -23,9 +20,6 @@
     <Filter Include="Source\utility">\r
       <UniqueIdentifier>{11860e2d-8adf-4573-956b-785e59aef2b0}</UniqueIdentifier>\r
     </Filter>\r
-    <Filter Include="Source\hardware">\r
-      <UniqueIdentifier>{5115d125-61f1-4fdd-9924-0f1bdced5d27}</UniqueIdentifier>\r
-    </Filter>\r
     <Filter Include="Source\gl">\r
       <UniqueIdentifier>{0d94bbc2-e196-4618-a90b-19392a3a0a8e}</UniqueIdentifier>\r
     </Filter>\r
     <ClCompile Include="log\log.cpp">\r
       <Filter>Source\log</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="io\SerialPort.cpp">\r
-      <Filter>Source\io</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="io\SocketInfo.cpp">\r
       <Filter>Source\io</Filter>\r
     </ClCompile>\r
     <ClCompile Include="io\AsyncEventServer.cpp">\r
       <Filter>Source\io</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="image\copy_field.cpp">\r
-      <Filter>Source\image</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="image\image.cpp">\r
-      <Filter>Source\image</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="image\clear.cpp">\r
-      <Filter>Source\image</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="image\copy.cpp">\r
-      <Filter>Source\image</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="exception\win32_exception.cpp">\r
       <Filter>Source\exception</Filter>\r
     </ClCompile>\r
     <ClCompile Include="concurrency\Thread.cpp">\r
       <Filter>Source\concurrency</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="hardware\cpuid.cpp">\r
-      <Filter>Source\hardware</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="utility\find_file.cpp">\r
       <Filter>Source\utility</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="utility\memory.cpp">\r
+      <Filter>Source\utility</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="stdafx.h">\r
     <ClInclude Include="io\ProtocolStrategy.h">\r
       <Filter>Source\io</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="io\SerialPort.h">\r
-      <Filter>Source\io</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="io\SocketInfo.h">\r
       <Filter>Source\io</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="image\copy.h">\r
-      <Filter>Source\image</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="image\copy_field.h">\r
-      <Filter>Source\image</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="image\image.h">\r
-      <Filter>Source\image</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="image\clear.h">\r
-      <Filter>Source\image</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="exception\exceptions.h">\r
       <Filter>Source\exception</Filter>\r
     </ClInclude>\r
     <ClInclude Include="config.h">\r
       <Filter>Source</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="hardware\cpuid.h">\r
-      <Filter>Source\hardware</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="utility\string_convert.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="utility\types.h">\r
-      <Filter>Source\utility</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="utility\scope_exit.h">\r
       <Filter>Source\utility</Filter>\r
     </ClInclude>\r
     <ClInclude Include="gl\utility.h">\r
       <Filter>Source\gl</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="utility\memory.h">\r
+      <Filter>Source\utility</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 18127c772381af9033a1b5a309bb127fe6c95074..929f649089580edba6a27e35e61e2e8578a751c2 100644 (file)
@@ -15,7 +15,11 @@ typedef boost::error_info<struct tag_msg_info, std::string> msg_info;
 typedef boost::error_info<struct tag_inner_info, std::exception_ptr> inner_info;\r
 typedef boost::error_info<struct tag_line_info, int> line_info;\r
 \r
-struct caspar_exception                        : virtual boost::exception, virtual std::exception {};\r
+struct caspar_exception                        : virtual boost::exception, virtual std::exception \r
+{\r
+       caspar_exception(){}\r
+       explicit caspar_exception(const char* msg) : std::exception(msg) {}\r
+};\r
 \r
 struct io_error                                        : virtual caspar_exception {};\r
 struct directory_not_found             : virtual io_error {};\r
diff --git a/common/hardware/cpuid.cpp b/common/hardware/cpuid.cpp
deleted file mode 100644 (file)
index 1b6eec0..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-\r
-#include "../stdafx.h"\r
-\r
-#include "cpuid.h"\r
-\r
-#include <intrin.h>\r
-\r
-#include <string>\r
-\r
-namespace caspar { namespace common {\r
-\r
-cpuid::cpuid() : \r
-       FPU(0), VME(0), DE(0), PSE(0), TSC(0),  MSR(0), PAE(0), MCE(0), CX8(0), APIC(0), SEP(0),  MTRR(0),      \r
-       PGE(0), MCA(0), CMOV(0), PAT(0), PSE_36(0),     PSN(0), CLFSH(0), DS(0), ACPI(0), MMX(0), FXSR(0),\r
-       SSE(0), SSE2(0),SSE3(0),SSSE3(0), SSE4_1(0), SSE4_2(0), SSE5(0), SS(0), HTT(0), TM(0),  \r
-       IA_64(0),Family(0),     Model(0), ModelEx(0), Stepping(0), FamilyEx(0), Brand(0), Type(0)\r
-{              \r
-       int CPUInfo[4] = {-1};\r
-       __cpuid(CPUInfo, 0);    \r
-\r
-       int nIds = CPUInfo[0];\r
-       std::string ID;\r
-       ID.append(reinterpret_cast<char*>(&CPUInfo[1]), 4);\r
-       ID.append(reinterpret_cast<char*>(&CPUInfo[3]), 4);\r
-       ID.append(reinterpret_cast<char*>(&CPUInfo[2]), 4);\r
-\r
-       for (int i = 0; i <= nIds; ++i)\r
-       {\r
-               __cpuid(CPUInfo, i);\r
-\r
-               if  (i == 1)\r
-               {\r
-                       Stepping =      (CPUInfo[0]      ) & 0x0F;\r
-                       Model =         (CPUInfo[0] >> 4 ) & 0x0F;\r
-                       Family =        (CPUInfo[0] >> 8 ) & 0x0F;\r
-                       Type =          (CPUInfo[0] >> 12) & 0x03;\r
-                       ModelEx =       (CPUInfo[0] >> 16) & 0x0F;\r
-                       FamilyEx =      (CPUInfo[0] >> 20) & 0xFF;\r
-                       Brand =         (CPUInfo[1]              ) & 0xFF;                      \r
-\r
-                       if(ID == "GenuineIntel") \r
-                       {\r
-                               FPU             = (CPUInfo[3] & (1 << 0))  != 0;\r
-                               VME             = (CPUInfo[3] & (1 << 1))  != 0;\r
-                               DE              = (CPUInfo[3] & (1 << 2))  != 0;\r
-                               PSE             = (CPUInfo[3] & (1 << 3))  != 0;\r
-                               TSC             = (CPUInfo[3] & (1 << 4))  != 0;\r
-                               MSR             = (CPUInfo[3] & (1 << 5))  != 0;\r
-                               PAE             = (CPUInfo[3] & (1 << 6))  != 0;\r
-                               MCE             = (CPUInfo[3] & (1 << 7))  != 0;\r
-                               CX8             = (CPUInfo[3] & (1 << 8))  != 0;\r
-                               APIC    = (CPUInfo[3] & (1 << 9))  != 0;\r
-                               //              = (CPUInfo[3] & (1 << 10)) != 0;\r
-                               SEP             = (CPUInfo[3] & (1 << 11)) != 0;\r
-                               MTRR    = (CPUInfo[3] & (1 << 12)) != 0;\r
-                               PGE             = (CPUInfo[3] & (1 << 13)) != 0;\r
-                               MCA             = (CPUInfo[3] & (1 << 14)) != 0;\r
-                               CMOV    = (CPUInfo[3] & (1 << 15)) != 0;\r
-                               PAT             = (CPUInfo[3] & (1 << 16)) != 0;\r
-                               PSE_36  = (CPUInfo[3] & (1 << 17)) != 0;\r
-                               PSN             = (CPUInfo[3] & (1 << 18)) != 0;\r
-                               CLFSH   = (CPUInfo[3] & (1 << 19)) != 0;\r
-                               //              = (CPUInfo[3] & (1 << 20)) != 0;\r
-                               DS              = (CPUInfo[3] & (1 << 21)) != 0;\r
-                               ACPI    = (CPUInfo[3] & (1 << 22)) != 0;\r
-                               MMX             = (CPUInfo[3] & (1 << 23)) != 0;\r
-                               FXSR    = (CPUInfo[3] & (1 << 24)) != 0;\r
-                               SSE             = (CPUInfo[3] & (1 << 25)) != 0;\r
-                               SSE2    = (CPUInfo[3] & (1 << 26)) != 0;\r
-                               SS              = (CPUInfo[3] & (1 << 27)) != 0;\r
-                               HTT             = (CPUInfo[3] & (1 << 28)) != 0;\r
-                               TM              = (CPUInfo[3] & (1 << 29)) != 0;\r
-                               //              = (CPUInfo[3] & (1 << 30)) != 0;\r
-                               IA_64   = (CPUInfo[3] & (1 << 31)) != 0;\r
-\r
-                               SSE3    = (CPUInfo[2] & (1 << 0))  != 0;\r
-                               SSSE3   = (CPUInfo[2] & (1 << 9))  != 0;\r
-                               SSE4_1  = (CPUInfo[2] & (1 << 19)) != 0;\r
-                               SSE4_2  = (CPUInfo[2] & (1 << 20)) != 0;\r
-                       }\r
-                       else if(ID == "AuthenticAMD") \r
-                       {\r
-                       }\r
-               }\r
-       }       \r
-\r
-       if(SSE5)\r
-               SIMD = common::SSE5;\r
-       else if(SSE4_2)\r
-               SIMD = common::SSE4_2;\r
-       else if(SSE4_1)\r
-               SIMD = common::SSE4_1;\r
-       else if(SSSE3)\r
-               SIMD = common::SSSE3;\r
-       else if(SSE3)\r
-               SIMD = common::SSE3;\r
-       else if(SSE2)\r
-               SIMD = common::SSE2;\r
-       else if(SSE)\r
-               SIMD = common::SSE;\r
-       else \r
-               SIMD = common::REF;\r
-}\r
-\r
-}\r
-}\r
diff --git a/common/hardware/cpuid.h b/common/hardware/cpuid.h
deleted file mode 100644 (file)
index 3fe22d6..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-\r
-#pragma once\r
-\r
-namespace caspar { namespace common {\r
-\r
-enum SIMD\r
-{\r
-       AUTO,\r
-       REF,\r
-       SSE,\r
-       SSE2,\r
-       SSE3,\r
-       SSSE3,\r
-       SSE4_1,\r
-       SSE4_2,\r
-       SSE5\r
-};\r
-\r
-struct cpuid\r
-{\r
-       cpuid();\r
-\r
-       bool FPU;               //Floating Point Unit\r
-       bool VME;               //Virtual Mode Extension\r
-       bool DE;                //Debugging Extension\r
-       bool PSE;               //Page Size Extension\r
-       bool TSC;               //Time Stamp Counter\r
-       bool MSR;               //Model Specific Registers\r
-       bool PAE;               //Physical Address Extesnion\r
-       bool MCE;               //Machine Check Extension\r
-       bool CX8;               //CMPXCHG8 Instruction\r
-       bool APIC;              //On-chip APIC Hardware\r
-       bool SEP;               //SYSENTER SYSEXIT\r
-       bool MTRR;              //Machine Type Range Registers\r
-       bool PGE;               //Global Paging Extension\r
-       bool MCA;               //Machine Check Architecture\r
-       bool CMOV;              //Conditional Move Instrction\r
-       bool PAT;               //Page Attribute Table\r
-       bool PSE_36;    //36-bit Page Size Extension\r
-       bool PSN;               //96-bit Processor Serial Number\r
-       bool CLFSH;             //CLFLUSH Instruction\r
-       bool DS;                //Debug Trace Store\r
-       bool ACPI;              //ACPI Support\r
-       bool MMX;               //MMX Technology\r
-       bool FXSR;              //FXSAVE FXRSTOR (Fast save and restore)\r
-       bool SSE;               //Streaming SIMD Extensions\r
-       bool SSE2;              //Streaming SIMD Extensions 2\r
-       bool SSE3;\r
-       bool SSSE3; \r
-       bool SSE4_1;\r
-       bool SSE4_2;\r
-       bool SSE5;\r
-       bool SS;                //Self-Snoop\r
-       bool HTT;               //Hyper-Threading Technology\r
-       bool TM;                //Thermal Monitor Supported\r
-       bool IA_64;             //IA-64 capable \r
-\r
-       int Family;\r
-       int Model;\r
-       int ModelEx;\r
-       int Stepping;\r
-       int FamilyEx;\r
-       int Brand; \r
-       int Type;\r
-\r
-       SIMD SIMD;\r
-\r
-       //int CacheLineSize;\r
-       //int LogicalProcessorCount;\r
-       //int LocalAPICID;\r
-\r
-};\r
-\r
-}\r
-}
\ No newline at end of file
diff --git a/common/image/clear.cpp b/common/image/clear.cpp
deleted file mode 100644 (file)
index d046e2c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "../stdafx.h"\r
-\r
-#include "clear.h"\r
-\r
-#include <intrin.h>\r
-#include <functional>\r
-\r
-#include "../utility/types.h"\r
-\r
-#include "tbb/parallel_for.h"\r
-#include "tbb/blocked_range.h"\r
-\r
-using namespace std::tr1::placeholders;\r
-\r
-namespace caspar{\r
-namespace common{\r
-namespace image{\r
-\r
-static const size_t STRIDE = sizeof(__m128i)*4;\r
-\r
-void DoclearParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, size_t)>& func, void* dest)\r
-{\r
-       size_t offset = r.begin()*STRIDE;\r
-       size_t size = r.size()*STRIDE;\r
-       func(reinterpret_cast<s8*>(dest) + offset, size);\r
-}\r
-\r
-void clearParallel(const std::tr1::function<void(void*, size_t)>& func, void* dest, size_t size)\r
-{\r
-       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::bind(&DoclearParallel, std::placeholders::_1, func, dest));  \r
-}\r
-\r
-clear_fun get_clear_fun(SIMD simd)\r
-{\r
-       if(simd >= SSE2)\r
-               return clearParallel_SSE2;\r
-       else\r
-               return clearParallel_REF;\r
-}\r
-\r
-// TODO: (R.N) optimize => prefetch and cacheline loop unroll\r
-void clear_SSE2(void* dest, size_t size)\r
-{\r
-       __m128i val = _mm_setzero_si128();\r
-       __m128i* ptr = reinterpret_cast<__m128i*>(dest);\r
-\r
-       int times = size / 16;\r
-       for(int i=0; i < times; ++i) \r
-       {\r
-               _mm_stream_si128(ptr, val);\r
-               ptr++;\r
-       }\r
-}\r
-\r
-void clearParallel_SSE2(void* dest, size_t size)\r
-{\r
-       clearParallel(&clear_SSE2, dest, size);\r
-}\r
-\r
-void clear_REF(void* dest, size_t size)\r
-{\r
-       __stosd(reinterpret_cast<unsigned long*>(dest), 0, size/4);\r
-}\r
-\r
-void clearParallel_REF(void* dest, size_t size)\r
-{\r
-       clearParallel(&clear_REF, dest, size);\r
-}\r
-\r
-}\r
-}\r
-}
\ No newline at end of file
diff --git a/common/image/copy.cpp b/common/image/copy.cpp
deleted file mode 100644 (file)
index 7214ad9..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "../stdafx.h"\r
-\r
-#include "copy.h"\r
-\r
-#include <intrin.h>\r
-#include <functional>\r
-\r
-#include "../utility/types.h"\r
-\r
-#include "tbb/parallel_for.h"\r
-#include "tbb/blocked_range.h"\r
-\r
-using namespace std::tr1::placeholders;\r
-\r
-namespace caspar{\r
-namespace common{\r
-namespace image{\r
-\r
-static const size_t STRIDE = sizeof(__m128i)*4;\r
-\r
-void DocopyParallel(const tbb::blocked_range<size_t>& r, const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source)\r
-{\r
-       size_t offset = r.begin()*STRIDE;\r
-       size_t size = r.size()*STRIDE;\r
-       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size);\r
-}\r
-\r
-void copyParallel(const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t size)\r
-{\r
-       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/STRIDE), std::bind(&DocopyParallel, std::placeholders::_1, func, dest, source));   \r
-}\r
-\r
-copy_fun get_copy_fun(SIMD simd)\r
-{\r
-       if(simd >= SSE2)\r
-               return copyParallel_SSE2;\r
-       else\r
-               return copyParallel_REF;\r
-}\r
-\r
-// TODO: (R.N) optimize => prefetch and cacheline loop unroll\r
-void copy_SSE2(void* dest, const void* source, size_t size)\r
-{\r
-       __m128i val = _mm_setzero_si128();\r
-       __m128i* pD = reinterpret_cast<__m128i*>(dest);\r
-       const __m128i* pS = reinterpret_cast<const __m128i*>(source);\r
-\r
-       int times = size / 16;\r
-       for(int i=0; i < times; ++i) \r
-       {\r
-               val = _mm_load_si128(pS);\r
-               _mm_stream_si128(pD, val);\r
-\r
-               ++pD;\r
-               ++pS;\r
-       }\r
-       _mm_mfence();   //ensure last WC buffers get flushed to memory\r
-}\r
-\r
-void copyParallel_SSE2(void* dest, const void* source, size_t size)\r
-{\r
-       copyParallel(&copy_SSE2, dest, source, size);\r
-}\r
-\r
-void copy_REF(void* dest, const void* source, size_t size)\r
-{\r
-       __movsd(reinterpret_cast<unsigned long*>(dest), reinterpret_cast<const unsigned long*>(source), size/4);\r
-}\r
-\r
-void copyParallel_REF(void* dest, const void* source, size_t size)\r
-{\r
-       copyParallel(&copy_REF, dest, source, size);\r
-}\r
-\r
-}\r
-}\r
-}
\ No newline at end of file
diff --git a/common/image/copy_field.cpp b/common/image/copy_field.cpp
deleted file mode 100644 (file)
index 785fbff..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "../stdafx.h"\r
-\r
-#include "copy_field.h"\r
-#include "copy.h"\r
-\r
-#include <intrin.h>\r
-#include <functional>\r
-\r
-#include "../utility/types.h"\r
-\r
-#include "tbb/parallel_for.h"\r
-#include "tbb/blocked_range.h"\r
-\r
-using namespace std::tr1::placeholders; \r
-\r
-namespace caspar{ namespace common{ namespace image{\r
-\r
-void Docopy_fieldParallel(size_t index, const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t width4)\r
-{\r
-       size_t offset = index*width4;\r
-       size_t size = width4;\r
-       func(reinterpret_cast<s8*>(dest) + offset, reinterpret_cast<const s8*>(source) + offset, size);\r
-}\r
-\r
-void copy_fieldParallel(const std::tr1::function<void(void*, const void*, size_t)>& func, void* dest, const void* source, size_t fieldIndex, size_t width, size_t height)\r
-{\r
-       tbb::parallel_for(fieldIndex, height, static_cast<size_t>(2), std::bind(&Docopy_fieldParallel, std::placeholders::_1, func, dest, source, width*4)); // copy for each row\r
-}\r
-\r
-copy_field_fun get_copy_field_fun(SIMD /*simd*/)\r
-{\r
-       //if(simd >= SSE2)\r
-       //      return copy_fieldParallel_SSE2;\r
-       //else\r
-       return copy_fieldParallel_REF; // REF is faster\r
-}\r
-\r
-void copy_fieldParallel_SSE2(unsigned char* dest, const unsigned char* source, size_t fieldIndex, size_t width, size_t height)\r
-{\r
-       copy_fieldParallel(&copy_SSE2, dest, source, fieldIndex, width, height);\r
-}\r
-\r
-void copy_field_REF(unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height)\r
-{\r
-       for(size_t rowIndex=fieldIndex; rowIndex < height; rowIndex+=2) \r
-       {\r
-               int offset = width*4*rowIndex;\r
-               __movsd(reinterpret_cast<unsigned long*>(&(pDest[offset])), reinterpret_cast<const unsigned long*>(&(pSrc[offset])), width);\r
-       }\r
-}\r
-\r
-void copy_fieldParallel_REF(unsigned char* dest, const unsigned char* source, size_t fieldIndex, size_t width, size_t height)\r
-{\r
-       copy_fieldParallel(&copy_REF, dest, source, fieldIndex, width, height);\r
-}\r
-\r
-}}}
\ No newline at end of file
diff --git a/common/image/copy_field.h b/common/image/copy_field.h
deleted file mode 100644 (file)
index 6384552..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#pragma once\r
-\r
-#include "../hardware/cpuid.h"\r
-\r
-namespace caspar{ namespace common{ namespace image{\r
-       \r
-void copy_field_SSE2    (unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-void copy_field_REF     (unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-\r
-void copy_fieldParallel_SSE2    (unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-void copy_fieldParallel_REF     (unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-\r
-typedef void(*copy_field_fun)(unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-copy_field_fun get_copy_field_fun(SIMD simd = REF);\r
-\r
-}}} \r
-\r
-\r
diff --git a/common/image/image.cpp b/common/image/image.cpp
deleted file mode 100644 (file)
index 4bcdb01..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "../stdafx.h"\r
-\r
-#include "image.h"\r
-\r
-#include "copy.h"\r
-#include "copy_field.h"\r
-#include "clear.h"\r
-//#include "Transition.hpp"\r
-\r
-namespace caspar{ namespace common{ namespace image{\r
-\r
-namespace detail\r
-{\r
-       cpuid my_cpuid;\r
-       copy_fun                        copy = get_copy_fun(my_cpuid.SIMD);\r
-       copy_field_fun          copy_field = get_copy_field_fun(my_cpuid.SIMD);\r
-       clear_fun                       clear = get_clear_fun(my_cpuid.SIMD);\r
-}\r
-\r
-void copy(void* dest, const void* source, size_t size)\r
-{\r
-       (*detail::copy)(dest, source, size);\r
-}\r
-\r
-void copy_field(unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height)\r
-{\r
-       (*detail::copy_field)(pDest, pSrc, fieldIndex, width, height);\r
-}\r
-\r
-void clear(void* dest, size_t size)\r
-{\r
-       (*detail::clear)(dest, size);\r
-}\r
-\r
-}}}
\ No newline at end of file
diff --git a/common/image/image.h b/common/image/image.h
deleted file mode 100644 (file)
index d97a4ed..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#pragma once\r
-\r
-#include "../utility/types.h"\r
-#include "../hardware/cpuid.h"\r
-\r
-namespace caspar{ namespace common{ namespace image{   \r
-       \r
-void set_version(SIMD simd = AUTO);\r
-\r
-void copy(void* dest, const void* source, size_t size);\r
-void clear(void* dest, size_t size);\r
-void copy_field(unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-\r
-namespace detail\r
-{\r
-       typedef void(*copy_fun)(void*, const void*, size_t);\r
-       typedef void(*copy_field_fun)(unsigned char* pDest, const unsigned char* pSrc, size_t fieldIndex, size_t width, size_t height);\r
-       typedef void(*clear_fun)(void*, size_t);\r
-       \r
-       extern copy_fun                 copy;\r
-       extern copy_field_fun   copy_field;\r
-       extern clear_fun                clear;\r
-}\r
-\r
-}}}
\ No newline at end of file
diff --git a/common/utility/memory.cpp b/common/utility/memory.cpp
new file mode 100644 (file)
index 0000000..c33dbef
--- /dev/null
@@ -0,0 +1,84 @@
+#include "../stdafx.h"\r
+\r
+#include "memory.h"\r
+\r
+#include <intrin.h>\r
+\r
+#include <tbb/parallel_for.h>\r
+#include <tbb/blocked_range.h>\r
+\r
+namespace caspar { namespace common {\r
+       \r
+void* memcpy_SSE2(void* dest, const void* source, size_t num)\r
+{      \r
+       assert(dest != nullptr);\r
+       assert(source != nullptr);\r
+       assert(dest != source);\r
+       assert(num % 256 == 0);\r
+       __asm\r
+       {\r
+               mov esi, source;    \r
+               mov edi, dest;   \r
\r
+               mov ebx, num; \r
+               shr ebx, 7;      \r
+  \r
+               cpy:\r
+                       prefetchnta [esi+80h];\r
\r
+                       movdqa xmm0, [esi+00h];\r
+                       movdqa xmm1, [esi+10h];\r
+                       movdqa xmm2, [esi+20h];\r
+                       movdqa xmm3, [esi+30h];\r
+         \r
+                       movntdq [edi+00h], xmm0;\r
+                       movntdq [edi+10h], xmm1;\r
+                       movntdq [edi+20h], xmm2;\r
+                       movntdq [edi+30h], xmm3;\r
+                       \r
+                       prefetchnta [esi+0C0h];\r
+                       \r
+                       movdqa xmm4, [esi+40h];\r
+                       movdqa xmm5, [esi+50h];\r
+                       movdqa xmm6, [esi+60h];\r
+                       movdqa xmm7, [esi+70h];\r
+         \r
+                       movntdq [edi+40h], xmm4;\r
+                       movntdq [edi+50h], xmm5;\r
+                       movntdq [edi+60h], xmm6;\r
+                       movntdq [edi+70h], xmm7;\r
\r
+                       lea edi, [edi+80h];\r
+                       lea esi, [esi+80h];\r
+                       dec ebx;\r
\r
+               jnz cpy;\r
+       }\r
+       return dest;\r
+}\r
+\r
+void* copy(void* dest, const void* source, size_t num)\r
+{      \r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, num/128), [&](const tbb::blocked_range<size_t>& r)\r
+       {\r
+               memcpy_SSE2(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128);\r
+       }, tbb::affinity_partitioner());\r
+\r
+       return dest;\r
+}\r
+\r
+void* clear(void* dest, size_t size)\r
+{\r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, size/16), [&](const tbb::blocked_range<size_t>& r)\r
+       {\r
+               __m128i val = _mm_setzero_si128();\r
+               __m128i* ptr = reinterpret_cast<__m128i*>(dest)+r.begin();\r
+               __m128i* end = ptr + r.size();\r
+\r
+               while(ptr != end)       \r
+                       _mm_stream_si128(ptr++, val);\r
+       });     \r
+       return dest;\r
+}\r
+\r
+}}
\ No newline at end of file
diff --git a/common/utility/memory.h b/common/utility/memory.h
new file mode 100644 (file)
index 0000000..6c9b767
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once\r
+\r
+namespace caspar { namespace common {\r
+               \r
+void* copy(void* dest, const void* source, size_t size);\r
+void* clear(void* dest, size_t size);\r
+\r
+}}
\ No newline at end of file
index ebd79ce2fb688730354856318de22e70eb859be4..7d68813ba2e14aa6baedd7dcedd341974d1db28a 100644 (file)
     <channel>\r
       <videomode>PAL</videomode>\r
       <consumers>\r
-        <ogl>\r
+        <!--ogl>\r
           <device>0</device>\r
           <stretch>uniform</stretch>\r
           <windowed>true</windowed>\r
         </ogl>\r
-        <audio/>\r
+        <audio/-->\r
+        <bluefish>\r
+          <device>1</device> \r
+          <embedded-audio>true</embedded-audio>\r
+        </bluefish>\r
       </consumers>\r
     </channel>\r
        </channels>\r
index a9705eaaafb563d89d4fcf3468464d4ed45719f9..64d1694722fd67e5c20308505826289b0a5e676c 100644 (file)
@@ -20,4 +20,4 @@
 \r
 #define TBB_USE_THREADING_TOOLS 1\r
 \r
-#define DISABLE_BLUEFISH\r
+//#define DISABLE_BLUEFISH\r
diff --git a/core/consumer/bluefish/BlueFishVideoConsumer.cpp b/core/consumer/bluefish/BlueFishVideoConsumer.cpp
deleted file mode 100644 (file)
index 1c02aea..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "..\..\StdAfx.h"\r
-\r
-#ifndef DISABLE_BLUEFISH\r
-\r
-#include <BlueVelvet4.h>\r
-#include "BlueFishVideoConsumer.h"\r
-#include "BluefishPlaybackStrategy.h"\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (push, 1) // TODO: Legacy code, just disable warnings\r
-#endif\r
-\r
-namespace caspar {\r
-namespace bluefish {\r
-\r
-///////////////////////////////////////////\r
-// BlueFishVideoConsumer::EnumerateDevices\r
-// RETURNS: Number of identified bluefish-cards\r
-int BlueFishVideoConsumer::EnumerateDevices()\r
-{\r
-       CASPAR_LOG(info) << "Bleufhsi SDK version: " << BlueVelvetVersion;\r
-       BlueVelvetPtr pSDK(BlueVelvetFactory4());\r
-\r
-       if(pSDK != 0) {\r
-               int deviceCount = 0;\r
-               pSDK->device_enumerate(deviceCount);\r
-               return deviceCount;\r
-       }\r
-       else\r
-               return 0;\r
-}\r
-\r
-\r
-///////////////////////////////////////////\r
-// BlueFishVideoConsumer::Create\r
-// PARAMS: deviceIndex(index of the card that is to be wrapped in a consumer)\r
-// RETURNS: a new BlueFishVideoConsumer-object for the specified card\r
-// COMMENT: Creates and initializes a consumer that outputs video to a bluefish-card\r
-frame_consumer_ptr BlueFishVideoConsumer::Create(const frame_format_desc& format_desc, unsigned int deviceIndex)\r
-{\r
-       BlueFishFrameConsumerPtr card(new BlueFishVideoConsumer(format_desc));\r
-       if(card != 0 && card->SetupDevice(deviceIndex) == false)\r
-               card.reset();\r
-\r
-       return card;\r
-}\r
-\r
-////////////////////////////////////////\r
-// BlueFishVideoConsumer constructor\r
-BlueFishVideoConsumer::BlueFishVideoConsumer(const frame_format_desc& format_desc) : format_desc_(format_desc), pSDK_(BlueVelvetFactory4()), currentFormat_(frame_format::pal), _deviceIndex(0), hasEmbeddedAudio_(false)\r
-{\r
-       frameBuffer_.set_capacity(1);\r
-       thread_ = boost::thread([=]{Run();});\r
-}\r
-\r
-////////////////////////////////////////\r
-// BlueFishVideoConsumer destructor\r
-BlueFishVideoConsumer::~BlueFishVideoConsumer()\r
-{\r
-       frameBuffer_.push(nullptr),\r
-       thread_.join();\r
-       ReleaseDevice();\r
-}\r
-\r
-/*******************/\r
-/**    METHODS    **/\r
-/*******************/\r
-\r
-unsigned long BlueFishVideoConsumer::VidFmtFromFrameFormat(frame_format fmt) \r
-{\r
-       switch(fmt)\r
-       {\r
-       case frame_format::pal:                 return VID_FMT_PAL;\r
-       case frame_format::ntsc:                return VID_FMT_NTSC;\r
-       case frame_format::x576p2500:   return ULONG_MAX;       //not supported\r
-       case frame_format::x720p5000:   return VID_FMT_720P_5000;\r
-       case frame_format::x720p5994:   return VID_FMT_720P_5994;\r
-       case frame_format::x720p6000:   return VID_FMT_720P_6000;\r
-       case frame_format::x1080p2397:  return VID_FMT_1080P_2397;\r
-       case frame_format::x1080p2400:  return VID_FMT_1080P_2400;\r
-       case frame_format::x1080i5000:  return VID_FMT_1080I_5000;\r
-       case frame_format::x1080i5994:  return VID_FMT_1080I_5994;\r
-       case frame_format::x1080i6000:  return VID_FMT_1080I_6000;\r
-       case frame_format::x1080p2500:  return VID_FMT_1080P_2500;\r
-       case frame_format::x1080p2997:  return VID_FMT_1080P_2997;\r
-       case frame_format::x1080p3000:  return VID_FMT_1080P_3000;\r
-       default:                                                return ULONG_MAX;\r
-       }\r
-}\r
-\r
-TCHAR* GetBluefishCardDesc(int cardType) \r
-{\r
-       switch(cardType) \r
-       {\r
-       case CRD_BLUEDEEP_LT:                           return TEXT("Deepblue LT"); // D64 Lite\r
-       case CRD_BLUEDEEP_SD:                           return TEXT("Iridium SD"); // Iridium SD\r
-       case CRD_BLUEDEEP_AV:                           return TEXT("Iridium AV"); // Iridium AV\r
-       case CRD_BLUEDEEP_IO:                           return TEXT("Deepblue IO"); // D64 Full\r
-       case CRD_BLUEWILD_AV:                           return TEXT("Wildblue AV"); // D64 AV\r
-       case CRD_IRIDIUM_HD:                            return TEXT("Iridium HD"); // * Iridium HD\r
-       case CRD_BLUEWILD_RT:                           return TEXT("Wildblue RT"); // D64 RT\r
-       case CRD_BLUEWILD_HD:                           return TEXT("Wildblue HD"); // * BadAss G2\r
-       case CRD_REDDEVIL:                                      return TEXT("Iridium Full"); // Iridium Full\r
-       case CRD_BLUEDEEP_HD:                                                                                                            // * BadAss G2 variant, proposed, reserved\r
-       case CRD_BLUEDEEP_HDS:                          return TEXT("Reserved for \"BasAss G2"); // * BadAss G2 variant, proposed, reserved\r
-       case CRD_BLUE_ENVY:                                     return TEXT("Blue envy"); // Mini Din \r
-       case CRD_BLUE_PRIDE:                            return TEXT("Blue pride"); //Mini Din Output \r
-       case CRD_BLUE_GREED:                            return TEXT("Blue greed");\r
-       case CRD_BLUE_INGEST:                           return TEXT("Blue ingest");\r
-       case CRD_BLUE_SD_DUALLINK:                      return TEXT("Blue SD duallink");\r
-       case CRD_BLUE_CATALYST:                         return TEXT("Blue catalyst");\r
-       case CRD_BLUE_SD_DUALLINK_PRO:          return TEXT("Blue SD duallink pro");\r
-       case CRD_BLUE_SD_INGEST_PRO:            return TEXT("Blue SD ingest pro");\r
-       case CRD_BLUE_SD_DEEPBLUE_LITE_PRO:     return TEXT("Blue SD deepblue lite pro");\r
-       case CRD_BLUE_SD_SINGLELINK_PRO:        return TEXT("Blue SD singlelink pro");\r
-       case CRD_BLUE_SD_IRIDIUM_AV_PRO:        return TEXT("Blue SD iridium AV pro");\r
-       case CRD_BLUE_SD_FIDELITY:                      return TEXT("Blue SD fidelity");\r
-       case CRD_BLUE_SD_FOCUS:                         return TEXT("Blue SD focus");\r
-       case CRD_BLUE_SD_PRIME:                         return TEXT("Blue SD prime");\r
-       case CRD_BLUE_EPOCH_2K_CORE:            return TEXT("Blue epoch 2k core");\r
-       case CRD_BLUE_EPOCH_2K_ULTRA:           return TEXT("Blue epoch 2k ultra");\r
-       case CRD_BLUE_EPOCH_HORIZON:            return TEXT("Blue epoch horizon");\r
-       case CRD_BLUE_EPOCH_CORE:                       return TEXT("Blue epoch core");\r
-       case CRD_BLUE_EPOCH_ULTRA:                      return TEXT("Blue epoch ultra");\r
-       case CRD_BLUE_CREATE_HD:                        return TEXT("Blue create HD");\r
-       case CRD_BLUE_CREATE_2K:                        return TEXT("Blue create 2k");\r
-       case CRD_BLUE_CREATE_2K_ULTRA:          return TEXT("Blue create 2k ultra");\r
-       default:                                                        return TEXT("Unknown");\r
-       }\r
-}\r
-\r
-bool BlueFishVideoConsumer::SetupDevice(unsigned int deviceIndex)\r
-{\r
-       return this->DoSetupDevice(deviceIndex);\r
-}\r
-\r
-/*\r
-// Original initialization code\r
-bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex, std::wstring strDesiredFrameFormat)\r
-{\r
-       _deviceIndex = deviceIndex;\r
-\r
-       unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL;\r
-       unsigned long desiredVideoFormat = VID_FMT_PAL;\r
-       int iDummy;\r
-\r
-       int bufferIndex=0;      //Bufferindex used when initializing the buffers\r
-\r
-       if(strDesiredFrameFormat.size() == 0)\r
-               strDesiredFrameFormat = TEXT("PAL");\r
-\r
-       frame_format casparVideoFormat = caspar::get_video_format(strDesiredFrameFormat);\r
-       desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(casparVideoFormat);\r
-       currentFormat_ = casparVideoFormat != FFormatInvalid ? casparVideoFormat : FFormatPAL;\r
-       if(desiredVideoFormat == ULONG_MAX) {\r
-               LOG << TEXT("BLUECARD ERROR: Unsupported videomode: ") << strDesiredFrameFormat << TEXT(". (device") << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) {\r
-               LOG << TEXT("BLUECARD ERROR: Failed to attach device") << _deviceIndex;\r
-               return false;\r
-       }\r
-\r
-       if(desiredVideoFormat != VID_FMT_PAL) {\r
-               int videoModeCount = pSDK_->count_video_mode();\r
-               for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) {\r
-                       EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex);\r
-                       if(videoMode == desiredVideoFormat) {\r
-                               vidFmt = videoMode;\r
-                       }\r
-               }\r
-       }\r
-\r
-       if(vidFmt == VID_FMT_PAL) {\r
-               strDesiredFrameFormat = TEXT("PAL");\r
-               currentFormat_ = FFormatPAL;\r
-       }\r
-\r
-       if(BLUE_FAIL(pSDK_->set_video_framestore_style(vidFmt, memFmt, updFmt, resFmt))) {\r
-               LOG << TEXT("BLUECARD ERROR: Failed to set videomode to ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       LOG << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-\r
-       if (pSDK_->has_output_key()) {\r
-               iDummy = TRUE;\r
-               int v4444 = FALSE, invert = FALSE, white = FALSE;\r
-               pSDK_->set_output_key(iDummy, v4444, invert, white);\r
-       }\r
-\r
-       if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) {\r
-               pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI);\r
-       }\r
-\r
-\r
-       iDummy = FALSE;\r
-       pSDK_->set_vertical_flip(iDummy);\r
-\r
-       // Get framestore parameters\r
-       if(BLUE_OK(pSDK_->render_buffer_sizeof(m_bufferCount, m_length, m_actual, m_golden))) {\r
-               LOG << TEXT("BLUECARD INFO: Buffers: ") << m_bufferCount << TEXT(", \"Length\": ") << m_length << TEXT(", Buffer size: ") << m_actual << TEXT(" (device ") << _deviceIndex << TEXT(")") << common::LogStream::Flush;\r
-       }\r
-       else {\r
-               LOG << TEXT("BLUECARD ERROR: Failed to get framestore parameters (device ") << _deviceIndex << TEXT(")");\r
-       }\r
-\r
-       pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, m_golden));\r
-\r
-       iDummy = TRUE;\r
-       pSDK_->set_output_video(iDummy);\r
-\r
-       // Now specify video output buffer\r
-       pSDK_->render_buffer_update(0);\r
-\r
-       pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new BluefishPlaybackStrategy(this))));\r
-       pPlaybackControl_->Start();\r
-\r
-       LOG << TEXT("BLUECARD INFO: Successfully initialized device ") << _deviceIndex;\r
-       return true;\r
-}\r
-*/\r
-\r
-//New, improved(?) initialization code. \r
-//Based on code sent from the bluefish-sdk support 2009-08-25. Email "RE: [sdk] Ang. RE: Issue with SD Lite Pro PCI-E"\r
-bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex)\r
-{\r
-       _deviceIndex = deviceIndex;\r
-\r
-       unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL, engineMode = VIDEO_ENGINE_FRAMESTORE;\r
-       unsigned long desiredVideoFormat = VID_FMT_PAL;\r
-       int iDummy;\r
-\r
-       int bufferIndex=0;      //Bufferindex used when initializing the buffers\r
-\r
-       if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to attach device. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       int videoCardType = pSDK_->has_video_cardtype();\r
-       CASPAR_LOG(info) << "BLUECARD INFO: Card type: " << GetBluefishCardDesc(videoCardType) << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-\r
-       desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(format_desc_.format);\r
-       currentFormat_ = format_desc_.format != frame_format::invalid ? format_desc_.format : frame_format::pal;\r
-       if(desiredVideoFormat == ULONG_MAX) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Unsupported videomode: " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       if(desiredVideoFormat != VID_FMT_PAL) {\r
-               int videoModeCount = pSDK_->count_video_mode();\r
-               for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) {\r
-                       EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex);\r
-                       if(videoMode == desiredVideoFormat) {\r
-                               vidFmt = videoMode;\r
-                       }\r
-               }\r
-       }\r
-\r
-       if(vidFmt != desiredVideoFormat) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set desired videomode: " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-       }\r
-\r
-       if(vidFmt == VID_FMT_PAL) {\r
-               currentFormat_ = frame_format::pal;\r
-               format_desc_ = frame_format_desc::format_descs[frame_format::pal];\r
-       }\r
-\r
-       DisableVideoOutput();\r
-\r
-       VARIANT value;\r
-       value.vt = VT_UI4;\r
-\r
-       //Enable dual link output\r
-       value.ulVal = 1;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to enable dual link. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       value.ulVal = Signal_FormatType_4224;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set dual link format type to 4:2:2:4. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       //Setting output Video mode\r
-       value.ulVal = vidFmt;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MODE, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set videomode. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       //Select Update Mode for output\r
-       value.ulVal = updFmt;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_UPDATE_TYPE, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set update type. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-       \r
-       //Select output memory format\r
-       value.ulVal = memFmt;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MEMORY_FORMAT, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set memory format. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       //SELECT IMAGE ORIENTATION\r
-       value.ulVal = ImageOrientation_Normal;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_IMAGE_ORIENTATION, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set image orientation to normal. (device " << _deviceIndex << TEXT(")");\r
-       }\r
-\r
-       value.ulVal = CGR_RANGE;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_RGB_DATA_RANGE, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set RGB data range to CGR. (device " << _deviceIndex << TEXT(")");\r
-       }\r
-\r
-       value.ulVal = MATRIX_709_CGR;\r
-       if(vidFmt == VID_FMT_PAL) {\r
-               value.ulVal = MATRIX_601_CGR;\r
-       }\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_PREDEFINED_COLOR_MATRIX, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set colormatrix to " << (vidFmt == VID_FMT_PAL ? TEXT("601 CGR") : TEXT("709 CGR")) << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-       }\r
-       \r
-\r
-       //Disable embedded audio\r
-       value.ulVal = 1;\r
-       if(!BLUE_PASS(pSDK_->SetCardProperty(EMBEDDED_AUDIO_OUTPUT, value))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to enable embedded audio. (device " << _deviceIndex << TEXT(")");\r
-       }\r
-       else {\r
-               CASPAR_LOG(info) << "BLUECARD INFO: Enabled embedded audio. (device " << _deviceIndex << TEXT(")");\r
-               hasEmbeddedAudio_ = true;\r
-       }\r
-\r
-       CASPAR_LOG(info) << "BLUECARD INFO: Successfully configured bluecard for " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")");\r
-\r
-       if (pSDK_->has_output_key()) {\r
-               iDummy = TRUE;\r
-               int v4444 = FALSE, invert = FALSE, white = FALSE;\r
-               pSDK_->set_output_key(iDummy, v4444, invert, white);\r
-       }\r
-\r
-       if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) {\r
-               pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI);\r
-       }\r
-\r
-       ULONG videoGolden = BlueVelvetGolden(vidFmt, memFmt, updFmt);\r
-\r
-       pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, videoGolden));\r
-\r
-       pPlayback_ = std::make_shared<BluefishPlaybackStrategy>(this);\r
-\r
-       if(BLUE_FAIL(pSDK_->set_video_engine(engineMode))) {\r
-               CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set vido engine. (device " << _deviceIndex << TEXT(")");\r
-               return false;\r
-       }\r
-\r
-       EnableVideoOutput();\r
-\r
-       CASPAR_LOG(info) << "BLUECARD INFO: Successfully initialized device " << _deviceIndex;\r
-       return true;\r
-}\r
-\r
-bool BlueFishVideoConsumer::ReleaseDevice()\r
-{\r
-       pPlayback_.reset();\r
-\r
-       pFrameManager_.reset();\r
-       DisableVideoOutput();\r
-\r
-       if(pSDK_) {\r
-               pSDK_->device_detach();\r
-       }\r
-\r
-       CASPAR_LOG(info) << "BLUECARD INFO: Successfully released device " << _deviceIndex;\r
-       return true;\r
-}\r
-\r
-void BlueFishVideoConsumer::EnableVideoOutput()\r
-{\r
-       //Need sync. protection?\r
-       if(pSDK_)\r
-       {\r
-               VARIANT value;\r
-               value.vt = VT_UI4;\r
-\r
-               //Deactivate channel\r
-               value.ulVal = 0;\r
-               if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) {\r
-                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << _deviceIndex << TEXT(")");\r
-               }\r
-       }\r
-}\r
-\r
-void BlueFishVideoConsumer::DisableVideoOutput()\r
-{\r
-       //Need sync. protection?\r
-       if(pSDK_)\r
-       {\r
-               VARIANT value;\r
-               value.vt = VT_UI4;\r
-\r
-               //Deactivate channel\r
-               value.ulVal = 1;\r
-               if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) {\r
-                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << _deviceIndex << TEXT(")");\r
-               }\r
-       }\r
-}\r
-\r
-void BlueFishVideoConsumer::display(const gpu_frame_ptr& frame)\r
-{\r
-       if(frame == nullptr)\r
-               return;\r
-\r
-       if(pException_ != nullptr)\r
-               std::rethrow_exception(pException_);\r
-\r
-       frameBuffer_.push(frame);\r
-}\r
-\r
-void BlueFishVideoConsumer::Run()\r
-{\r
-       while(true)\r
-       {\r
-               try\r
-               {\r
-                       gpu_frame_ptr frame;\r
-                       frameBuffer_.pop(frame);\r
-                       if(frame == nullptr)\r
-                               return;\r
-\r
-                       pPlayback_->display(frame);\r
-               }\r
-               catch(...)\r
-               {\r
-                       pException_ = std::current_exception();\r
-               }\r
-       }       \r
-}\r
-\r
-}}\r
-\r
-#endif
\ No newline at end of file
diff --git a/core/consumer/bluefish/BlueFishVideoConsumer.h b/core/consumer/bluefish/BlueFishVideoConsumer.h
deleted file mode 100644 (file)
index 88d53f4..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#pragma once\r
-\r
-#include "../../../common/concurrency/thread.h"\r
-#include "BluefishException.h"\r
-#include "BluefishFrameManager.h"\r
-#include "../../consumer/frame_consumer.h"\r
-#include "../../renderer/render_device.h"\r
-#include <tbb/concurrent_queue.h>\r
-#include <boost/thread.hpp>\r
-\r
-#define TIMEOUT                        1000\r
-\r
-class CBlueVelvet4;\r
-\r
-namespace caspar {\r
-       \r
-namespace bluefish {\r
-\r
-typedef std::tr1::shared_ptr<CBlueVelvet4> BlueVelvetPtr;\r
-\r
-class BlueFishVideoConsumer : public frame_consumer\r
-{\r
-       friend class BluefishPlaybackStrategy;\r
-\r
-       BlueFishVideoConsumer(const frame_format_desc& format_desc);\r
-       BlueFishVideoConsumer(const BlueFishVideoConsumer&);\r
-       const BlueFishVideoConsumer& operator=(const BlueFishVideoConsumer&);\r
-\r
-public:\r
-       virtual ~BlueFishVideoConsumer();\r
-\r
-       static int EnumerateDevices();\r
-       static frame_consumer_ptr Create(const frame_format_desc& format_desc, unsigned int deviceIndex);\r
-       \r
-       void display(const gpu_frame_ptr&);\r
-               \r
-       const frame_format_desc& get_frame_format_desc() const { return format_desc_; }\r
-\r
-private:\r
-\r
-       void Run();\r
-\r
-       void EnableVideoOutput();\r
-       void DisableVideoOutput();\r
-       bool SetupDevice(unsigned int deviceIndex);\r
-       bool ReleaseDevice();\r
-\r
-       bool DoSetupDevice(unsigned int deviceIndex);\r
-\r
-       BlueVelvetPtr pSDK_;\r
-       std::shared_ptr<BluefishPlaybackStrategy> pPlayback_;\r
-       BluefishFrameManagerPtr pFrameManager_;\r
-       unsigned long m_bufferCount;\r
-       unsigned long m_length;\r
-       unsigned long m_actual;\r
-       unsigned long m_golden;\r
-\r
-       unsigned long VidFmtFromFrameFormat(frame_format fmt);\r
-\r
-       frame_format currentFormat_;\r
-       unsigned int _deviceIndex;\r
-       bool hasEmbeddedAudio_;\r
-       frame_format_desc format_desc_;\r
-       \r
-       std::exception_ptr pException_;\r
-       boost::thread thread_;\r
-       tbb::concurrent_bounded_queue<gpu_frame_ptr> frameBuffer_;\r
-};\r
-typedef std::tr1::shared_ptr<BlueFishVideoConsumer> BlueFishFrameConsumerPtr;\r
-\r
-}}\r
diff --git a/core/consumer/bluefish/BluefishException.h b/core/consumer/bluefish/BluefishException.h
deleted file mode 100644 (file)
index 4ea18eb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#ifndef _CASPAR_BLUEFISHEXCEPTION_H__\r
-#define _CASPAR_BLUEFISHEXCEPTION_H__\r
-\r
-#include <exception>\r
-\r
-namespace caspar {\r
-namespace bluefish {\r
-\r
-class BluefishException : public std::exception\r
-{\r
-public:\r
-       explicit BluefishException(const char* msg) : std::exception(msg) {}\r
-       ~BluefishException() {}\r
-};\r
-\r
-}      //namespace bluefish\r
-}      //namespace caspar\r
-\r
-#endif //_CASPAR_BLUEFISHEXCEPTION_H__
\ No newline at end of file
diff --git a/core/consumer/bluefish/BluefishPlaybackStrategy.cpp b/core/consumer/bluefish/BluefishPlaybackStrategy.cpp
deleted file mode 100644 (file)
index 013b0ce..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-*  This file is part of CasparCG.\r
-*\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
-*\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
\r
-#include "../../StdAfx.h"\r
-\r
-#include "../../../common/image/image.h"\r
-#include <BlueVelvet4.h>\r
-#include <BlueHancUtils.h>\r
-\r
-#include <vector>\r
-\r
-#include "BluefishPlaybackStrategy.h"\r
-#include "BluefishVideoConsumer.h"\r
-\r
-namespace caspar { namespace bluefish {\r
-\r
-using namespace caspar::common;\r
-\r
-struct BluefishPlaybackStrategy::Implementation\r
-{\r
-       Implementation(BlueFishVideoConsumer* pConsumer) : pConsumer_(pConsumer), currentReservedFrameIndex_(0)\r
-       {\r
-               auto frame = pConsumer->pFrameManager_->CreateFrame();\r
-               if(frame != 0)\r
-                       reservedFrames_.push_back(frame);\r
-               else {\r
-                       throw std::exception("Failed to reserve temporary bluefishframe");\r
-               }\r
-               frame.reset();\r
-\r
-               frame = pConsumer->pFrameManager_->CreateFrame();\r
-               if(frame != 0)\r
-                       reservedFrames_.push_back(frame);\r
-               else {\r
-                       throw std::exception("Failed to reserve temporary bluefishframe");\r
-               }\r
-\r
-               memset(&hancStreamInfo_, 0, sizeof(hancStreamInfo_));\r
-       }\r
-       std::shared_ptr<BluefishVideoFrame> GetReservedFrame() {\r
-               std::shared_ptr<BluefishVideoFrame> frame = reservedFrames_[currentReservedFrameIndex_];\r
-               currentReservedFrameIndex_ ^= 1;\r
-               return frame;\r
-       }\r
-\r
-       void DisplayFrame(const gpu_frame_ptr& frame)\r
-       {\r
-               if(frame != nullptr) {\r
-                       if(pConsumer_->pFrameManager_.get() == reinterpret_cast<BluefishFrameManager*>(frame->tag())) {\r
-                               DoRender(std::static_pointer_cast<BluefishVideoFrame>(frame));\r
-                       }\r
-                       else {\r
-                               std::shared_ptr<BluefishVideoFrame> pTempFrame = reservedFrames_[currentReservedFrameIndex_];\r
-                               if(frame->size() == pTempFrame->size()) {\r
-                                       common::image::copy(pTempFrame->data(), frame->data(), pTempFrame->size());\r
-                                       DoRender(pTempFrame);\r
-                               }\r
-\r
-                               currentReservedFrameIndex_ ^= 1;\r
-                       }\r
-               }\r
-               else {\r
-                       CASPAR_LOG(error) << "BLUEFISH: Tried to render frame with no data";\r
-               }\r
-       }\r
-\r
-       void DoRender(const std::shared_ptr<BluefishVideoFrame>& frame) {\r
-               static bool doLog = true;\r
-               static int frameID = 0;\r
-               // video synch\r
-               unsigned long fieldCount = 0;\r
-               pConsumer_->pSDK_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
-\r
-               // Host->PCI in_Frame buffer to the card buffer\r
-               pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frame->meta_data(), 0);\r
-               if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frame->meta_data()))) {\r
-               /*pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frameID, 0);\r
-               if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frameID))) {*/\r
-                       if(doLog) {\r
-                               CASPAR_LOG(error) << "BLUEFISH: render_buffer_update failed";\r
-                               doLog = false;\r
-                       }\r
-               }\r
-               else\r
-                       doLog = true;\r
-\r
-               frameID = (frameID+1) & 3;\r
-       }\r
-\r
-       BlueFishVideoConsumer* pConsumer_;\r
-       std::vector<std::shared_ptr<BluefishVideoFrame>> reservedFrames_;\r
-       int currentReservedFrameIndex_;\r
-\r
-       hanc_stream_info_struct hancStreamInfo_;\r
-};\r
-\r
-BluefishPlaybackStrategy::BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer) : pImpl_(new Implementation(pConsumer)) \r
-{ }\r
-\r
-BluefishPlaybackStrategy::~BluefishPlaybackStrategy()\r
-{ }\r
-//\r
-//FrameConsumer* BluefishPlaybackStrategy::GetConsumer()\r
-//{\r
-//     return pImpl_->pConsumer_;\r
-//}\r
-//\r
-//gpu_frame_ptr BluefishPlaybackStrategy::GetReservedFrame() {\r
-//     return pImpl_->GetReservedFrame();\r
-//}\r
-\r
-void BluefishPlaybackStrategy::display(const gpu_frame_ptr& frame) \r
-{\r
-       return pImpl_->DisplayFrame(frame);\r
-}\r
-\r
-}      //namespace bluefish\r
-}      //namespace caspar
\ No newline at end of file
diff --git a/core/consumer/bluefish/bluefish_consumer.cpp b/core/consumer/bluefish/bluefish_consumer.cpp
new file mode 100644 (file)
index 0000000..1cc3af8
--- /dev/null
@@ -0,0 +1,314 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
\r
+#include "..\..\StdAfx.h"\r
+\r
+#ifndef DISABLE_BLUEFISH\r
+\r
+#include "fwd.h"\r
+#include "bluefish_consumer.h"\r
+#include "util.h"\r
+#include "exception.h"\r
+#include "memory.h"\r
+\r
+#include "../../frame/gpu_frame.h"\r
+\r
+#include <boost/thread.hpp>\r
+\r
+#include <tbb/concurrent_queue.h>\r
+\r
+#include <BlueVelvet4.h>\r
+#include <BlueHancUtils.h>\r
+\r
+#if defined(_MSC_VER)\r
+#pragma warning (push, 1) // TODO: Legacy code, just disable warnings\r
+#endif\r
+\r
+namespace caspar { namespace bluefish {\r
+       \r
+struct consumer::implementation\r
+{\r
+       implementation::implementation(const frame_format_desc& format_desc, unsigned int device_index, bool embeed_audio) \r
+               : device_index_(device_index), format_desc_(format_desc), sdk_(BlueVelvetFactory4()), current_id_(0), embeed_audio_(embeed_audio)\r
+       {\r
+               mem_fmt_                = MEM_FMT_ARGB_PC;\r
+               upd_fmt_                = UPD_FMT_FRAME;\r
+               vid_fmt_                = VID_FMT_PAL; \r
+               res_fmt_                = RES_FMT_NORMAL; \r
+               engine_mode_    = VIDEO_ENGINE_FRAMESTORE;\r
+                               \r
+               if(BLUE_FAIL(sdk_->device_attach(device_index_, FALSE))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to attach device."));\r
+       \r
+               int videoCardType = sdk_->has_video_cardtype();\r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Card type: ") << get_card_desc(videoCardType) << TEXT(". (device ") << device_index_ << TEXT(")");\r
+       \r
+               //void* pBlueDevice = blue_attach_to_device(1);\r
+               //EBlueConnectorPropertySetting video_routing[1];\r
+               //auto channel = BLUE_VIDEO_OUTPUT_CHANNEL_A;\r
+               //video_routing[0].channel = channel;   \r
+               //video_routing[0].propType = BLUE_CONNECTOR_PROP_SINGLE_LINK;\r
+               //video_routing[0].connector = channel == BLUE_VIDEO_OUTPUT_CHANNEL_A ? BLUE_CONNECTOR_SDI_OUTPUT_A : BLUE_CONNECTOR_SDI_OUTPUT_B;\r
+               //blue_set_connector_property(pBlueDevice, 1, video_routing);\r
+               //blue_detach_from_device(&pBlueDevice);\r
+               \r
+               vid_fmt_ = ULONG_MAX;\r
+               auto desiredVideoFormat = vid_fmt_from_frame_format(format_desc_.format);\r
+               int videoModeCount = sdk_->count_video_mode();\r
+               for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) \r
+               {\r
+                       EVideoMode videoMode = sdk_->enum_video_mode(videoModeIndex);\r
+                       if(videoMode == desiredVideoFormat) \r
+                               vid_fmt_ = videoMode;                   \r
+               }\r
+               if(vid_fmt_ == ULONG_MAX)\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set videomode."));\r
+               \r
+               // Set default video output channel\r
+               //if(BLUE_FAIL(set_card_property(sdk_, DEFAULT_VIDEO_OUTPUT_CHANNEL, channel)))\r
+               //      CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set default channel. (device ") << device_index_ << TEXT(")");\r
+\r
+               //Setting output Video mode\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_MODE, vid_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set videomode."));\r
+\r
+               //Select Update Mode for output\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_UPDATE_TYPE, upd_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set update type. "));\r
+       \r
+               disable_video_output();\r
+\r
+               //Enable dual link output\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_DUAL_LINK_OUTPUT, 1)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to enable dual link."));\r
+\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, Signal_FormatType_4224)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set dual link format type to 4:2:2:4. (device " + boost::lexical_cast<std::string>(device_index_) + ")"));\r
+                       \r
+               //Select output memory format\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_MEMORY_FORMAT, mem_fmt_))) \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set memory format."));\r
+               \r
+               //Select image orientation\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_IMAGE_ORIENTATION, ImageOrientation_Normal)))\r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set image orientation to normal. (device ") << device_index_ << TEXT(")"); \r
+\r
+               // Select data range\r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_RGB_DATA_RANGE, CGR_RANGE))) \r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set RGB data range to CGR. (device ") << device_index_ << TEXT(")");       \r
+               \r
+               if(BLUE_FAIL(set_card_property(sdk_, VIDEO_PREDEFINED_COLOR_MATRIX, vid_fmt_ == VID_FMT_PAL ? MATRIX_601_CGR : MATRIX_709_CGR)))\r
+                       CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to set colormatrix to ") << (vid_fmt_ == VID_FMT_PAL ? TEXT("601 CGR") : TEXT("709 CGR")) << TEXT(". (device ") << device_index_ << TEXT(")");\r
+               \r
+               //if(BLUE_FAIL(set_card_property(sdk_, EMBEDDED_AUDIO_OUTPUT, 0)))      \r
+               //      CASPAR_LOG(error) << TEXT("BLUECARD ERROR: Failed to enable embedded audio. (device ") << device_index_ << TEXT(")");   \r
+               //else \r
+               //{\r
+               //      CASPAR_LOG(info) << TEXT("BLUECARD INFO: Enabled embedded audio. (device ") << device_index_ << TEXT(")");\r
+               //      hasEmbeddedAudio_ = true;\r
+               //}\r
+\r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << format_desc_ << TEXT(". (device ") << device_index_ << TEXT(")");\r
+\r
+               if (sdk_->has_output_key()) \r
+               {\r
+                       int dummy = TRUE; int v4444 = FALSE; int invert = FALSE; int white = FALSE;\r
+                       sdk_->set_output_key(dummy, v4444, invert, white);\r
+               }\r
+\r
+               if(sdk_->GetHDCardType(device_index_) != CRD_HD_INVALID) \r
+                       sdk_->Set_DownConverterSignalType(vid_fmt_ == VID_FMT_PAL ? SD_SDI : HD_SDI);   \r
+       \r
+               if(BLUE_FAIL(sdk_->set_video_engine(engine_mode_)))\r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("BLUECARD ERROR: Failed to set vido engine."));\r
+\r
+               enable_video_output();\r
+\r
+                               \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
+\r
+               frame_buffer_.set_capacity(1);\r
+               thread_ = boost::thread([=]{run();});\r
+               \r
+               CASPAR_LOG(info) << TEXT("BLUECARD INFO: Successfully initialized device ") << device_index_;\r
+       }\r
+\r
+       ~implementation()\r
+       {\r
+               frame_buffer_.push(nullptr),\r
+               thread_.join();\r
+\r
+               disable_video_output();\r
+\r
+               if(sdk_)\r
+                       sdk_->device_detach();          \r
+\r
+               CASPAR_LOG(info) << "BLUECARD INFO: Successfully released device " << device_index_;\r
+       }\r
+       \r
+       void enable_video_output()\r
+       {\r
+               if(!BLUE_PASS(set_card_property(sdk_, VIDEO_BLACKGENERATOR, 0)))\r
+                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");  \r
+       }\r
+\r
+       void disable_video_output()\r
+       {\r
+               if(!BLUE_PASS(set_card_property(sdk_, VIDEO_BLACKGENERATOR, 1)))\r
+                       CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << device_index_ << TEXT(")");          \r
+       }\r
+\r
+       void display(const gpu_frame_ptr& 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
+       }\r
+\r
+       void do_display(const gpu_frame_ptr& frame)\r
+       {\r
+               auto hanc = hanc_buffers_[current_id_];         \r
+               current_id_ = (current_id_+1) % hanc_buffers_.size();           \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->audio_data().empty() ? silence : frame->audio_data();\r
+\r
+               unsigned long fieldCount = 0;\r
+               sdk_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
+                               \r
+               if(embeed_audio_)\r
+               {               \r
+                       encode_hanc(reinterpret_cast<BLUE_UINT32*>(hanc->data()), frame_audio_data.data(), audio_samples, audio_nchannels);\r
+\r
+                       sdk_->system_buffer_write_async(frame->data(), \r
+                                                                                        frame->size(), \r
+                                                                                        nullptr, \r
+                                                                                        BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
+\r
+                       sdk_->system_buffer_write_async(hanc->data(),\r
+                                                                                        hanc->size(), \r
+                                                                                        nullptr,                 \r
+                                                                                        BlueImage_HANC_DMABuffer(current_id_, BLUE_DATA_HANC));\r
+\r
+                       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(),\r
+                                                                                        frame->size(), \r
+                                                                                        nullptr,                 \r
+                                                                                        BlueImage_DMABuffer(current_id_, BLUE_DATA_IMAGE));\r
+                       \r
+                       if(BLUE_FAIL(sdk_->render_buffer_update(BlueBuffer_Image(current_id_))))\r
+                               CASPAR_LOG(trace) << TEXT("BLUEFISH: render_buffer_update failed");\r
+               }\r
+       }\r
+\r
+\r
+       void encode_hanc(BLUE_UINT32* hanc_data, void* audio_data, size_t audio_samples, size_t audio_nchannels)\r
+       {       \r
+               auto card_type = sdk_->has_video_cardtype();\r
+               auto sample_type = (AUDIO_CHANNEL_16BIT | AUDIO_CHANNEL_LITTLEENDIAN);\r
+               \r
+               hanc_stream_info_struct hanc_stream_info;\r
+               memset(&hanc_stream_info, 0, sizeof(hanc_stream_info));\r
+\r
+               hanc_stream_info.AudioDBNArray[0] = -1;\r
+               hanc_stream_info.AudioDBNArray[1] = -1;\r
+               hanc_stream_info.AudioDBNArray[2] = -1;\r
+               hanc_stream_info.AudioDBNArray[3] = -1;\r
+               hanc_stream_info.hanc_data_ptr = hanc_data;\r
+               hanc_stream_info.video_mode = vid_fmt_;\r
+               \r
+               auto emb_audio_flag = (blue_emb_audio_enable | blue_emb_audio_group1_enable);\r
+\r
+               if (!is_epoch_card(card_type))\r
+               {\r
+                       encode_hanc_frame(&hanc_stream_info, audio_data, audio_nchannels, \r
+                                                               audio_samples, sample_type, emb_audio_flag);    \r
+               }\r
+               else\r
+               {\r
+                       encode_hanc_frame_ex(card_type, &hanc_stream_info, audio_data, audio_nchannels,\r
+                                                                audio_samples, sample_type, emb_audio_flag);\r
+               }                                               \r
+       }\r
+\r
+       void run()\r
+       {\r
+               while(true)\r
+               {\r
+                       try\r
+                       {\r
+                               gpu_frame_ptr frame;\r
+                               frame_buffer_.pop(frame);\r
+                               if(frame == nullptr)\r
+                                       return;\r
+\r
+                               do_display(frame);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               exception_ = std::current_exception();\r
+                       }\r
+               }       \r
+       }\r
+               \r
+       BlueVelvetPtr sdk_;\r
+       \r
+       unsigned int device_index_;\r
+       frame_format_desc format_desc_;\r
+       \r
+       std::exception_ptr exception_;\r
+       boost::thread thread_;\r
+       tbb::concurrent_bounded_queue<gpu_frame_ptr> frame_buffer_;\r
+       \r
+       unsigned long mem_fmt_;\r
+       unsigned long upd_fmt_;\r
+       unsigned long vid_fmt_; \r
+       unsigned long res_fmt_; \r
+       unsigned long engine_mode_;\r
+\r
+       gpu_frame_ptr transferring_frame_;\r
+\r
+       std::vector<page_locked_buffer_ptr> hanc_buffers_;\r
+       int current_id_;\r
+       bool embeed_audio_;\r
+};\r
+\r
+consumer::consumer(const frame_format_desc& format_desc, unsigned int device_index, bool embeed_audio) : impl_(new implementation(format_desc, device_index, embeed_audio)){}  \r
+void consumer::display(const gpu_frame_ptr& frame){impl_->display(frame);}\r
+const frame_format_desc& consumer::get_frame_format_desc() const { return impl_->format_desc_;}\r
+\r
+}}\r
+\r
+#endif
\ No newline at end of file
similarity index 56%
rename from common/image/clear.h
rename to core/consumer/bluefish/bluefish_consumer.h
index 49a4f6dd92fbf30ecb36a507771137cdb6e4a815..5ddbfd2b7159d91c600a907222e98dd4680672a0 100644 (file)
 */\r
 #pragma once\r
 \r
-#include "../hardware/cpuid.h"\r
+#include "../../frame/frame_fwd.h"\r
+#include "../../consumer/frame_consumer.h"\r
 \r
-namespace caspar{ namespace common{ namespace image{\r
+namespace caspar { namespace bluefish {\r
        \r
-void clear_SSE2         (void* dest, size_t size);\r
-void clear_REF  (void* dest, size_t size);\r
-void clearParallel_SSE2         (void* dest, size_t size);\r
-void clearParallel_REF  (void* dest, size_t size);\r
-\r
-typedef void(*clear_fun)(void*, size_t);\r
-clear_fun get_clear_fun(SIMD simd = REF);\r
-\r
-}}}\r
-\r
+class consumer : public frame_consumer\r
+{\r
+public:\r
+       consumer(const frame_format_desc& format_desc, unsigned int deviceIndex, bool embedd_audio = false);\r
+       \r
+       void display(const gpu_frame_ptr&);\r
+               \r
+       const frame_format_desc& get_frame_format_desc() const;\r
+       virtual bool has_sync_clock() const {return false;}\r
+private:\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
+};\r
+typedef std::tr1::shared_ptr<consumer> BlueFishFrameConsumerPtr;\r
 \r
+}}\r
similarity index 72%
rename from common/utility/types.h
rename to core/consumer/bluefish/exception.h
index da508bb5be4989a88294a29950cab6005e372296..6b70ec27dc73b06a58dc99125a48637521422c3d 100644 (file)
 */\r
 #pragma once\r
 \r
-typedef unsigned __int8                u8;\r
-typedef __int8                         s8;\r
+#include "../../../common/exception/exceptions.h"\r
 \r
-typedef unsigned __int16       u16;\r
-typedef __int16                                s16;\r
+#include <exception>\r
 \r
-typedef unsigned __int32       u32;\r
-typedef __int32                                s32;
\ No newline at end of file
+namespace caspar { namespace bluefish {\r
+\r
+struct bluefish_exception : public caspar_exception\r
+{\r
+       bluefish_exception(){}\r
+       explicit bluefish_exception(const char* msg) : std::exception(msg) {}\r
+};\r
+\r
+}}
\ No newline at end of file
diff --git a/core/consumer/bluefish/fwd.h b/core/consumer/bluefish/fwd.h
new file mode 100644 (file)
index 0000000..2b39a78
--- /dev/null
@@ -0,0 +1,12 @@
+#pragma once\r
+\r
+class CBlueVelvet4;\r
+\r
+namespace caspar { namespace bluefish {\r
+\r
+typedef std::tr1::shared_ptr<CBlueVelvet4> BlueVelvetPtr;\r
+\r
+class consumer;\r
+typedef std::shared_ptr<consumer> consumer_ptr;\r
+\r
+}}
\ No newline at end of file
diff --git a/core/consumer/bluefish/memory.h b/core/consumer/bluefish/memory.h
new file mode 100644 (file)
index 0000000..9b4f198
--- /dev/null
@@ -0,0 +1,58 @@
+#pragma once\r
+\r
+#include <Windows.h>\r
+\r
+#include <BlueVelvet4.h>\r
+#include "../../frame/frame_format.h"\r
+#include "exception.h"\r
+\r
+namespace caspar { namespace bluefish {\r
+       \r
+static const size_t MAX_HANC_BUFFER_SIZE = 256*1024;\r
+static const size_t MAX_VBI_BUFFER_SIZE = 36*1920*4;\r
+\r
+struct page_locked_buffer\r
+{\r
+public:\r
+       page_locked_buffer(size_t size) : size_(size), data_(static_cast<unsigned char*>(::VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))\r
+       {\r
+               if(!data_)      \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed to allocate memory for paged locked buffer."));  \r
+               if(::VirtualLock(data_.get(), size_) == 0)      \r
+                       BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed to lock memory for paged locked buffer."));\r
+       }\r
+\r
+       static void reserve_working_size(size_t size)\r
+       {\r
+               SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0;\r
+               if(::GetProcessWorkingSetSize(::GetCurrentProcess(), &workingSetMinSize, &workingSetMaxSize))\r
+               {\r
+                       CASPAR_LOG(debug) << TEXT("WorkingSet size: min = ") << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize;\r
+                       \r
+                       workingSetMinSize += size;\r
+                       workingSetMaxSize += size;\r
+\r
+                       if(!::SetProcessWorkingSetSize(::GetCurrentProcess(), workingSetMinSize, workingSetMaxSize))            \r
+                               BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed set workingset."));              \r
+               }\r
+       }\r
+\r
+       PBYTE data() const { return data_.get(); }\r
+       size_t size() const { return size_; }\r
+private:\r
+\r
+       struct virtual_free\r
+       {\r
+               void operator()(LPVOID lpAddress)\r
+               {\r
+                       if(lpAddress != nullptr)                \r
+                               try{::VirtualFree(lpAddress, 0, MEM_RELEASE);}catch(...){}              \r
+               }\r
+       };\r
+\r
+       size_t size_;\r
+       std::unique_ptr<BYTE, virtual_free> data_;\r
+};\r
+typedef std::shared_ptr<page_locked_buffer> page_locked_buffer_ptr;\r
+\r
+}}
\ No newline at end of file
diff --git a/core/consumer/bluefish/util.h b/core/consumer/bluefish/util.h
new file mode 100644 (file)
index 0000000..02f5b54
--- /dev/null
@@ -0,0 +1,96 @@
+#pragma once\r
+\r
+#include <BlueVelvet4.h>\r
+#include "../../frame/frame_format.h"\r
+\r
+#include <memory>\r
+\r
+namespace caspar { namespace bluefish {\r
+       \r
+inline bool is_epoch_card(int card_type)\r
+{\r
+       return  card_type == CRD_BLUE_EPOCH_2K ||       \r
+                       card_type == CRD_BLUE_EPOCH_HORIZON || \r
+                       card_type == CRD_BLUE_EPOCH_2K_CORE ||  \r
+                       card_type == CRD_BLUE_EPOCH_2K_ULTRA || \r
+                       card_type == CRD_BLUE_EPOCH_CORE || \r
+                       card_type == CRD_BLUE_EPOCH_ULTRA;\r
+}\r
+\r
+inline unsigned long vid_fmt_from_frame_format(const frame_format& fmt) \r
+{\r
+       switch(fmt)\r
+       {\r
+       case frame_format::pal:                 return VID_FMT_PAL;\r
+       case frame_format::ntsc:                return VID_FMT_NTSC;\r
+       case frame_format::x576p2500:   return ULONG_MAX;       //not supported\r
+       case frame_format::x720p5000:   return VID_FMT_720P_5000;\r
+       case frame_format::x720p5994:   return VID_FMT_720P_5994;\r
+       case frame_format::x720p6000:   return VID_FMT_720P_6000;\r
+       case frame_format::x1080p2397:  return VID_FMT_1080P_2397;\r
+       case frame_format::x1080p2400:  return VID_FMT_1080P_2400;\r
+       case frame_format::x1080i5000:  return VID_FMT_1080I_5000;\r
+       case frame_format::x1080i5994:  return VID_FMT_1080I_5994;\r
+       case frame_format::x1080i6000:  return VID_FMT_1080I_6000;\r
+       case frame_format::x1080p2500:  return VID_FMT_1080P_2500;\r
+       case frame_format::x1080p2997:  return VID_FMT_1080P_2997;\r
+       case frame_format::x1080p3000:  return VID_FMT_1080P_3000;\r
+       default:                                                return ULONG_MAX;\r
+       }\r
+}\r
+\r
+inline wchar_t* get_card_desc(int cardType)\r
+{\r
+       switch(cardType) \r
+       {\r
+       case CRD_BLUEDEEP_LT:                           return L"Deepblue LT";// D64 Lite\r
+       case CRD_BLUEDEEP_SD:                           return L"Iridium SD";// Iridium SD\r
+       case CRD_BLUEDEEP_AV:                           return L"Iridium AV";// Iridium AV\r
+       case CRD_BLUEDEEP_IO:                           return L"Deepblue IO";// D64 Full\r
+       case CRD_BLUEWILD_AV:                           return L"Wildblue AV";// D64 AV\r
+       case CRD_IRIDIUM_HD:                            return L"Iridium HD";// * Iridium HD\r
+       case CRD_BLUEWILD_RT:                           return L"Wildblue RT";// D64 RT\r
+       case CRD_BLUEWILD_HD:                           return L"Wildblue HD";// * BadAss G2\r
+       case CRD_REDDEVIL:                                      return L"Iridium Full";// Iridium Full\r
+       case CRD_BLUEDEEP_HD:   \r
+       case CRD_BLUEDEEP_HDS:                          return L"Reserved for \"BasAss G2";// * BadAss G2 variant, proposed, reserved\r
+       case CRD_BLUE_ENVY:                                     return L"Blue envy"; // Mini Din \r
+       case CRD_BLUE_PRIDE:                            return L"Blue pride";//Mini Din Output \r
+       case CRD_BLUE_GREED:                            return L"Blue greed";\r
+       case CRD_BLUE_INGEST:                           return L"Blue ingest";\r
+       case CRD_BLUE_SD_DUALLINK:                      return L"Blue SD duallink";\r
+       case CRD_BLUE_CATALYST:                         return L"Blue catalyst";\r
+       case CRD_BLUE_SD_DUALLINK_PRO:          return L"Blue SD duallink pro";\r
+       case CRD_BLUE_SD_INGEST_PRO:            return L"Blue SD ingest pro";\r
+       case CRD_BLUE_SD_DEEPBLUE_LITE_PRO:     return L"Blue SD deepblue lite pro";\r
+       case CRD_BLUE_SD_SINGLELINK_PRO:        return L"Blue SD singlelink pro";\r
+       case CRD_BLUE_SD_IRIDIUM_AV_PRO:        return L"Blue SD iridium AV pro";\r
+       case CRD_BLUE_SD_FIDELITY:                      return L"Blue SD fidelity";\r
+       case CRD_BLUE_SD_FOCUS:                         return L"Blue SD focus";\r
+       case CRD_BLUE_SD_PRIME:                         return L"Blue SD prime";\r
+       case CRD_BLUE_EPOCH_2K_CORE:            return L"Blue epoch 2k core";\r
+       case CRD_BLUE_EPOCH_2K_ULTRA:           return L"Blue epoch 2k ultra";\r
+       case CRD_BLUE_EPOCH_HORIZON:            return L"Blue epoch horizon";\r
+       case CRD_BLUE_EPOCH_CORE:                       return L"Blue epoch core";\r
+       case CRD_BLUE_EPOCH_ULTRA:                      return L"Blue epoch ultra";\r
+       case CRD_BLUE_CREATE_HD:                        return L"Blue create HD";\r
+       case CRD_BLUE_CREATE_2K:                        return L"Blue create 2k";\r
+       case CRD_BLUE_CREATE_2K_ULTRA:          return L"Blue create 2k ultra";\r
+       default:                                                        return L"Unknown";\r
+       }\r
+}\r
+\r
+inline int set_card_property(CBlueVelvet4 * pSdk, ULONG prop, ULONG value)\r
+{\r
+       VARIANT variantValue;\r
+       variantValue.vt  = VT_UI4;\r
+       variantValue.ulVal = value;\r
+       return (pSdk->SetCardProperty(prop,variantValue));\r
+}\r
+\r
+inline int set_card_property(const std::shared_ptr<CBlueVelvet4> pSdk, ULONG prop, ULONG value)\r
+{\r
+       return set_card_property(pSdk.get(), prop, value);\r
+}\r
+\r
+}}
\ No newline at end of file
index dea018a1baab4e6e84c9e5118b7c3f75914b31e4..a71e3a392894afd5be23fef5fceadfba271b6b3b 100644 (file)
@@ -29,7 +29,7 @@
 #include "DeckLinkAPI_h.h"\r
 \r
 #include "../../frame/frame_format.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 \r
 #include "../../renderer/render_device.h"\r
 \r
@@ -129,7 +129,7 @@ struct DecklinkVideoConsumer::Implementation : public IDeckLinkVideoOutputCallba
                                std::shared_ptr<DecklinkVideoFrame> pTempFrame = GetReservedFrame();\r
                                if(pTempFrame && frame->size() == pTempFrame->size())\r
                                {\r
-                                       common::image::copy(pTempFrame->data(), frame->data(), pTempFrame->size());\r
+                                       common::copy(pTempFrame->data(), frame->data(), pTempFrame->size());\r
                                        DoRender(pTempFrame);\r
                                }\r
                                else\r
@@ -255,8 +255,6 @@ struct DecklinkVideoConsumer::Implementation : public IDeckLinkVideoOutputCallba
 \r
        void Run()\r
        {                               \r
-               auto period = boost::posix_time::microseconds(get_frame_format_period(format_desc_)*1000000);\r
-               auto time = boost::posix_time::microsec_clock::local_time();\r
                while(true)\r
                {\r
                        try\r
@@ -265,12 +263,7 @@ struct DecklinkVideoConsumer::Implementation : public IDeckLinkVideoOutputCallba
                                frameBuffer_.pop(frame);\r
                                if(frame == nullptr)\r
                                        return;\r
-\r
-                               auto remaining = period - (boost::posix_time::microsec_clock::local_time() - time);\r
-                               if(remaining > boost::posix_time::microseconds(5000))\r
-                                       boost::this_thread::sleep(remaining - boost::posix_time::microseconds(5000));\r
-                               time = boost::posix_time::microsec_clock::local_time();\r
-\r
+                               \r
                                pPlayback_->DisplayFrame(frame);\r
                        }\r
                        catch(...)\r
index 27dae150f199209c070bfd33d78b2287afa13854..bbc661f4bdc9d9cf0e2def0119027228b0c168d0 100644 (file)
@@ -33,8 +33,9 @@ public:
        virtual ~frame_consumer() {}\r
 \r
        virtual const frame_format_desc& get_frame_format_desc() const = 0;\r
-       virtual void prepare(const gpu_frame_ptr&){};\r
-       virtual void display(const gpu_frame_ptr&){};\r
+       virtual void prepare(const gpu_frame_ptr&){}\r
+       virtual void display(const gpu_frame_ptr&){}\r
+       virtual bool has_sync_clock() const {return false;}\r
 };\r
 typedef std::shared_ptr<frame_consumer> frame_consumer_ptr;\r
 typedef std::shared_ptr<const frame_consumer> frame_consumer_const_ptr;\r
similarity index 79%
rename from core/consumer/oal/oal_frame_consumer.cpp
rename to core/consumer/oal/oal_consumer.cpp
index 9e1322a5be645757f2f016a439af8e358df10633..e94a5001fb6381a39a53cb1589226223f3e2671a 100644 (file)
@@ -20,7 +20,7 @@
  \r
 #include "../../StdAfx.h"\r
 \r
-#include "oal_frame_consumer.h"\r
+#include "oal_consumer.h"\r
 \r
 #include "../../frame/gpu_frame.h"\r
 #include "../../frame/frame_format.h"\r
@@ -76,11 +76,11 @@ private:
        bool OnGetData(sf::SoundStream::Chunk& data)\r
     {\r
                gpu_frame_ptr frame;\r
-               //if(!external_chunks_.try_pop(frame))\r
-               //{\r
-                       //CASPAR_LOG(trace) << "Sound Buffer Underrun";\r
+               if(!external_chunks_.try_pop(frame))\r
+               {\r
+                       CASPAR_LOG(trace) << "Sound Buffer Underrun";\r
                        external_chunks_.pop(frame);\r
-               //}\r
+               }\r
 \r
                if(frame == nullptr)\r
                {\r
@@ -101,7 +101,7 @@ private:
 };\r
 typedef std::shared_ptr<sound_channel> sound_channelPtr;\r
 \r
-struct oal_frame_consumer::implementation : boost::noncopyable\r
+struct consumer::implementation : boost::noncopyable\r
 {      \r
        implementation(const frame_format_desc& format_desc) : format_desc_(format_desc)\r
        {\r
@@ -117,7 +117,7 @@ struct oal_frame_consumer::implementation : boost::noncopyable
        caspar::frame_format_desc format_desc_;\r
 };\r
 \r
-oal_frame_consumer::oal_frame_consumer(const caspar::frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-const caspar::frame_format_desc& oal_frame_consumer::get_frame_format_desc() const{return impl_->format_desc_;}\r
-void oal_frame_consumer::prepare(const gpu_frame_ptr& frame){impl_->push(frame);}\r
+consumer::consumer(const caspar::frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
+const caspar::frame_format_desc& consumer::get_frame_format_desc() const{return impl_->format_desc_;}\r
+void consumer::prepare(const gpu_frame_ptr& frame){impl_->push(frame);}\r
 }}\r
similarity index 64%
rename from core/consumer/bluefish/BluefishPlaybackStrategy.h
rename to core/consumer/oal/oal_consumer.h
index 781a115676ccc996a50fcfa0ff0bb41998dda172..e3cf70c59ab98926a7b0031ee48c9c6f1e492320 100644 (file)
 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
 *\r
 */\r
\r
 #pragma once\r
 \r
-#include "../../frame/gpu_frame.h"\r
 #include "../../consumer/frame_consumer.h"\r
 \r
-namespace caspar {\r
-namespace bluefish {\r
+namespace caspar { namespace audio {\r
 \r
-class BlueFishVideoConsumer;\r
-\r
-class BluefishPlaybackStrategy\r
+class consumer : public frame_consumer\r
 {\r
-       struct Implementation;\r
-       std::shared_ptr<Implementation> pImpl_;\r
-\r
-public:\r
-       explicit BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer);\r
-       virtual ~BluefishPlaybackStrategy();\r
-\r
-       void display(const gpu_frame_ptr&);\r
+public:        \r
+       explicit consumer(const frame_format_desc& format_desc);\r
+       \r
+       const frame_format_desc& get_frame_format_desc() const; \r
+       void prepare(const gpu_frame_ptr& frame);\r
+       virtual bool has_sync_clock() const {return true;}\r
+private:\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
 };\r
 \r
-}      //namespace bluefish\r
-}      //namespace caspar\r
+}}
\ No newline at end of file
similarity index 85%
rename from core/consumer/ogl/ogl_frame_consumer.cpp
rename to core/consumer/ogl/ogl_consumer.cpp
index 4fc0fc2c12d0a94424349c4f382a52cf19fed9ba..d48bd43dc24c24b2b3720399460a9097b9dbb3ab 100644 (file)
 #pragma warning (disable : 4244)\r
 #endif\r
 \r
-#include "ogl_frame_consumer.h"\r
+#include "ogl_consumer.h"\r
 \r
 #include "../../frame/frame_format.h"\r
 #include "../../frame/gpu_frame.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 \r
 #include <boost/thread.hpp>\r
 \r
@@ -45,7 +45,7 @@ void GL_CHECK()
                BOOST_THROW_EXCEPTION(ogl_error() << msg_info(boost::lexical_cast<std::string>(glGetError())));\r
 }\r
 \r
-struct ogl_frame_consumer::implementation : boost::noncopyable\r
+struct consumer::implementation : boost::noncopyable\r
 {      \r
        implementation(const frame_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed) \r
                : format_desc_(format_desc), stretch_(stretch), texture_(0), pbo_index_(0), screen_width_(0), screen_height_(0), windowed_(windowed)\r
@@ -226,7 +226,7 @@ struct ogl_frame_consumer::implementation : boost::noncopyable
 \r
                if(ptr != NULL)                 \r
                {\r
-                       common::image::copy(ptr, frame->data(), frame->size());\r
+                       common::copy(ptr, frame->data(), frame->size());\r
                        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);\r
                }\r
 \r
@@ -248,10 +248,7 @@ struct ogl_frame_consumer::implementation : boost::noncopyable
        void run()\r
        {                       \r
                init();\r
-               \r
-               auto period = boost::posix_time::microseconds(static_cast<long>(get_frame_format_period(format_desc_)*1000000.0));\r
-               auto time = boost::posix_time::microsec_clock::local_time();\r
-               \r
+                               \r
                gpu_frame_ptr frame;\r
                do\r
                {\r
@@ -260,11 +257,6 @@ struct ogl_frame_consumer::implementation : boost::noncopyable
                                frame_buffer_.pop(frame);\r
                                if(frame != nullptr)\r
                                {\r
-                                       auto remaining = period - (boost::posix_time::microsec_clock::local_time() - time);\r
-                                       if(remaining > boost::posix_time::microseconds(5000))\r
-                                               boost::this_thread::sleep(remaining - boost::posix_time::microseconds(5000));\r
-                                       time = boost::posix_time::microsec_clock::local_time();\r
-\r
                                        sf::Event e;\r
                                        while(window_->GetEvent(e)){}\r
                                        window_->SetActive();\r
@@ -302,8 +294,8 @@ struct ogl_frame_consumer::implementation : boost::noncopyable
        tbb::concurrent_bounded_queue<gpu_frame_ptr> frame_buffer_;\r
 };\r
 \r
-ogl_frame_consumer::ogl_frame_consumer(const caspar::frame_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed)\r
+consumer::consumer(const caspar::frame_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed)\r
 : impl_(new implementation(format_desc, screen_index, stretch, windowed)){}\r
-const caspar::frame_format_desc& ogl_frame_consumer::get_frame_format_desc() const{return impl_->format_desc_;}\r
-void ogl_frame_consumer::display(const gpu_frame_ptr& frame){impl_->display(frame);}\r
+const caspar::frame_format_desc& consumer::get_frame_format_desc() const{return impl_->format_desc_;}\r
+void consumer::display(const gpu_frame_ptr& frame){impl_->display(frame);}\r
 }}\r
similarity index 56%
rename from common/image/copy.h
rename to core/consumer/ogl/ogl_consumer.h
index fb5c2a561501676de47074af54b6c1f5e721b2f2..184309239729aa2848ca666fa8e15953622e19bc 100644 (file)
 */\r
 #pragma once\r
 \r
-#include "../hardware/cpuid.h"\r
+#include "../../consumer/frame_consumer.h"\r
 \r
-namespace caspar{ namespace common{ namespace image{\r
-       \r
-void copy_SSE2  (void* dest, const void* source, size_t size);\r
-void copy_REF   (void* dest, const void* source, size_t size);\r
-\r
-void copyParallel_SSE2  (void* dest, const void* source, size_t size);\r
-void copyParallel_REF   (void* dest, const void* source, size_t size);\r
+namespace caspar { namespace ogl {\r
 \r
-typedef void(*copy_fun)(void*, const void*, size_t);\r
-copy_fun get_copy_fun(SIMD simd = REF);\r
-\r
-}}} \r
+struct ogl_error : virtual caspar_exception{};\r
 \r
+enum stretch\r
+{\r
+       none,\r
+       uniform,\r
+       fill,\r
+       uniform_to_fill\r
+};\r
 \r
+class consumer : public frame_consumer\r
+{\r
+public:        \r
+       explicit consumer(const frame_format_desc& format_desc, unsigned int screen_index = 0, stretch stretch = stretch::fill, bool windowed = false);\r
+       \r
+       const frame_format_desc& get_frame_format_desc() const; \r
+       void display(const gpu_frame_ptr& frame);\r
+private:\r
+       struct implementation;\r
+       std::shared_ptr<implementation> impl_;\r
+};\r
+\r
+}}
\ No newline at end of file
index bb369d01140c71f6c9649f56040e4a2957e7d7f5..eb211ff9668d5e4b64ab1689480cd2ff4460c4d9 100644 (file)
@@ -77,7 +77,7 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
     </ClCompile>\r
     <Link>\r
-      <AdditionalDependencies>sfml-audio-d.lib;sfml-window-d.lib;OpenGL32.lib;FreeImage.lib;GLee.lib;Winmm.lib;Ws2_32.lib;BlueVelvet3_d.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;swscale-0.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>BlueHancUtils_d.lib;sfml-audio-d.lib;sfml-window-d.lib;OpenGL32.lib;FreeImage.lib;GLee.lib;Winmm.lib;Ws2_32.lib;BlueVelvet3_d.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;swscale-0.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <Version>\r
       </Version>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
       <PreprocessorDefinitions>NDEBUG;_VC80_UPGRADE=0x0710;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <WholeProgramOptimization>false</WholeProgramOptimization>\r
+      <TreatWarningAsError>true</TreatWarningAsError>\r
     </ClCompile>\r
     <PreLinkEvent>\r
       <Command>\r
       </Command>\r
     </PreLinkEvent>\r
     <Link>\r
-      <AdditionalDependencies>sfml-audio.lib;sfml-window.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;Bluevelvet3.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;SWSCALE-0.lib;tbb.lib;Glee.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>BlueHancUtils.lib;sfml-audio.lib;sfml-window.lib;OpenGL32.lib;FreeImage.lib;Winmm.lib;Ws2_32.lib;Bluevelvet3.lib;avformat-52.lib;avcodec-52.lib;avutil-50.lib;SWSCALE-0.lib;tbb.lib;Glee.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <Version>\r
       </Version>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ClInclude Include="config.h" />\r
-    <ClInclude Include="consumer\bluefish\BluefishException.h" />\r
-    <ClInclude Include="consumer\bluefish\BluefishPlaybackStrategy.h" />\r
-    <ClInclude Include="consumer\bluefish\BlueFishVideoConsumer.h" />\r
+    <ClInclude Include="consumer\bluefish\exception.h" />\r
+    <ClInclude Include="consumer\bluefish\fwd.h" />\r
+    <ClInclude Include="consumer\bluefish\memory.h" />\r
+    <ClInclude Include="consumer\bluefish\bluefish_consumer.h" />\r
+    <ClInclude Include="consumer\bluefish\util.h" />\r
     <ClInclude Include="consumer\decklink\DeckLinkAPI_h.h" />\r
     <ClInclude Include="consumer\decklink\DecklinkVideoConsumer.h" />\r
     <ClInclude Include="consumer\frame_consumer.h" />\r
-    <ClInclude Include="consumer\oal\oal_frame_consumer.h" />\r
-    <ClInclude Include="consumer\ogl\ogl_frame_consumer.h" />\r
+    <ClInclude Include="consumer\oal\oal_consumer.h" />\r
+    <ClInclude Include="consumer\ogl\ogl_consumer.h" />\r
     <ClInclude Include="frame\composite_gpu_frame.h" />\r
     <ClInclude Include="frame\frame_factory.h" />\r
     <ClInclude Include="frame\frame_format.h" />\r
     <ClInclude Include="StdAfx.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="consumer\bluefish\BluefishPlaybackStrategy.cpp">\r
+    <ClCompile Include="consumer\bluefish\bluefish_consumer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="consumer\bluefish\BlueFishVideoConsumer.cpp">\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="consumer\decklink\DeckLinkAPI_i.c">\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\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="consumer\oal\oal_frame_consumer.cpp">\r
+    <ClCompile Include="consumer\oal\oal_consumer.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="consumer\ogl\ogl_frame_consumer.cpp">\r
+    <ClCompile Include="consumer\ogl\ogl_consumer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
     <ClCompile Include="producer\ffmpeg\audio\audio_decoder.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="producer\ffmpeg\ffmpeg_producer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
     <ClCompile Include="producer\ffmpeg\video\video_decoder.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="producer\ffmpeg\video\video_deinterlacer.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="producer\ffmpeg\video\video_transformer.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)'=='Release|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
     <ClCompile Include="producer\flash\bitmap.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="producer\flash\cg_producer.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="producer\flash\ct_producer.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="producer\flash\Flash9e_i.c">\r
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../stdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+      </PrecompiledHeaderFile>\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
     </ClCompile>\r
     <ClCompile Include="producer\flash\FlashAxContainer.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="producer\flash\flash_producer.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="producer\image\image_loader.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
     </Midl>\r
     <Midl Include="producer\flash\Flash9e.IDL">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
     </Midl>\r
   </ItemGroup>\r
   <ItemGroup>\r
index acf0135158685d1f8e74c86571da565c945652f6..0c4287ab2c3794bcf64c9a3234fa7d444e34e561 100644 (file)
     <ClInclude Include="server.h">\r
       <Filter>Source</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="consumer\bluefish\BluefishPlaybackStrategy.h">\r
-      <Filter>Source\consumer\bluefish</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="consumer\bluefish\BlueFishVideoConsumer.h">\r
-      <Filter>Source\consumer\bluefish</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="consumer\bluefish\BluefishException.h">\r
-      <Filter>Source\consumer\bluefish</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="consumer\decklink\DecklinkVideoConsumer.h">\r
       <Filter>Source\consumer\decklink</Filter>\r
     </ClInclude>\r
     <ClInclude Include="consumer\decklink\DeckLinkAPI_h.h">\r
       <Filter>Source\consumer\decklink\interop</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="consumer\oal\oal_frame_consumer.h">\r
-      <Filter>Source\consumer\oal</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="consumer\ogl\ogl_frame_consumer.h">\r
-      <Filter>Source\consumer\ogl</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="consumer\frame_consumer.h">\r
       <Filter>Source\consumer</Filter>\r
     </ClInclude>\r
     <ClInclude Include="producer\ffmpeg\video\video_deinterlacer.h">\r
       <Filter>Source\producer\ffmpeg\video</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="producer\flash\ct_producer.h">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\flash\flash_producer.h">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\flash\cg_producer.h">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\flash\TimerHelper.h">\r
-      <Filter>Source\producer\flash\interop</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\flash\FlashAxContainer.h">\r
-      <Filter>Source\producer\flash\interop</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\flash\axflash.h">\r
-      <Filter>Source\producer\flash\interop</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="producer\image\image_loader.h">\r
       <Filter>Source\producer\image</Filter>\r
     </ClInclude>\r
     <ClInclude Include="producer\ffmpeg\video\video_transformer.h">\r
       <Filter>Source\producer\ffmpeg\video</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="frame\composite_gpu_frame.h">\r
+      <Filter>Source\frame\gpu</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="producer\flash\bitmap.h">\r
       <Filter>Source\producer\flash</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="frame\composite_gpu_frame.h">\r
-      <Filter>Source\frame\gpu</Filter>\r
+    <ClInclude Include="producer\flash\cg_producer.h">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\flash\ct_producer.h">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\flash\flash_producer.h">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\flash\axflash.h">\r
+      <Filter>Source\producer\flash\interop</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\flash\FlashAxContainer.h">\r
+      <Filter>Source\producer\flash\interop</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\flash\TimerHelper.h">\r
+      <Filter>Source\producer\flash\interop</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\bluefish\util.h">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\bluefish\exception.h">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\bluefish\memory.h">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\bluefish\fwd.h">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\ogl\ogl_consumer.h">\r
+      <Filter>Source\consumer\ogl</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\oal\oal_consumer.h">\r
+      <Filter>Source\consumer\oal</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="consumer\bluefish\bluefish_consumer.h">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="server.cpp">\r
       <Filter>Source</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="consumer\bluefish\BluefishPlaybackStrategy.cpp">\r
-      <Filter>Source\consumer\bluefish</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="consumer\bluefish\BlueFishVideoConsumer.cpp">\r
-      <Filter>Source\consumer\bluefish</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="consumer\decklink\DecklinkVideoConsumer.cpp">\r
       <Filter>Source\consumer\decklink</Filter>\r
     </ClCompile>\r
     <ClCompile Include="consumer\decklink\DeckLinkAPI_i.c">\r
       <Filter>Source\consumer\decklink\interop</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="consumer\oal\oal_frame_consumer.cpp">\r
-      <Filter>Source\consumer\oal</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="consumer\ogl\ogl_frame_consumer.cpp">\r
-      <Filter>Source\consumer\ogl</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="producer\color\color_producer.cpp">\r
       <Filter>Source\producer\color</Filter>\r
     </ClCompile>\r
     <ClCompile Include="producer\ffmpeg\video\video_decoder.cpp">\r
       <Filter>Source\producer\ffmpeg\video</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="producer\flash\ct_producer.cpp">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\flash\flash_producer.cpp">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\flash\cg_producer.cpp">\r
-      <Filter>Source\producer\flash</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\flash\FlashAxContainer.cpp">\r
-      <Filter>Source\producer\flash\interop</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\flash\Flash9e_i.c">\r
-      <Filter>Source\producer\flash\interop</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="producer\image\image_loader.cpp">\r
       <Filter>Source\producer\image</Filter>\r
     </ClCompile>\r
     <ClCompile Include="frame\gpu_frame.cpp">\r
       <Filter>Source\frame\gpu</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="frame\composite_gpu_frame.cpp">\r
+      <Filter>Source\frame\gpu</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="producer\ffmpeg\video\video_transformer.cpp">\r
       <Filter>Source\producer\ffmpeg\video</Filter>\r
     </ClCompile>\r
     <ClCompile Include="producer\flash\bitmap.cpp">\r
       <Filter>Source\producer\flash</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="frame\composite_gpu_frame.cpp">\r
-      <Filter>Source\frame\gpu</Filter>\r
+    <ClCompile Include="producer\flash\cg_producer.cpp">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\flash\ct_producer.cpp">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\flash\flash_producer.cpp">\r
+      <Filter>Source\producer\flash</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\flash\Flash9e_i.c">\r
+      <Filter>Source\producer\flash\interop</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\flash\FlashAxContainer.cpp">\r
+      <Filter>Source\producer\flash\interop</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumer\ogl\ogl_consumer.cpp">\r
+      <Filter>Source\consumer\ogl</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumer\oal\oal_consumer.cpp">\r
+      <Filter>Source\consumer\oal</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="consumer\bluefish\bluefish_consumer.cpp">\r
+      <Filter>Source\consumer\bluefish</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
index 36c90149e60b3c9b687ef3d5e0bee80c4b26b558..19c815031fc64bc8f0395925b25f9ac54523c436 100644 (file)
@@ -1,8 +1,8 @@
 #include "../StdAfx.h"\r
 \r
 #include "composite_gpu_frame.h"\r
-#include "../../common/image/copy.h"\r
 #include "../../common/gl/utility.h"\r
+#include "../../common/utility/memory.h"\r
 \r
 #include <algorithm>\r
 #include <numeric>\r
@@ -44,7 +44,14 @@ struct composite_gpu_frame::implementation
        void add(const gpu_frame_ptr& frame)\r
        {\r
                frames_.push_back(frame);\r
-               mix_audio_safe(audio_data_, frame->audio_data());\r
+\r
+               if(audio_data_.empty())\r
+                       audio_data_ = std::move(frame->audio_data());\r
+               else\r
+               {\r
+                       for(size_t n = 0; n < frame->audio_data().size(); ++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
        unsigned char* data()\r
index ddb085b758e4cc3bd0db4a9d2acd74b9a337ae5d..53398350cfb3e0010e0100caed3850c1db6e65d6 100644 (file)
@@ -1,15 +1,71 @@
 #include "../StdAfx.h"\r
 \r
 #include "gpu_frame.h"\r
-#include "../../common/image/copy.h"\r
+#include "../../common/utility/memory.h"\r
 #include "../../common/gl/utility.h"\r
 \r
 namespace caspar {\r
        \r
+GLubyte progressive_pattern[] = {\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
+       \r
+GLubyte upper_pattern[] = {\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
+               \r
+GLubyte lower_pattern[] = {\r
+                                                       0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+       0xff, 0xff, 0xff, 0xff};\r
+\r
 struct gpu_frame::implementation\r
 {\r
        implementation(size_t width, size_t height) \r
-               : pbo_(0), data_(nullptr), width_(width), height_(height), size_(width*height*4), reading_(false), texture_(0), alpha_(1.0f)\r
+               : pbo_(0), data_(nullptr), width_(width), height_(height), size_(width*height*4), \r
+               reading_(false), texture_(0), alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive)\r
        {       \r
        }\r
 \r
@@ -103,6 +159,14 @@ struct gpu_frame::implementation
                glPushMatrix();\r
                glTranslatef(x_*2.0f, y_*2.0f, 0.0f);\r
                glColor4f(1.0f, 1.0f, 1.0f, alpha_);\r
+\r
+               if(mode_ == video_mode::progressive)\r
+                       glPolygonStipple(progressive_pattern);\r
+               else if(mode_ == video_mode::upper)\r
+                       glPolygonStipple(upper_pattern);\r
+               else if(mode_ == video_mode::lower)\r
+                       glPolygonStipple(lower_pattern);\r
+\r
                CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));\r
                glBegin(GL_QUADS);\r
                        glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);\r
@@ -126,6 +190,7 @@ struct gpu_frame::implementation
                alpha_ = 1.0f;\r
                x_ = 0.0f;\r
                y_ = 0.0f;\r
+               mode_ = video_mode::progressive;\r
        }\r
 \r
        gpu_frame* self_;\r
@@ -141,6 +206,7 @@ struct gpu_frame::implementation
        float alpha_;\r
        float x_;\r
        float y_;\r
+       video_mode mode_;\r
 };\r
 \r
 gpu_frame::gpu_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}\r
@@ -161,4 +227,6 @@ void gpu_frame::alpha(float value){ impl_->alpha_ = value;}
 float gpu_frame::x() const { return impl_->x_;}\r
 float gpu_frame::y() const { return impl_->y_;}\r
 void gpu_frame::translate(float x, float y) { impl_->x_ += x; impl_->y_ += y; }\r
+void gpu_frame::mode(video_mode mode){ impl_->mode_ = mode;}\r
+video_mode gpu_frame::mode() const{ return impl_->mode_;}\r
 }
\ No newline at end of file
index c362d7066873015de3d80df4058f5dadcc807d4c..eba2d5465746e525cfc8c608ddc6a8c4cd01b6b8 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once\r
 \r
+#include "frame_format.h"\r
+\r
 #include <memory>\r
 \r
 #include <Glee.h>\r
@@ -34,6 +36,9 @@ public:
        virtual float y() const;\r
        virtual void translate(float x, float y);\r
 \r
+       virtual void mode(video_mode mode);\r
+       virtual video_mode mode() const;\r
+\r
        static std::shared_ptr<gpu_frame> null()\r
        {\r
                static auto my_null_frame = std::make_shared<gpu_frame>(0,0);\r
@@ -46,22 +51,4 @@ private:
 };\r
 typedef std::shared_ptr<gpu_frame> gpu_frame_ptr;\r
        \r
-inline void mix_audio_safe(std::vector<short>& frame1, const std::vector<short>& frame2)\r
-{\r
-       if(frame1.empty())\r
-               frame1 = std::move(frame2);\r
-       else if(!frame2.empty())\r
-       {\r
-               for(size_t n = 0; n < frame1.size(); ++n)\r
-                       frame1[n] = static_cast<short>(static_cast<int>(frame1[n]) + static_cast<int>(frame2[n]) & 0xFFFF);                             \r
-       }\r
-}\r
-\r
-template<typename frame_ptr_type>\r
-frame_ptr_type& mix_audio_safe(frame_ptr_type& frame1, const gpu_frame_ptr& frame2)\r
-{\r
-       mix_audio_safe(frame1->audio_data(), frame2->audio_data());\r
-       return frame1;\r
-}\r
-\r
 }
\ No newline at end of file
index 9162d4f919e3511cf9d2bdf2e4534b54fa08440a..690a699232d83f36db2ed370a9c330a7cfd1d09a 100644 (file)
@@ -3,11 +3,12 @@
 #include "gpu_frame_processor.h"\r
 \r
 #include "gpu_frame.h"\r
+#include "composite_gpu_frame.h"\r
 #include "frame_format.h"\r
 \r
 #include "../../common/exception/exceptions.h"\r
 #include "../../common/concurrency/executor.h"\r
-#include "../../common/image/image.h"\r
+#include "../../common/utility/memory.h"\r
 #include "../../common/gl/utility.h"\r
 \r
 #include <Glee.h>\r
@@ -76,6 +77,7 @@ struct gpu_frame_processor::implementation
                {\r
                        context_.reset(new sf::Context());\r
                        context_->SetActive(true);\r
+                       glEnable(GL_POLYGON_STIPPLE);\r
                        glEnable(GL_TEXTURE_2D);\r
                        glEnable(GL_BLEND);\r
                        glDisable(GL_DEPTH_TEST);\r
@@ -84,16 +86,15 @@ struct gpu_frame_processor::implementation
                        glViewport(0, 0, format_desc_.width, format_desc_.height);\r
                        glLoadIdentity();\r
 \r
-                       input_.resize(2);\r
-                       writing_.resize(2);\r
+                       input_.resize(2, std::make_shared<composite_gpu_frame>(format_desc_.width, format_desc_.height));\r
+                       writing_.resize(2, std::make_shared<composite_gpu_frame>(format_desc_.width, format_desc_.height));\r
                        fbo_ = std::make_shared<frame_buffer>(format_desc_.width, format_desc_.height);\r
                        output_frame_ = std::make_shared<gpu_frame>(format_desc_.width, format_desc_.height);\r
                        index_ = 0;\r
                });\r
 \r
                empty_frame_ = create_frame(format_desc.width, format_desc.height);\r
-               common::image::clear(empty_frame_->data(), empty_frame_->size());\r
-               // Fill pipeline length\r
+               common::clear(empty_frame_->data(), empty_frame_->size());\r
                for(int n = 0; n < 3; ++n)\r
                        finished_frames_.push(empty_frame_);\r
        }\r
@@ -113,6 +114,8 @@ struct gpu_frame_processor::implementation
        {\r
                boost::range::remove_erase(frames, nullptr);\r
                boost::range::remove_erase(frames, gpu_frame::null());\r
+               auto composite_frame = std::make_shared<composite_gpu_frame>(format_desc_.width, format_desc_.height);\r
+               boost::range::for_each(frames, std::bind(&composite_gpu_frame::add, composite_frame, std::placeholders::_1));\r
 \r
                executor_.begin_invoke([=]\r
                {\r
@@ -123,40 +126,33 @@ struct gpu_frame_processor::implementation
 \r
                                // 2. Start asynchronous DMA transfer to video memory\r
                                // Lock frames and give pointer ownership to OpenGL                     \r
-                               boost::range::for_each(input_[index_], std::mem_fn(&gpu_frame::write_lock));\r
-                               writing_[index_] = input_[index_];      \r
-                               input_[index_].clear();\r
+                               input_[index_]->write_lock();\r
+                               writing_[index_] = std::move(input_[index_]);   \r
                                \r
                                // 1. Copy to page-locked memory\r
-                               input_[next_index] = frames;\r
+                               input_[next_index] = std::move(composite_frame);\r
                                                                \r
                                // 4. Output to external buffer\r
                                if(output_frame_->read_unlock())\r
                                        finished_frames_.push(output_frame_);\r
-                               output_frame_ = nullptr;\r
                \r
                                // 3. Draw to framebuffer and start asynchronous DMA transfer to page-locked memory                             \r
                                // Clear framebuffer\r
                                glClear(GL_COLOR_BUFFER_BIT);   \r
-\r
-                               // Draw all frames to framebuffer\r
-                               glLoadIdentity();\r
-                               boost::range::for_each(writing_[next_index], std::mem_fn(&gpu_frame::draw));\r
+                               writing_[next_index]->draw();\r
                                \r
                                // Create an output frame\r
                                output_frame_ = create_output_frame();\r
                        \r
                                // Read from framebuffer into page-locked memory\r
                                output_frame_->read_lock(GL_COLOR_ATTACHMENT0_EXT);\r
+                               output_frame_->audio_data() = std::move(writing_[next_index]->audio_data());\r
 \r
                                // Unlock frames and give back pointer ownership\r
-                               boost::range::for_each(writing_[next_index], std::mem_fn(&gpu_frame::write_unlock));\r
+                               writing_[next_index]->write_unlock();\r
                                \r
-                               // Mix audio from composite frames into output frame\r
-                               std::accumulate(writing_[next_index].begin(), writing_[next_index].end(), output_frame_, mix_audio_safe<gpu_frame_ptr>);        \r
-\r
                                // Return frames to pool\r
-                               writing_[next_index].clear();\r
+                               writing_[next_index].reset();\r
                        }\r
                        catch(...)\r
                        {\r
@@ -213,8 +209,8 @@ struct gpu_frame_processor::implementation
        frame_buffer_ptr fbo_;\r
 \r
        int index_;\r
-       std::vector<std::vector<gpu_frame_ptr>>                 input_;\r
-       std::vector<std::vector<gpu_frame_ptr>>                 writing_;\r
+       std::vector<composite_gpu_frame_ptr>                    input_;\r
+       std::vector<composite_gpu_frame_ptr>                    writing_;\r
 \r
        gpu_frame_ptr                                                                   output_frame_;\r
        tbb::concurrent_bounded_queue<gpu_frame_ptr>    finished_frames_;\r
index 381f846d7c6a81ac150108ca9bbcd6993174d309..e25b54d70a1eaf6490763b8d404bebd517904790 100644 (file)
@@ -2,7 +2,7 @@
 \r
 #include "audio_decoder.h"\r
 \r
-#include "../../../../common/image/image.h"\r
+#include "../../../../common/utility/memory.h"\r
 \r
 #include <queue>\r
                \r
@@ -43,7 +43,7 @@ struct audio_decoder::implementation : boost::noncopyable
                {\r
                        //either fill what's left of the chunk or copy all written_bytes that are left\r
                        int targetLength = std::min((max_chunk_length - current_audio_chunk_offset_), written_bytes);\r
-                       common::image::copy(current_chunk_data_ + current_audio_chunk_offset_, pDecomp, targetLength);\r
+                       common::copy(current_chunk_data_ + current_audio_chunk_offset_, pDecomp, targetLength);\r
                        written_bytes -= targetLength;\r
 \r
                        current_audio_chunk_offset_ += targetLength;\r
@@ -52,7 +52,7 @@ struct audio_decoder::implementation : boost::noncopyable
                        if(current_audio_chunk_offset_ >= max_chunk_length) \r
                        {\r
                                if(max_chunk_length < static_cast<int>(audio_packet->audio_frame_size)) \r
-                                       common::image::clear(current_chunk_data_ + max_chunk_length, audio_packet->audio_frame_size-max_chunk_length);                                  \r
+                                       common::clear(current_chunk_data_ + max_chunk_length, audio_packet->audio_frame_size-max_chunk_length);                                 \r
                                else if(audio_packet->audio_frame_size < audio_packet->src_audio_frame_size) \r
                                        discard_bytes_ = audio_packet->src_audio_frame_size-audio_packet->audio_frame_size;\r
                                \r
index 5def640f47db85b694b7ed308c14e6448376fd2c..ebae14b88d6afd7a6105f8c5d873c28577fae3c4 100644 (file)
@@ -31,7 +31,7 @@ extern "C"
 #include "../../frame/frame_format.h"\r
 #include "../../../common/utility/find_file.h"\r
 #include "../../server.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 \r
 #include <tbb/mutex.h>\r
index 6cf6f5b7f7e89583c8896bb2dbd3ae52b3882c66..fb1a7e5a56e2a38d9b117e8e6b2f03af13e1b960 100644 (file)
@@ -3,7 +3,7 @@
 #include "input.h"\r
 \r
 #include "../../frame/frame_format.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 \r
 #include <tbb/concurrent_queue.h>\r
index e59c6d31550086bc80f860946df92a7995520af6..1ac528a0cef1fc8b30e595b8f8974702be289822 100644 (file)
@@ -4,7 +4,7 @@
 \r
 #include "../packet.h"\r
 \r
-#include "../../../../common/image/image.h"\r
+#include "../../../../common/utility/memory.h"\r
 \r
 #include <tbb/parallel_for.h>\r
 #include <tbb/atomic.h>\r
diff --git a/core/producer/ffmpeg/video/video_transformer.cpp b/core/producer/ffmpeg/video/video_transformer.cpp
deleted file mode 100644 (file)
index d88a734..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#include "../../../stdafx.h"\r
-\r
-#include "video_transformer.h"\r
-\r
-#include "../../../frame/frame_format.h"\r
-#include "../../../../common/image/image.h"\r
-#include "../../../frame/gpu_frame.h"\r
-#include "../../../frame/gpu_frame.h"\r
-#include "../../../frame/frame_factory.h"\r
-\r
-#include <tbb/parallel_for.h>\r
-#include <tbb/atomic.h>\r
-#include <tbb/mutex.h>\r
-#include <tbb/concurrent_queue.h>\r
-#include <tbb/scalable_allocator.h>\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (push)\r
-#pragma warning (disable : 4244)\r
-#endif\r
-extern "C" \r
-{\r
-       #define __STDC_CONSTANT_MACROS\r
-       #define __STDC_LIMIT_MACROS\r
-       #include <libswscale/swscale.h>\r
-}\r
-#if defined(_MSC_VER)\r
-#pragma warning (pop)\r
-#endif\r
-\r
-namespace caspar{ namespace ffmpeg{\r
-\r
-typedef std::shared_ptr<SwsContext> SwsContextPtr;\r
-\r
-// TODO: Remove and do copy right into frame\r
-struct fill_frame\r
-{\r
-       fill_frame(size_t width, size_t height) \r
-               : frame(avcodec_alloc_frame(), av_free), buffer(static_cast<unsigned char*>(scalable_aligned_malloc(width*height*4, 16)), scalable_aligned_free)\r
-       {       \r
-               avpicture_fill(reinterpret_cast<AVPicture*>(frame.get()), buffer.get(), PIX_FMT_BGRA, width, height);\r
-       }\r
-       const AVFramePtr        frame;\r
-       const std::shared_ptr<unsigned char>            buffer;\r
-};\r
-typedef std::shared_ptr<fill_frame> fill_frame_ptr;\r
-\r
-struct video_transformer::implementation : boost::noncopyable\r
-{\r
-       video_packet_ptr execute(const video_packet_ptr video_packet)\r
-       {                               \r
-               assert(video_packet);\r
-\r
-               if(!sws_context_)\r
-               {\r
-                       double param;\r
-                       sws_context_.reset(sws_getContext(video_packet->codec_context->width, video_packet->codec_context->height, video_packet->codec_context->pix_fmt, video_packet->format_desc.width, video_packet->format_desc.height, \r
-                                                                                               PIX_FMT_BGRA, SWS_BILINEAR, nullptr, nullptr, &param), sws_freeContext);\r
-               }\r
-               \r
-               //AVFrame avFrame;      \r
-               //avcodec_get_frame_defaults(avFrame);\r
-               //avpicture_fill(reinterpret_cast<AVPicture*>(&avFrame), video_packet->frame->data(), PIX_FMT_BGRA, video_packet->frameFormat.width, video_packet->frameFormat.height);\r
-               \r
-               auto format_desc = video_packet->format_desc;\r
-\r
-               fill_frame fill_frame(format_desc.width, format_desc.height);\r
-               video_packet->frame = factory_->create_frame(format_desc.width, format_desc.height);\r
-               int result = sws_scale(sws_context_.get(), video_packet->decoded_frame->data, video_packet->decoded_frame->linesize, 0, video_packet->codec_context->height, fill_frame.frame->data, fill_frame.frame->linesize);\r
-               video_packet->decoded_frame.reset(); // Free memory\r
-               \r
-               if(video_packet->codec->id == CODEC_ID_DVVIDEO) // Move up one field\r
-               {\r
-                       size_t size = format_desc.width * format_desc.height * 4;\r
-                       size_t linesize = format_desc.width * 4;\r
-                       common::image::copy(video_packet->frame->data(), fill_frame.buffer.get() + linesize, size - linesize);\r
-                       common::image::clear(video_packet->frame->data() + size - linesize, linesize);\r
-               }\r
-               else\r
-               {\r
-                        // This copy should be unnecessary. But it seems that when mapping the frame memory to an avframe for scaling there are some artifacts in the picture. See line 59-61.\r
-                       common::image::copy(video_packet->frame->data(), fill_frame.buffer.get(), video_packet->frame->size());\r
-               }\r
-\r
-               return video_packet;    \r
-       }\r
-\r
-       frame_factory_ptr factory_;\r
-       SwsContextPtr sws_context_;\r
-};\r
-\r
-video_transformer::video_transformer() : impl_(new implementation()){}\r
-video_packet_ptr video_transformer::execute(const video_packet_ptr& video_packet){return impl_->execute(video_packet);}\r
-void video_transformer::initialize(const frame_factory_ptr& factory){impl_->factory_ = factory; }\r
-}}
\ No newline at end of file
index e64ae7ceb8e8f0a224f01a8becb1f54ec57e04a1..6fd7c01d93305fb55e7e0957d7702a8aad6cb304 100644 (file)
 #include "../../server.h"\r
 #include "../../../common/concurrency/executor.h"\r
 #include "../../../common/concurrency/function_task.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 #include "../../../common/utility/scope_exit.h"\r
 \r
+#include "../../frame/gpu_frame.h"\r
+#include "../../frame/composite_gpu_frame.h"\r
+\r
 #include <boost/assign.hpp>\r
 #include <boost/filesystem.hpp>\r
 #include <boost/thread.hpp>\r
@@ -63,8 +66,7 @@ struct flash_producer::implementation
        if(!boost::filesystem::exists(filename))\r
                BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(common::narrow(filename)));\r
 \r
-               frame_buffer_.set_capacity(flash_producer::DEFAULT_BUFFER_SIZE);\r
-               last_frame_ = std::make_shared<bitmap>(format_desc_.width, format_desc_.height);\r
+               frame_buffer_.set_capacity(flash_producer::DEFAULT_BUFFER_SIZE);                \r
 \r
                start();\r
        }\r
@@ -224,20 +226,36 @@ struct flash_producer::implementation
                        }\r
 \r
                        bool isProgressive = format_desc_.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc_.fps/2 == 0);\r
-                       frame_buffer_.push(isProgressive ? render_frame() : render_interlace_frame());\r
+\r
+                       gpu_frame_ptr result;\r
+\r
+                       if(isProgressive)                                                       \r
+                               result = render_frame();                \r
+                       else\r
+                       {\r
+                               auto result = std::make_shared<composite_gpu_frame>(format_desc_.width, format_desc_.height);\r
+                               auto frame1 = render_frame();\r
+                               auto frame2 = render_frame();\r
+                               result->add(frame1);\r
+                               result->add(frame2);\r
+                               if(format_desc_.mode == video_mode::upper)\r
+                               {\r
+                                       frame1->mode(video_mode::upper);\r
+                                       frame2->mode(video_mode::lower);\r
+                               }\r
+                               else\r
+                               {\r
+                                       frame1->mode(video_mode::lower);\r
+                                       frame2->mode(video_mode::upper);\r
+                               }\r
+                       }\r
+\r
+                       frame_buffer_.push(result);\r
                        is_empty_ = flashax_container_->IsEmpty();\r
                }\r
        }\r
-\r
-       bitmap_ptr render_interlace_frame()\r
-       {               \r
-               bitmap_ptr frame1 = render_frame();\r
-               bitmap_ptr frame2 = render_frame();\r
-               common::image::copy(frame1->data(), frame2->data(), frame1->size());\r
-               return frame1;\r
-       }\r
-       \r
-       bitmap_ptr render_frame()\r
+               \r
+       gpu_frame_ptr render_frame()\r
        {\r
                flashax_container_->Tick();\r
                invalid_count_ = !flashax_container_->InvalidRectangle() ? std::min(2, invalid_count_+1) : 0;\r
@@ -248,7 +266,7 @@ struct flash_producer::implementation
                        {       \r
                                CASPAR_LOG(trace) << "Allocated bitmap";\r
                                frame = std::make_shared<bitmap>(format_desc_.width, format_desc_.height);                                      \r
-                               common::image::clear(frame->data(), frame->size());\r
+                               common::clear(frame->data(), frame->size());\r
                        }\r
                        flashax_container_->DrawControl(frame->hdc());\r
 \r
@@ -258,11 +276,16 @@ struct flash_producer::implementation
                                common::function_task::enqueue([=]\r
                                {\r
                                        if(pool->try_push(frame))\r
-                                               common::image::clear(frame->data(), frame->size());\r
+                                               common::clear(frame->data(), frame->size());\r
                                });\r
                        });\r
                }       \r
-               return current_frame_;\r
+\r
+               auto frame = factory_->create_frame(format_desc_);\r
+               auto bitmap = render_frame();\r
+               common::copy(frame->data(), current_frame_->data(), current_frame_->size());    \r
+\r
+               return frame;\r
        }\r
                \r
        gpu_frame_ptr get_frame()\r
@@ -270,10 +293,7 @@ struct flash_producer::implementation
                if(!frame_buffer_.try_pop(last_frame_) && is_empty_)\r
                        return gpu_frame::null();\r
                \r
-               auto frame = factory_->create_frame(format_desc_);\r
-               common::image::copy(frame->data(), last_frame_->data(), last_frame_->size());   \r
-               \r
-               return frame;\r
+               return last_frame_;\r
        }\r
 \r
        void initialize(const frame_factory_ptr& factory)\r
@@ -287,8 +307,8 @@ struct flash_producer::implementation
 \r
        CComObject<caspar::flash::FlashAxContainer>* flashax_container_;\r
                \r
-       tbb::concurrent_bounded_queue<bitmap_ptr> frame_buffer_;\r
-       bitmap_ptr last_frame_;\r
+       tbb::concurrent_bounded_queue<gpu_frame_ptr> frame_buffer_;\r
+       gpu_frame_ptr last_frame_;\r
        bitmap_ptr current_frame_;\r
        \r
        std::wstring filename_;\r
index 0bf56306f5c2a8274d3e77ce64a29a83b566b985..a4293e8d45b1202bea5d971163e7fc1c991e4902 100644 (file)
@@ -5,7 +5,7 @@
 #include "../../../common/exception/Exceptions.h"\r
 \r
 #include "../../frame/gpu_frame.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 \r
 #if defined(_MSC_VER)\r
 #pragma warning (disable : 4714) // marked as __forceinline not inlined\r
index 4b945ffa4e2dd78c80394697aa9c0c2778c9d2fb..6718121e9b0ea3a7612a8e228f46400ff97cc083 100644 (file)
@@ -7,7 +7,7 @@
 #include "../../frame/frame_format.h"\r
 #include "../../server.h"\r
 #include "../../../common/utility/find_file.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 \r
 #include <boost/assign.hpp>\r
 \r
@@ -33,7 +33,7 @@ struct image_producer : public frame_producer
 \r
                FreeImage_FlipVertical(bitmap.get());\r
                frame_ = factory->create_frame(format_desc_);\r
-               common::image::copy(frame_->data(), FreeImage_GetBits(bitmap.get()), frame_->size());\r
+               common::copy(frame_->data(), FreeImage_GetBits(bitmap.get()), frame_->size());\r
        }\r
 \r
        const frame_format_desc& get_frame_format_desc() const { return format_desc_; } \r
index 0bd071cd428ee2701e88bc733f7ceb948f3d549d..48cca8844f3152a29a76667dbe9b99abdc0c7033 100644 (file)
@@ -4,11 +4,13 @@
 \r
 #include "image_loader.h"\r
 \r
+#include "../../frame/gpu_frame.h"\r
+#include "../../frame/composite_gpu_frame.h"\r
 #include "../../frame/frame_format.h"\r
 #include "../../frame/frame_factory.h"\r
 #include "../../server.h"\r
 #include "../../../common/utility/find_file.h"\r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 \r
 #include <tbb/parallel_for.h>\r
 #include <tbb/parallel_invoke.h>\r
@@ -73,18 +75,18 @@ struct image_scroll_producer : public frame_producer
                image_height_ = std::max(height, format_desc_.height);\r
 \r
                image_ = std::shared_ptr<unsigned char>(static_cast<unsigned char*>(scalable_aligned_malloc(image_width_*image_height_*4, 16)));\r
-               common::image::clear(image_.get(), image_width_*image_height_*4);\r
+               common::clear(image_.get(), image_width_*image_height_*4);\r
 \r
                unsigned char* pBits = FreeImage_GetBits(pBitmap.get());\r
                \r
                for (size_t i = 0; i < height; ++i)\r
-                       common::image::copy(&image_.get()[i * image_width_ * 4], &pBits[i* width * 4], width * 4);\r
+                       common::copy(&image_.get()[i * image_width_ * 4], &pBits[i* width * 4], width * 4);\r
        }\r
 \r
        gpu_frame_ptr render_frame()\r
        {\r
                gpu_frame_ptr frame = factory_->create_frame(format_desc_);\r
-               common::image::clear(frame->data(), frame->size());\r
+               common::clear(frame->data(), frame->size());\r
 \r
                const int delta_x = direction_ == direction::Left ? speed_ : -speed_;\r
                const int delta_y = direction_ == direction::Up ? speed_ : -speed_;\r
@@ -125,20 +127,33 @@ struct image_scroll_producer : public frame_producer
 \r
                return frame;\r
        }\r
-\r
-       gpu_frame_ptr render_interlaced_frame()\r
-       {\r
-               gpu_frame_ptr next_frame1;\r
-               gpu_frame_ptr next_frame2;\r
-               tbb::parallel_invoke([&]{ next_frame1 = render_frame(); }, [&]{ next_frame2 = render_frame(); });\r
                \r
-               common::image::copy_field(next_frame1->data(), next_frame2->data(), format_desc_.mode == video_mode::upper ? 1 : 0, format_desc_.width, format_desc_.height);\r
-               return next_frame1;\r
-       }\r
-       \r
        gpu_frame_ptr get_frame()\r
-       {\r
-               return format_desc_.mode == video_mode::progressive ? render_frame() : render_interlaced_frame();\r
+       {               \r
+               gpu_frame_ptr result;\r
+               if(format_desc_.mode == video_mode::progressive)                                                        \r
+                       result = render_frame();                \r
+               else\r
+               {\r
+                       auto result = std::make_shared<composite_gpu_frame>(format_desc_.width, format_desc_.height);\r
+                       gpu_frame_ptr frame1;\r
+                       gpu_frame_ptr frame2;\r
+                       tbb::parallel_invoke([&]{ frame1 = render_frame(); }, [&]{ frame2 = render_frame(); });\r
+                       result->add(frame1);\r
+                       result->add(frame2);\r
+                       if(format_desc_.mode == video_mode::upper)\r
+                       {\r
+                               frame1->mode(video_mode::upper);\r
+                               frame2->mode(video_mode::lower);\r
+                       }\r
+                       else\r
+                       {\r
+                               frame1->mode(video_mode::lower);\r
+                               frame2->mode(video_mode::upper);\r
+                       }\r
+               }\r
+\r
+               return result;\r
        }\r
 \r
        \r
index 7d71f5f4a3f16b5cb173b8e50ea75c684d76256f..5c4831f8e5a6061b93762b94915aaff6fcea899c 100644 (file)
@@ -26,7 +26,7 @@
 #include "../../frame/composite_gpu_frame.h"\r
 #include "../../frame/frame_factory.h"\r
 \r
-#include "../../../common/image/image.h"\r
+#include "../../../common/utility/memory.h"\r
 #include "../../renderer/render_device.h"\r
 \r
 #include <boost/range/algorithm/copy.hpp>\r
@@ -65,7 +65,7 @@ struct transition_producer::implementation : boost::noncopyable
                if(producer == nullptr)\r
                {       \r
                        auto frame = factory_->create_frame(format_desc_);\r
-                       common::image::clear(frame->data(), frame->size());\r
+                       common::clear(frame->data(), frame->size());\r
                        return frame;\r
                }\r
 \r
@@ -114,12 +114,23 @@ struct transition_producer::implementation : boost::noncopyable
                }\r
                else if(info_.type == transition_type::slide)\r
                {\r
-                       dest_frame->translate(-1.0f+alpha, 0.0f);\r
+                       if(info_.direction == transition_direction::from_left)                  \r
+                               dest_frame->translate(-1.0f+alpha, 0.0f);                       \r
+                       else if(info_.direction == transition_direction::from_right)\r
+                               dest_frame->translate(1.0f-alpha, 0.0f);                        \r
                }\r
                else if(info_.type == transition_type::push)\r
                {\r
-                       dest_frame->translate(-1.0f+alpha, 0.0f);\r
-                       src_frame->translate(alpha, 0.0f);\r
+                       if(info_.direction == transition_direction::from_left)          \r
+                       {\r
+                               dest_frame->translate(-1.0f+alpha, 0.0f);\r
+                               src_frame->translate(0.0f+alpha, 0.0f);\r
+                       }\r
+                       else if(info_.direction == transition_direction::from_right)\r
+                       {\r
+                               dest_frame->translate(1.0f-alpha, 0.0f);\r
+                               src_frame->translate(0.0f-alpha, 0.0f);\r
+                       }\r
                }\r
                return composite;\r
        }\r
index b5550936df9d719aebfda49125d49f287c3c2e7f..343f4929d7e96b976453016cc7d6685759d2e49b 100644 (file)
@@ -1,5 +1,9 @@
 #include "..\StdAfx.h"\r
 \r
+#ifdef _MSC_VER\r
+#pragma warning (disable : 4244)\r
+#endif\r
+\r
 #include "render_device.h"\r
 #include "layer.h"\r
 \r
@@ -9,7 +13,7 @@
 #include "../frame/gpu_frame_processor.h"\r
 \r
 #include "../../common/utility/scope_exit.h"\r
-#include "../../common/image/image.h"\r
+#include "../../common/utility/memory.h"\r
 \r
 #include <numeric>\r
 \r
@@ -45,7 +49,7 @@ std::vector<gpu_frame_ptr> render_frames(std::map<int, layer>& layers)
 struct render_device::implementation : boost::noncopyable\r
 {      \r
        implementation(const caspar::frame_format_desc& format_desc, unsigned int index, const std::vector<frame_consumer_ptr>& consumers)  \r
-               : consumers_(consumers), fmt_(format_desc), frame_processor_(new gpu_frame_processor(format_desc))\r
+               : consumers_(consumers), fmt_(format_desc), frame_processor_(new gpu_frame_processor(format_desc)), needs_clock_(false)\r
        {       \r
                is_running_ = true;\r
                if(consumers.empty())\r
@@ -56,6 +60,8 @@ struct render_device::implementation : boost::noncopyable
                        BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("consumer") \r
                                                                                                                << msg_info("All consumers must have same frameformat as renderdevice."));\r
                \r
+               needs_clock_ = !std::any_of(consumers.begin(), consumers.end(), std::mem_fn(&frame_consumer::has_sync_clock));\r
+\r
                frame_buffer_.set_capacity(3);\r
                display_thread_ = boost::thread([=]{display();});\r
                render_thread_ = boost::thread([=]{render();});\r
@@ -74,7 +80,7 @@ struct render_device::implementation : boost::noncopyable
                \r
        void render()\r
        {               \r
-               CASPAR_LOG(info) << L"Started render_device::render Thread";\r
+               CASPAR_LOG(info) << L"Started render_device::render thread";\r
                win32_exception::install_handler();\r
                \r
                while(is_running_)\r
@@ -100,20 +106,46 @@ struct render_device::implementation : boost::noncopyable
                        }\r
                }\r
 \r
-               CASPAR_LOG(info) << L"Ended render_device::render Thread";\r
+               CASPAR_LOG(info) << L"Ended render_device::render thread";\r
        }\r
+\r
+       struct video_sync_clock\r
+       {\r
+               video_sync_clock(const caspar::frame_format_desc& format_desc)\r
+               {\r
+                       period_ = static_cast<long>(get_frame_format_period(format_desc)*1000000.0);\r
+                       time_ = boost::posix_time::microsec_clock::local_time();\r
+               }\r
+\r
+               void sync_video()\r
+               {\r
+                       auto remaining = boost::posix_time::microseconds(period_) - (boost::posix_time::microsec_clock::local_time() - time_);\r
+                       if(remaining > boost::posix_time::microseconds(5000))\r
+                               boost::this_thread::sleep(remaining - boost::posix_time::microseconds(5000));\r
+                       time_ = boost::posix_time::microsec_clock::local_time();\r
+               }\r
+\r
+               boost::posix_time::ptime time_;\r
+               long period_;\r
+\r
+       };\r
        \r
        void display()\r
        {\r
-               CASPAR_LOG(info) << L"Started render_device::display Thread";\r
+               CASPAR_LOG(info) << L"Started render_device::display thread";\r
                win32_exception::install_handler();\r
                                \r
                gpu_frame_ptr frame = frame_processor_->create_frame(fmt_.width, fmt_.height);\r
-               common::image::clear(frame->data(), frame->size());\r
+               common::clear(frame->data(), frame->size());\r
                std::deque<gpu_frame_ptr> prepared(3, frame);\r
+\r
+               video_sync_clock clock(fmt_);\r
                                \r
                while(is_running_)\r
                {\r
+                       if(needs_clock_)\r
+                               clock.sync_video();\r
+\r
                        if(!frame_buffer_.try_pop(frame))\r
                        {\r
                                CASPAR_LOG(trace) << "Display Buffer Underrun";\r
@@ -127,7 +159,7 @@ struct render_device::implementation : boost::noncopyable
                        }\r
                }\r
                \r
-               CASPAR_LOG(info) << L"Ended render_device::display Thread";\r
+               CASPAR_LOG(info) << L"Ended render_device::display thread";\r
        }\r
 \r
        void send_frame(const gpu_frame_ptr& prepared_frame, const gpu_frame_ptr& next_frame)\r
@@ -206,7 +238,7 @@ struct render_device::implementation : boost::noncopyable
                auto it = layers_.find(exLayer);\r
                return it != layers_.end() ? it->second.background() : nullptr;\r
        }\r
-               \r
+                       \r
        boost::thread render_thread_;\r
        boost::thread display_thread_;\r
                \r
@@ -221,6 +253,8 @@ struct render_device::implementation : boost::noncopyable
        tbb::atomic<bool> is_running_;  \r
 \r
        gpu_frame_processor_ptr frame_processor_;\r
+\r
+       bool needs_clock_;\r
 };\r
 \r
 render_device::render_device(const caspar::frame_format_desc& format_desc, unsigned int index, const std::vector<frame_consumer_ptr>& consumers) \r
@@ -234,4 +268,3 @@ frame_producer_ptr render_device::active(int exLayer) const {return impl_->activ
 frame_producer_ptr render_device::background(int exLayer) const {return impl_->background(exLayer);}\r
 const frame_format_desc& render_device::frame_format_desc() const{return impl_->fmt_;}\r
 }}\r
-\r
index 7312db42f67649cb4a1332f0eb4b946dd1b8adae..0e0bb8a88f274d9b17b7172df8e9394be64adfb9 100644 (file)
@@ -2,12 +2,12 @@
 \r
 #include "server.h"\r
 \r
-#include "consumer/oal/oal_frame_consumer.h"\r
+#include "consumer/oal/oal_consumer.h"\r
 #ifndef DISABLE_BLUEFISH\r
-#include "consumer/bluefish/BlueFishVideoConsumer.h"\r
+#include "consumer/bluefish/bluefish_consumer.h"\r
 #endif\r
 #include "consumer/decklink/DecklinkVideoConsumer.h"\r
-#include "consumer/ogl/ogl_frame_consumer.h"\r
+#include "consumer/ogl/ogl_consumer.h"\r
 \r
 #include <FreeImage.h>\r
 \r
@@ -17,7 +17,6 @@
 #include "producer/flash/FlashAxContainer.h"\r
 \r
 #include "../common/io/AsyncEventServer.h"\r
-#include "../common/io/SerialPort.h"\r
 #include "../common/utility/string_convert.h"\r
 \r
 #include <boost/algorithm/string.hpp>\r
@@ -42,14 +41,13 @@ struct server::implementation : boost::noncopyable
                setup_channels(pt);\r
                setup_controllers(pt);\r
        \r
-               if(!flash::FlashAxContainer::CheckForFlashSupport())\r
-                       CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";\r
+               //if(!flash::FlashAxContainer::CheckForFlashSupport())\r
+               //      CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled";\r
        }\r
 \r
        ~implementation()\r
        {               \r
                FreeImage_DeInitialise();\r
-               serial_ports_.clear();\r
                async_servers_.clear();\r
                channels_.clear();\r
        }\r
@@ -98,16 +96,16 @@ struct server::implementation : boost::noncopyable
                                                        stretch = ogl::stretch::uniform_to_fill;\r
 \r
                                                bool windowed = xml_consumer.second.get("windowed", false);\r
-                                               pConsumer = std::make_shared<ogl::ogl_frame_consumer>(format_desc, device, stretch, windowed);\r
+                                               pConsumer = std::make_shared<ogl::consumer>(format_desc, device, stretch, windowed);\r
                                        }\r
                                #ifndef DISABLE_BLUEFISH\r
-                                       else if(name == "bluefish")\r
-                                               pConsumer = caspar::bluefish::BlueFishVideoConsumer::Create(format_desc, xml_consumer.second.get("device", 0));\r
+                                       else if(name == "bluefish")                                     \r
+                                               pConsumer = std::make_shared<bluefish::consumer>(format_desc, xml_consumer.second.get("device", 0), xml_consumer.second.get("embedded-audio", false));                                  \r
                                #endif\r
                                        else if(name == "decklink")\r
                                                pConsumer = std::make_shared<decklink::DecklinkVideoConsumer>(format_desc, xml_consumer.second.get("internalkey", false));\r
                                        else if(name == "audio")\r
-                                               pConsumer = std::make_shared<audio::oal_frame_consumer>(format_desc);\r
+                                               pConsumer = std::make_shared<audio::consumer>(format_desc);\r
 \r
                                        if(pConsumer)                                   \r
                                                consumers.push_back(pConsumer);                                 \r
@@ -140,23 +138,6 @@ struct server::implementation : boost::noncopyable
                                        asyncserver->Start();\r
                                        async_servers_.push_back(asyncserver);\r
                                }\r
-                               else if(name == "serialcontroller")\r
-                               {\r
-                                       std::wstring portName = common::widen(xml_controller.second.get<std::string>("port-name"));                                             \r
-                                       unsigned int baudRate = xml_controller.second.get<unsigned int>("baud-rate");\r
-                                       unsigned int dataBits = xml_controller.second.get<unsigned int>("data-bits");\r
-                                       unsigned int parity = xml_controller.second.get<unsigned int>("parity");\r
-                                       unsigned int stopBits = xml_controller.second.get<unsigned int>("stop-bits");\r
-\r
-                                       baudRate =      baudRate        != 0 ? baudRate : 19200;\r
-                                       dataBits =      dataBits        != 0 ? dataBits : 8;\r
-                                       parity =        parity          != 0 ? parity   : NOPARITY;\r
-                                       stopBits =      stopBits        != 0 ? stopBits : ONESTOPBIT;\r
-                                       \r
-                                       auto serialPort = std::make_shared<IO::SerialPort>(create_protocol(protocol), baudRate, parity, dataBits, stopBits, portName, xml_controller.second.get("spy", false));\r
-                                       serialPort->Start();\r
-                                       serial_ports_.push_back(serialPort);\r
-                               }\r
                                else\r
                                        BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info(name) << msg_info("Invalid controller"));\r
                        }\r
@@ -180,7 +161,6 @@ struct server::implementation : boost::noncopyable
                BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol"));\r
        }\r
 \r
-       std::vector<IO::SerialPortPtr> serial_ports_;\r
        std::vector<IO::AsyncEventServerPtr> async_servers_;\r
 \r
        std::vector<renderer::render_device_ptr> channels_;\r
diff --git a/test/test.cpp b/test/test.cpp
new file mode 100644 (file)
index 0000000..371bf74
--- /dev/null
@@ -0,0 +1,237 @@
+#define NOMINMAX\r
+\r
+#include <functional>\r
+#include "timer.h"\r
+\r
+#include <iostream>\r
+#include <limits>\r
+#include <numeric>\r
+\r
+#include <tbb/scalable_allocator.h>\r
+#include <tbb/parallel_for.h>\r
+#include <intrin.h>\r
+       \r
+const unsigned int TEST_COUNT = 1000;\r
+const unsigned int TEST_SIZE = 1920*1080*4;\r
+\r
+void test(const std::function<void*(void*, const void*, size_t)>& func)\r
+{\r
+       size_t size = TEST_SIZE;\r
+       void* src = scalable_aligned_malloc(size, 16);\r
+       void* dest = scalable_aligned_malloc(size, 16);\r
+\r
+       timer timer;\r
+       double total_time = 0.0;\r
+       for(int i = 0 ;i < TEST_COUNT; ++i)     \r
+       {\r
+               timer.start();\r
+               func(dest, src, size);\r
+               total_time += timer.time();\r
+               if(memcmp(dest, src, size) != 0)\r
+                       std::cout << "ERROR";\r
+               memset(src, rand(), size); // flush\r
+       }\r
+\r
+       scalable_aligned_free(dest);\r
+       scalable_aligned_free(src);\r
+\r
+       double unit_time = total_time/static_cast<double>(TEST_COUNT);\r
+       std::cout << 1.0/unit_time*static_cast<double>(TEST_SIZE)/1000000000.0 << " gb/s";\r
+}\r
+\r
+void* memcpy_SSE2_1(void* dest, const void* source, size_t size)\r
+{      \r
+       __m128i* dest_128 = reinterpret_cast<__m128i*>(dest);\r
+       const __m128i* source_128 = reinterpret_cast<const __m128i*>(source);\r
+\r
+       for(size_t n = 0; n < size/16; n += 8) \r
+       {\r
+               _mm_prefetch(reinterpret_cast<const char*>(source_128+8), _MM_HINT_NTA);\r
+               _mm_prefetch(reinterpret_cast<const char*>(source_128+12), _MM_HINT_NTA);\r
+\r
+               __m128i xmm0 = _mm_load_si128(source_128++);\r
+               __m128i xmm1 = _mm_load_si128(source_128++);\r
+               __m128i xmm2 = _mm_load_si128(source_128++);\r
+               __m128i xmm3 = _mm_load_si128(source_128++);\r
+               \r
+               _mm_stream_si128(dest_128++, xmm0);\r
+               _mm_stream_si128(dest_128++, xmm1);\r
+               _mm_stream_si128(dest_128++, xmm2);\r
+               _mm_stream_si128(dest_128++, xmm3);\r
+               \r
+               __m128i xmm4 = _mm_load_si128(source_128++);\r
+               __m128i xmm5 = _mm_load_si128(source_128++);\r
+               __m128i xmm6 = _mm_load_si128(source_128++);\r
+               __m128i xmm7 = _mm_load_si128(source_128++);\r
+\r
+               _mm_stream_si128(dest_128++, xmm4);\r
+               _mm_stream_si128(dest_128++, xmm5);\r
+               _mm_stream_si128(dest_128++, xmm6);\r
+               _mm_stream_si128(dest_128++, xmm7);\r
+       }\r
+       return dest;\r
+}\r
+\r
+void* memcpy_SSE2_2(void* dest, const void* source, size_t num)\r
+{      \r
+       __asm\r
+       {\r
+               mov esi, source;    \r
+               mov edi, dest;   \r
\r
+               mov ebx, num; \r
+               shr ebx, 7;      \r
+  \r
+               cpy:\r
+                       prefetchnta [esi+80h];\r
+                       prefetchnta [esi+0A0h];\r
+                       prefetchnta [esi+0C0h];\r
+                       prefetchnta [esi+0E0h];\r
\r
+                       movdqa xmm0, [esi+00h];\r
+                       movdqa xmm1, [esi+10h];\r
+                       movdqa xmm2, [esi+20h];\r
+                       movdqa xmm3, [esi+30h];\r
+         \r
+                       movntdq [edi+00h], xmm0;\r
+                       movntdq [edi+10h], xmm1;\r
+                       movntdq [edi+20h], xmm2;\r
+                       movntdq [edi+30h], xmm3;\r
+                       \r
+                       movdqa xmm4, [esi+40h];\r
+                       movdqa xmm5, [esi+50h];\r
+                       movdqa xmm6, [esi+60h];\r
+                       movdqa xmm7, [esi+70h];\r
+         \r
+                       movntdq [edi+40h], xmm4;\r
+                       movntdq [edi+50h], xmm5;\r
+                       movntdq [edi+60h], xmm6;\r
+                       movntdq [edi+70h], xmm7;\r
\r
+                       lea edi,[edi+80h];\r
+                       lea esi,[esi+80h];\r
+                       dec ebx;\r
\r
+               jnz cpy;\r
+       }\r
+       return dest;\r
+}\r
+\r
+void* memcpy_SSE2_3(void* dest, const void* source, size_t num)\r
+{      \r
+       __asm\r
+       {\r
+               mov esi, source;    \r
+               mov edi, dest;   \r
\r
+               mov ebx, num; \r
+               shr ebx, 7;      \r
+  \r
+               cpy:\r
+                       prefetchnta [esi+80h];\r
+                       prefetchnta [esi+0C0h];\r
\r
+                       movdqa xmm0, [esi+00h];\r
+                       movdqa xmm1, [esi+10h];\r
+                       movdqa xmm2, [esi+20h];\r
+                       movdqa xmm3, [esi+30h];\r
+         \r
+                       movntdq [edi+00h], xmm0;\r
+                       movntdq [edi+10h], xmm1;\r
+                       movntdq [edi+20h], xmm2;\r
+                       movntdq [edi+30h], xmm3;\r
+                       \r
+                       movdqa xmm4, [esi+40h];\r
+                       movdqa xmm5, [esi+50h];\r
+                       movdqa xmm6, [esi+60h];\r
+                       movdqa xmm7, [esi+70h];\r
+         \r
+                       movntdq [edi+40h], xmm4;\r
+                       movntdq [edi+50h], xmm5;\r
+                       movntdq [edi+60h], xmm6;\r
+                       movntdq [edi+70h], xmm7;\r
\r
+                       lea edi, [edi+80h];\r
+                       lea esi, [esi+80h];\r
+                       dec ebx; \r
+               jnz cpy;\r
+       }\r
+       return dest;\r
+}\r
+\r
+void* memcpy_SSE2_3_tbb(void* dest, const void* source, size_t num)\r
+{      \r
+       tbb::parallel_for(tbb::blocked_range<size_t>(0, num/128), [&](const tbb::blocked_range<size_t>& r)\r
+       {\r
+               memcpy_SSE2_3(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128);\r
+       }, tbb::affinity_partitioner());\r
+\r
+       return dest;\r
+}\r
+\r
+void* X_aligned_memcpy_sse2(void* dest, const void* src, size_t size_t)\r
+{ \r
+  __asm\r
+  {\r
+    mov esi, src;    //src pointer\r
+    mov edi, dest;   //dest pointer\r
\r
+    mov ebx, size_t; //ebx is our counter \r
+    shr ebx, 7;      //divide by 128 (8 * 128bit registers)\r
\r
\r
+    loop_copy:\r
+      prefetchnta 128[ESI]; //SSE2 prefetch\r
+      prefetchnta 160[ESI];\r
+      prefetchnta 192[ESI];\r
+      prefetchnta 224[ESI];\r
\r
+      movdqa xmm0, 0[ESI]; //move data from src to registers\r
+      movdqa xmm1, 16[ESI];\r
+      movdqa xmm2, 32[ESI];\r
+      movdqa xmm3, 48[ESI];\r
+      movdqa xmm4, 64[ESI];\r
+      movdqa xmm5, 80[ESI];\r
+      movdqa xmm6, 96[ESI];\r
+      movdqa xmm7, 112[ESI];\r
\r
+      movntdq 0[EDI], xmm0; //move data from registers to dest\r
+      movntdq 16[EDI], xmm1;\r
+      movntdq 32[EDI], xmm2;\r
+      movntdq 48[EDI], xmm3;\r
+      movntdq 64[EDI], xmm4;\r
+      movntdq 80[EDI], xmm5;\r
+      movntdq 96[EDI], xmm6;\r
+      movntdq 112[EDI], xmm7;\r
\r
+      add esi, 128;\r
+      add edi, 128;\r
+      dec ebx;\r
\r
+      jnz loop_copy; //loop please\r
+  }\r
+  return dest;\r
+}\r
+\r
+int main(int argc, wchar_t* argv[])\r
+{\r
+       SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);\r
+       test(memcpy);\r
+       std::cout << " memcpy" << std::endl;\r
+       test(memcpy_SSE2_1);\r
+       std::cout << " memcpy_SSE2_1" << std::endl;\r
+       test(memcpy_SSE2_2);\r
+       std::cout << " memcpy_SSE2_2" << std::endl;\r
+       test(memcpy_SSE2_3);\r
+       std::cout << " memcpy_SSE2_3" << std::endl;\r
+       test(memcpy_SSE2_3_tbb);\r
+       std::cout << " memcpy_SSE2_3_tbb" << std::endl;\r
+       test(X_aligned_memcpy_sse2);\r
+       std::cout << " X_aligned_memcpy_sse2" << std::endl;\r
+\r
+       std::cout << "Press ENTER to continue... " << std::endl;\r
+       std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');\r
+\r
+       return 0;\r
+}\r
+\r
diff --git a/test/test.vcxproj b/test/test.vcxproj
new file mode 100644 (file)
index 0000000..1b852ea
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{CE1CD805-3904-4E58-824E-09C027585991}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>test</RootNamespace>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+    <IncludePath>..\..\dependencies\tbb30_20100406oss\include;..\..\..\dependencies\tbb30_20100406oss\include;$(IncludePath)</IncludePath>\r
+    <LibraryPath>..\..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;$(LibraryPath)</LibraryPath>\r
+    <OutDir>$(SolutionDir)\$(ProjectName)\$(Configuration)\</OutDir>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <AdditionalDependencies>tbb.lib; kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="test.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+      </PrecompiledHeaderFile>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="timer.h" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters
new file mode 100644 (file)
index 0000000..88bc9b9
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="memcpy">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="utility">\r
+      <UniqueIdentifier>{e218486c-9cba-405b-935b-6875a0b9b0d5}</UniqueIdentifier>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="test.cpp">\r
+      <Filter>memcpy</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="timer.h">\r
+      <Filter>utility</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/test/timer.h b/test/timer.h
new file mode 100644 (file)
index 0000000..046a1a5
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once\r
+\r
+#include <windows.h>\r
+\r
+class timer\r
+{\r
+public:\r
+       timer()\r
+       {\r
+               QueryPerformanceFrequency(&freq_);\r
+       }\r
+\r
+       void start()\r
+       {\r
+               QueryPerformanceCounter(&start_);\r
+       }\r
+\r
+       double time()\r
+       {\r
+               LARGE_INTEGER time_;\r
+               QueryPerformanceCounter(&time_);\r
+               return static_cast<double>(time_.QuadPart - start_.QuadPart) / static_cast<double>(freq_.QuadPart);\r
+       }\r
+\r
+private:\r
+       LARGE_INTEGER freq_;\r
+       LARGE_INTEGER start_;\r
+};
\ No newline at end of file