[host] added multithreaded memcopy implementation

This commit is contained in:
Geoffrey McRae 2017-11-01 02:15:47 +11:00
parent de8403dcd6
commit 9ac3cadc7d
6 changed files with 141 additions and 2 deletions

View File

@ -123,12 +123,21 @@ namespace Capture
m_grabFrameParams.eGMode = NVFBC_TOSYS_SOURCEMODE_SCALE; m_grabFrameParams.eGMode = NVFBC_TOSYS_SOURCEMODE_SCALE;
m_grabFrameParams.pNvFBCFrameGrabInfo = &m_grabInfo; m_grabFrameParams.pNvFBCFrameGrabInfo = &m_grabInfo;
if (!m_memcpy.Initialize())
{
DEBUG_ERROR("Failed to initialize MTMemcpy");
DeInitialize();
return false;
}
m_initialized = true; m_initialized = true;
return true; return true;
} }
void NvFBC::DeInitialize() void NvFBC::DeInitialize()
{ {
m_memcpy.DeInitialize();
m_frameBuffer = NULL; m_frameBuffer = NULL;
if (m_nvFBC) if (m_nvFBC)
@ -197,7 +206,11 @@ namespace Capture
frame.height = m_grabInfo.dwHeight; frame.height = m_grabInfo.dwHeight;
frame.stride = m_grabInfo.dwBufferWidth; frame.stride = m_grabInfo.dwBufferWidth;
frame.outSize = m_grabInfo.dwBufferWidth * m_grabInfo.dwHeight * 3; frame.outSize = m_grabInfo.dwBufferWidth * m_grabInfo.dwHeight * 3;
memcpy(frame.buffer, m_frameBuffer, frame.outSize); if (!m_memcpy.Copy(frame.buffer, m_frameBuffer, frame.outSize))
{
DEBUG_ERROR("Memory copy failed");
return false;
}
return true; return true;
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ICapture.h" #include "ICapture.h"
#include "MTMemcpy.h"
#define W32_LEAN_AND_MEAN #define W32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
@ -24,7 +25,8 @@ namespace Capture
private: private:
bool m_initialized; bool m_initialized;
HMODULE m_hDLL; HMODULE m_hDLL;
MTMemcpy m_memcpy;
NvFBC_CreateFunctionExType m_fnCreateEx; NvFBC_CreateFunctionExType m_fnCreateEx;
NvFBC_SetGlobalFlagsType m_fnSetGlobalFlags; NvFBC_SetGlobalFlagsType m_fnSetGlobalFlags;

79
host/MTMemcpy.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "MTMemcpy.h"
MTMemcpy::MTMemcpy() :
m_initialized(false)
{
}
MTMemcpy::~MTMemcpy()
{
DeInitialize();
}
DWORD WINAPI MTMemcpy::thread_copy_proc(LPVOID param)
{
mt_cpy_t * p = (mt_cpy_t *)param;
while (1)
{
WaitForSingleObject(p->s->hCopyStartSemaphores[p->ct], INFINITE);
memcpy(p->dest, p->src, p->size);
ReleaseSemaphore(p->s->hCopyStopSemaphores[p->ct], 1, NULL);
}
return 0;
}
bool MTMemcpy::Initialize()
{
if (m_initialized)
DeInitialize();
for (int ctr = 0; ctr < NUM_CPY_THREADS; ctr++)
{
hCopyStartSemaphores[ctr] = CreateSemaphore(NULL, 0, 1, NULL);
hCopyStopSemaphores[ctr] = CreateSemaphore(NULL, 0, 1, NULL);
mtParamters[ctr].s = this;
mtParamters[ctr].ct = ctr;
hCopyThreads[ctr] = CreateThread(0, 0, thread_copy_proc, &mtParamters[ctr], 0, NULL);
}
m_initialized = true;
return true;
}
bool MTMemcpy::Copy(void * dest, void * src, size_t bytes)
{
if (!m_initialized)
return false;
//set up parameters
for (int ctr = 0; ctr < NUM_CPY_THREADS; ctr++)
{
mtParamters[ctr].dest = (char *)dest + ctr * bytes / NUM_CPY_THREADS;
mtParamters[ctr].src = (char *)src + ctr * bytes / NUM_CPY_THREADS;
mtParamters[ctr].size = (ctr + 1) * bytes / NUM_CPY_THREADS - ctr * bytes / NUM_CPY_THREADS;
ReleaseSemaphore(hCopyStartSemaphores[ctr], 1, NULL);
}
//wait for all threads to finish
WaitForMultipleObjects(NUM_CPY_THREADS, hCopyStopSemaphores, TRUE, INFINITE);
return true;
}
void MTMemcpy::DeInitialize()
{
if (!m_initialized)
return;
for (int ctr = 0; ctr < NUM_CPY_THREADS; ctr++)
{
TerminateThread(hCopyThreads[ctr], 0);
CloseHandle(hCopyStartSemaphores[ctr]);
CloseHandle(hCopyStopSemaphores[ctr]);
}
m_initialized = false;
}

37
host/MTMemcpy.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#define W32_LEAN_AND_MEAN
#include <Windows.h>
#define NUM_CPY_THREADS 4
class MTMemcpy
{
public:
bool MTMemcpy::Initialize();
void MTMemcpy::DeInitialize();
bool MTMemcpy::Copy(void * dest, void * src, size_t bytes);
MTMemcpy();
~MTMemcpy();
private:
bool m_initialized;
static DWORD WINAPI MTMemcpy::thread_copy_proc(LPVOID param);
typedef struct
{
MTMemcpy * s;
int ct;
void * src;
void * dest;
size_t size;
}
mt_cpy_t;
HANDLE hCopyThreads[NUM_CPY_THREADS] = { 0 };
HANDLE hCopyStartSemaphores[NUM_CPY_THREADS] = { 0 };
HANDLE hCopyStopSemaphores[NUM_CPY_THREADS] = { 0 };
mt_cpy_t mtParamters[NUM_CPY_THREADS] = { 0 };
};

View File

@ -163,6 +163,7 @@
<ClCompile Include="Capture\NvFBC.cpp" /> <ClCompile Include="Capture\NvFBC.cpp" />
<ClCompile Include="ivshmem.cpp" /> <ClCompile Include="ivshmem.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="MTMemcpy.cpp" />
<ClCompile Include="Service.cpp" /> <ClCompile Include="Service.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -170,6 +171,7 @@
<ClInclude Include="Capture\NvFBC.h" /> <ClInclude Include="Capture\NvFBC.h" />
<ClInclude Include="ICapture.h" /> <ClInclude Include="ICapture.h" />
<ClInclude Include="ivshmem.h" /> <ClInclude Include="ivshmem.h" />
<ClInclude Include="MTMemcpy.h" />
<ClInclude Include="Service.h" /> <ClInclude Include="Service.h" />
<ClInclude Include="Util.h" /> <ClInclude Include="Util.h" />
</ItemGroup> </ItemGroup>

View File

@ -33,6 +33,9 @@
<ClCompile Include="Capture\NvFBC.cpp"> <ClCompile Include="Capture\NvFBC.cpp">
<Filter>Source Files\Capture</Filter> <Filter>Source Files\Capture</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="MTMemcpy.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ivshmem.h"> <ClInclude Include="ivshmem.h">
@ -53,5 +56,8 @@
<ClInclude Include="Util.h"> <ClInclude Include="Util.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MTMemcpy.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>