Clean up NvFBC interfaces
This commit is contained in:
parent
80190c40af
commit
3521879ced
4 changed files with 57 additions and 59 deletions
|
@ -110,14 +110,14 @@ namespace hazelnut {
|
|||
}
|
||||
|
||||
bool NvfbcCreateInstance() {
|
||||
// Destroy an existing NVFBC session to avoid memory leak
|
||||
// Destroy an existing NvFBC instance to avoid resource leaks.
|
||||
if(nvfbc) {
|
||||
NvfbcDestroyInstance();
|
||||
}
|
||||
|
||||
DWORD maxDisplayWidth = -1;
|
||||
DWORD maxDisplayHeight = -1;
|
||||
nvfbc = (NvFBCToSys*)nvfbcLib.create(NVFBC_TO_SYS, &maxDisplayWidth, &maxDisplayHeight);
|
||||
nvfbc = nvfbcLib.CreateToSys(&maxDisplayWidth, &maxDisplayHeight);
|
||||
|
||||
if(!nvfbc) {
|
||||
return false;
|
||||
|
@ -133,22 +133,23 @@ namespace hazelnut {
|
|||
blockSize = NVFBC_TOSYS_DIFFMAP_BLOCKSIZE_32X32;
|
||||
|
||||
// set up a session
|
||||
NVFBC_TOSYS_SETUP_PARAMS fbcSysSetupParams = { 0 };
|
||||
NVFBC_TOSYS_SETUP_PARAMS fbcSysSetupParams{};
|
||||
fbcSysSetupParams.dwVersion = NVFBC_TOSYS_SETUP_PARAMS_VER;
|
||||
fbcSysSetupParams.eMode = NVFBC_TOSYS_ARGB;
|
||||
fbcSysSetupParams.bWithHWCursor = true;
|
||||
fbcSysSetupParams.ppBuffer = (void**)&pRawFramebuffer;
|
||||
fbcSysSetupParams.ppBuffer = reinterpret_cast<void**>(&pRawFramebuffer);
|
||||
|
||||
// enable a 32x32 difference map
|
||||
// enable the difference map with configured blocksize
|
||||
// (currently hardcoded to 32x32).
|
||||
fbcSysSetupParams.bDiffMap = TRUE;
|
||||
fbcSysSetupParams.ppDiffMap = (void**)&pDiffMap;
|
||||
fbcSysSetupParams.ppDiffMap = reinterpret_cast<void**>(&pDiffMap);
|
||||
fbcSysSetupParams.eDiffMapBlockSize = blockSize;
|
||||
|
||||
auto status = nvfbc->NvFBCToSysSetUp(&fbcSysSetupParams);
|
||||
if(status != NVFBC_SUCCESS)
|
||||
return false;
|
||||
|
||||
memset(&fbcSysGrabParams, 0, sizeof(NVFBC_TOSYS_GRAB_FRAME_PARAMS));
|
||||
fbcSysGrabParams = {};
|
||||
|
||||
// set up grab params
|
||||
fbcSysGrabParams.dwVersion = NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER;
|
||||
|
@ -196,11 +197,13 @@ namespace hazelnut {
|
|||
auto* pSrcData = (u8*)&pRawFramebuffer[0];
|
||||
|
||||
for(u32 y = 0; y < grabInfo.dwHeight; ++y) {
|
||||
|
||||
|
||||
// Convert to BGRA
|
||||
// FIXME: Make this SIMD. I can't into this very well
|
||||
#if 0
|
||||
usize srcStart = (y * grabInfo.dwBufferWidth) * 4;
|
||||
usize dstStart = (y * width) * 4;
|
||||
|
||||
// Convert to BGRA
|
||||
for(u32 x = 0; x < grabInfo.dwWidth * 4; x += 4) {
|
||||
pBufferData[(dstStart + x) + 0] = pSrcData[(srcStart + x) + 2]; // B
|
||||
pBufferData[(dstStart + x) + 1] = pSrcData[(srcStart + x) + 1]; // G
|
||||
|
|
|
@ -100,12 +100,12 @@ class cStreamClient {
|
|||
header.datalen = sizeof(tDataMessage);
|
||||
|
||||
// send tile header
|
||||
//bool sendFull = false;
|
||||
// bool sendFull = false;
|
||||
tDataMessage dm;
|
||||
|
||||
//if(tiles.empty()) {
|
||||
// if(tiles.empty()) {
|
||||
// sendFull = true;
|
||||
//}
|
||||
// }
|
||||
|
||||
if(sendFull) {
|
||||
dm.tileCount = 1;
|
||||
|
@ -118,7 +118,7 @@ class cStreamClient {
|
|||
dm.tileCount = 1;
|
||||
sendFull = true;
|
||||
} else {
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
// we have writev() at home
|
||||
|
@ -143,7 +143,7 @@ class cStreamClient {
|
|||
|
||||
// send header
|
||||
send(tcpSocket, (const char*)&tile_wire, (i32)sizeof(tile_wire), 0);
|
||||
// send(tcpSocket, (const char*)&tileData[0], (i32)tileData.size() * 4, 0);
|
||||
// send(tcpSocket, (const char*)&tileData[0], (i32)tileData.size() * 4, 0);
|
||||
|
||||
// send data now
|
||||
/*for (auto y = tile.y; y < tile.y + tile.height; ++y) {
|
||||
|
@ -154,7 +154,7 @@ class cStreamClient {
|
|||
} else {
|
||||
tTile tDummyTile { 0, 0, width, height };
|
||||
send(tcpSocket, (const char*)&tDummyTile, sizeof(tDummyTile), 0);
|
||||
//send(tcpSocket, (const char*)&pData[0], (i32)((width * height) * sizeof(u32)), 0);
|
||||
// send(tcpSocket, (const char*)&pData[0], (i32)((width * height) * sizeof(u32)), 0);
|
||||
}
|
||||
|
||||
send(tcpSocket, (const char*)&pData[0], (i32)((width * height) * sizeof(u32)), 0);
|
||||
|
@ -193,21 +193,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
while(true) {
|
||||
auto result = capture->CaptureFrame();
|
||||
if(result == hazelnut::DisplayCaptureResult::Ok || result == hazelnut::DisplayCaptureResult::OkButResized) {
|
||||
// Check for resize.
|
||||
if(result == hazelnut::DisplayCaptureResult::OkButResized) {
|
||||
framebuffer = capture->GetFramebufferInformation();
|
||||
diff = capture->GetDiffInformation();
|
||||
firstFrame = true;
|
||||
|
||||
client.SendResize({ framebuffer.width, framebuffer.height });
|
||||
|
||||
// send empty frame
|
||||
tiles.clear();
|
||||
client.SendData(framebuffer.pFramebuffer, framebuffer.width, framebuffer.height, tiles, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(result == hazelnut::DisplayCaptureResult::Ok) {
|
||||
tiles.clear();
|
||||
|
||||
if(firstFrame == false) {
|
||||
|
@ -230,10 +216,21 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
// send that to the server
|
||||
client.SendData(framebuffer.pFramebuffer, framebuffer.width, framebuffer.height, tiles, false);
|
||||
client.SendData(framebuffer.pFramebuffer, framebuffer.width, framebuffer.height, tiles, firstFrame == false);
|
||||
|
||||
if(firstFrame)
|
||||
firstFrame = false;
|
||||
} else if(result == hazelnut::DisplayCaptureResult::OkButResized) {
|
||||
// We resized. Notify of that
|
||||
framebuffer = capture->GetFramebufferInformation();
|
||||
diff = capture->GetDiffInformation();
|
||||
firstFrame = true;
|
||||
|
||||
client.SendResize({ framebuffer.width, framebuffer.height });
|
||||
|
||||
// send empty frame
|
||||
tiles.clear();
|
||||
client.SendData(framebuffer.pFramebuffer, framebuffer.width, framebuffer.height, tiles, true);
|
||||
} else {
|
||||
printf("Failed to capture\n");
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "nvfbc_library.hpp"
|
||||
#include "NvFBC/nvFBCToSys.h"
|
||||
|
||||
namespace {
|
||||
// Get the default NvFBC library path
|
||||
|
@ -10,6 +11,8 @@ namespace {
|
|||
|
||||
bool IsWow64() {
|
||||
#ifdef _WIN64
|
||||
// If we're built for a x64 target, we kinda can't be WOW64.
|
||||
// Statically enforce this at compile time
|
||||
return false;
|
||||
#else
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
@ -56,10 +59,6 @@ NvFBCLibrary::~NvFBCLibrary() {
|
|||
close();
|
||||
}
|
||||
|
||||
// Attempts to load NvFBC from system directory.
|
||||
// on 32-bit OS: looks for NvFBC.dll in system32
|
||||
// for 32-bit app on 64-bit OS: looks for NvFBC.dll in syswow64
|
||||
// for 64-bit app on 64-bit OS: looks for NvFBC64.dll in system32
|
||||
bool NvFBCLibrary::load() {
|
||||
if(m_handle != nullptr)
|
||||
return true;
|
||||
|
@ -67,23 +66,20 @@ bool NvFBCLibrary::load() {
|
|||
char szDefaultPath[MAX_PATH] {};
|
||||
GetNvFBCDefaultPath(&szDefaultPath[0]);
|
||||
|
||||
m_handle = ::LoadLibraryA(szDefaultPath);
|
||||
m_handle = LoadLibraryA(szDefaultPath);
|
||||
|
||||
if(NULL == m_handle) {
|
||||
fprintf(stderr, "Unable to load NvFBC.\n");
|
||||
if(m_handle == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the three functions exported by NvFBC
|
||||
pfn_create = (NvFBC_CreateFunctionExType)::GetProcAddress(m_handle, "NvFBC_CreateEx");
|
||||
pfn_set_global_flags = (NvFBC_SetGlobalFlagsType)::GetProcAddress(m_handle, "NvFBC_SetGlobalFlags");
|
||||
pfn_get_status = (NvFBC_GetStatusExFunctionType)::GetProcAddress(m_handle, "NvFBC_GetStatusEx");
|
||||
pfn_enable = (NvFBC_EnableFunctionType)::GetProcAddress(m_handle, "NvFBC_Enable");
|
||||
// Load NvFBC exports
|
||||
pfn_create = reinterpret_cast<NvFBC_CreateFunctionExType>(GetProcAddress(m_handle, "NvFBC_CreateEx"));
|
||||
pfn_set_global_flags = reinterpret_cast<NvFBC_SetGlobalFlagsType>(GetProcAddress(m_handle, "NvFBC_SetGlobalFlags"));
|
||||
pfn_get_status = reinterpret_cast<NvFBC_GetStatusExFunctionType>(GetProcAddress(m_handle, "NvFBC_GetStatusEx"));
|
||||
pfn_enable = reinterpret_cast<NvFBC_EnableFunctionType>(GetProcAddress(m_handle, "NvFBC_Enable"));
|
||||
|
||||
if((NULL == pfn_create) || (NULL == pfn_set_global_flags) || (NULL == pfn_get_status) || (NULL == pfn_enable)) {
|
||||
fprintf(stderr, "Unable to load the NvFBC function pointers.\n");
|
||||
if((pfn_create == nullptr) || (pfn_set_global_flags == nullptr) || (pfn_get_status == nullptr) || (pfn_enable == nullptr)) {
|
||||
close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -118,30 +114,25 @@ void* NvFBCLibrary::create(DWORD type, DWORD* maxWidth, DWORD* maxHeight, int ad
|
|||
return NULL;
|
||||
|
||||
NVFBCRESULT res = NVFBC_SUCCESS;
|
||||
NvFBCStatusEx status = { 0 };
|
||||
NvFBCStatusEx status{};
|
||||
status.dwVersion = NVFBC_STATUS_VER;
|
||||
status.dwAdapterIdx = adapter;
|
||||
res = getStatus(&status);
|
||||
|
||||
if(res != NVFBC_SUCCESS) {
|
||||
fprintf(stderr, "NvFBC not supported on this device + driver.\r\n");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check to see if the device and driver are supported
|
||||
if(!status.bIsCapturePossible) {
|
||||
fprintf(stderr, "Unsupported device or driver.\r\n");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check to see if an instance can be created
|
||||
if(!status.bCanCreateNow) {
|
||||
fprintf(stderr, "Unable to create an instance of NvFBC.\r\n");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NvFBCCreateParams createParams;
|
||||
memset(&createParams, 0, sizeof(createParams));
|
||||
NvFBCCreateParams createParams{};
|
||||
|
||||
createParams.dwVersion = NVFBC_CREATE_PARAMS_VER;
|
||||
createParams.dwInterfaceType = type;
|
||||
createParams.pDevice = devicePtr;
|
||||
|
@ -155,13 +146,16 @@ void* NvFBCLibrary::create(DWORD type, DWORD* maxWidth, DWORD* maxHeight, int ad
|
|||
return createParams.pNvFBC;
|
||||
}
|
||||
|
||||
INvFBCToSys_v4* NvFBCLibrary::CreateToSys(DWORD* maxWidth, DWORD* maxHeight, int adapter) {
|
||||
return static_cast<NvFBCToSys*>(create(NVFBC_TO_SYS, maxWidth, maxHeight, adapter, nullptr));
|
||||
}
|
||||
|
||||
NVFBCRESULT NvFBCLibrary::enable(NVFBC_STATE nvFBCState) {
|
||||
NVFBCRESULT res = NVFBC_SUCCESS;
|
||||
return pfn_enable(nvFBCState);
|
||||
}
|
||||
|
||||
void NvFBCLibrary::setTargetAdapter(int adapter) {
|
||||
char targetAdapter[10] = { 0 };
|
||||
char targetAdapter[10]{};
|
||||
_snprintf_s(targetAdapter, 10, 9, "%d", adapter);
|
||||
SetEnvironmentVariableA("NVFBC_TARGET_ADAPTER", targetAdapter);
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "NvFBC/nvFBC.h"
|
||||
|
||||
class INvFBCToSys_v4;
|
||||
|
||||
/// Wraps loading and using NvFBC
|
||||
class NvFBCLibrary {
|
||||
public:
|
||||
|
@ -35,6 +37,8 @@ class NvFBCLibrary {
|
|||
/// Creates an instance of the provided NvFBC type if possible.
|
||||
void* create(DWORD type, DWORD* maxWidth, DWORD* maxHeight, int adapter = 0, void* devicePtr = NULL);
|
||||
|
||||
INvFBCToSys_v4* CreateToSys(DWORD* maxWidth, DWORD* maxHeight, int adapter = 0);
|
||||
|
||||
/// enable/disable NVFBC
|
||||
NVFBCRESULT enable(NVFBC_STATE nvFBCState);
|
||||
|
||||
|
|
Loading…
Reference in a new issue