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
{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
<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
<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
<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
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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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(©_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(©_REF, dest, source, size);\r
-}\r
-\r
-}\r
-}\r
-}
\ No newline at end of file
+++ /dev/null
-/*\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(©_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(©_REF, dest, source, fieldIndex, width, height);\r
-}\r
-\r
-}}}
\ No newline at end of file
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
--- /dev/null
+#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
--- /dev/null
+#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
<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
\r
#define TBB_USE_THREADING_TOOLS 1\r
\r
-#define DISABLE_BLUEFISH\r
+//#define DISABLE_BLUEFISH\r
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
+++ /dev/null
-/*\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
--- /dev/null
+/*\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
*/\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
*/\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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
#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
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
\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
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
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
\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
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
};\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
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
* 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
#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
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
\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
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
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
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
*/\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
<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
<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
#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
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
#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
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
alpha_ = 1.0f;\r
x_ = 0.0f;\r
y_ = 0.0f;\r
+ mode_ = video_mode::progressive;\r
}\r
\r
gpu_frame* self_;\r
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
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
#pragma once\r
\r
+#include "frame_format.h"\r
+\r
#include <memory>\r
\r
#include <Glee.h>\r
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
};\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
#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
{\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
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
{\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
\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
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
\r
#include "audio_decoder.h"\r
\r
-#include "../../../../common/image/image.h"\r
+#include "../../../../common/utility/memory.h"\r
\r
#include <queue>\r
\r
{\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
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
#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
#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
\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
+++ /dev/null
-#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, ¶m), 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
#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
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
}\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
{ \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
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
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
\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
#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
#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
\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
\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
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
\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
#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
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
}\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
#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
#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
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
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
\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
}\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
}\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
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
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
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
\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
#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
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
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
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
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
--- /dev/null
+#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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+#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