clang-format
This commit is contained in:
parent
e10261543f
commit
5f9f547db8
4 changed files with 259 additions and 273 deletions
44
.clang-format
Executable file
44
.clang-format
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
BasedOnStyle: Google
|
||||||
|
|
||||||
|
# force T* or T&
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Left
|
||||||
|
|
||||||
|
TabWidth: 4
|
||||||
|
IndentWidth: 4
|
||||||
|
UseTab: Always
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakStringLiterals: false
|
||||||
|
|
||||||
|
ColumnLimit: 150
|
||||||
|
CompactNamespaces: false
|
||||||
|
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ContinuationIndentWidth: 0
|
||||||
|
|
||||||
|
# turning this on causes major issues with initalizer lists
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
|
||||||
|
FixNamespaceComments: true
|
||||||
|
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ReflowComments: true
|
||||||
|
|
||||||
|
SortIncludes: CaseInsensitive
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeParens: Never
|
||||||
|
SpacesBeforeTrailingComments: 1
|
|
@ -1,3 +1,4 @@
|
||||||
|
// clang-format off
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
@ -11,11 +12,12 @@
|
||||||
|
|
||||||
#include "NvFBCLibrary.h"
|
#include "NvFBCLibrary.h"
|
||||||
#include <NvFBC/nvFBCToSys.h>
|
#include <NvFBC/nvFBCToSys.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
enum class MessageType : u32 {
|
enum class MessageType : u32 {
|
||||||
Resize, // tResizeMessage
|
Resize, // tResizeMessage
|
||||||
Data, // tDataMessage
|
Data, // tDataMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tMessageHeader {
|
struct tMessageHeader {
|
||||||
|
@ -45,19 +47,19 @@ struct tDataMessage {
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
struct tileRect {
|
struct tileRect {
|
||||||
u32 x, y, width, height;
|
u32 x, y, width, height;
|
||||||
};
|
};
|
||||||
|
|
||||||
// client for streamserver
|
// client for streamserver
|
||||||
class cStreamClient {
|
class cStreamClient {
|
||||||
SOCKET tcpSocket{ -1 };
|
SOCKET tcpSocket { -1 };
|
||||||
public:
|
|
||||||
|
public:
|
||||||
cStreamClient() = default;
|
cStreamClient() = default;
|
||||||
|
|
||||||
~cStreamClient() {
|
~cStreamClient() {
|
||||||
if (tcpSocket != -1) {
|
if(tcpSocket != -1) {
|
||||||
closesocket(tcpSocket);
|
closesocket(tcpSocket);
|
||||||
tcpSocket = -1;
|
tcpSocket = -1;
|
||||||
}
|
}
|
||||||
|
@ -65,17 +67,17 @@ public:
|
||||||
|
|
||||||
bool Connect(const char* address, int port) {
|
bool Connect(const char* address, int port) {
|
||||||
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (tcpSocket == -1) {
|
if(tcpSocket == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in clientSvc{};
|
sockaddr_in clientSvc {};
|
||||||
clientSvc.sin_family = AF_INET;
|
clientSvc.sin_family = AF_INET;
|
||||||
inet_pton(AF_INET, address, &clientSvc.sin_addr.s_addr);
|
inet_pton(AF_INET, address, &clientSvc.sin_addr.s_addr);
|
||||||
// clientSvc.sin_addr.s_addr = inet_addr(address);
|
// clientSvc.sin_addr.s_addr = inet_addr(address);
|
||||||
clientSvc.sin_port = htons(port);
|
clientSvc.sin_port = htons(port);
|
||||||
|
|
||||||
if (connect(tcpSocket, (SOCKADDR*)&clientSvc, sizeof(clientSvc)) == SOCKET_ERROR) {
|
if(connect(tcpSocket, (SOCKADDR*)&clientSvc, sizeof(clientSvc)) == SOCKET_ERROR) {
|
||||||
printf("No connection socket. Fuck you\n");
|
printf("No connection socket. Fuck you\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -98,21 +100,18 @@ public:
|
||||||
void SendData(const unique_buffer<u32>& data, u32 width, u32 height, const std::vector<tileRect>& tiles) {
|
void SendData(const unique_buffer<u32>& data, u32 width, u32 height, const std::vector<tileRect>& tiles) {
|
||||||
tMessageHeader header;
|
tMessageHeader header;
|
||||||
header.type = MessageType::Data;
|
header.type = MessageType::Data;
|
||||||
//header.datalen = data.get_size() * sizeof(UINT32);
|
// header.datalen = data.get_size() * sizeof(UINT32);
|
||||||
header.datalen = sizeof(tDataMessage);
|
header.datalen = sizeof(tDataMessage);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto* pData = data.data();
|
auto* pData = data.data();
|
||||||
|
|
||||||
// send tile header
|
// send tile header
|
||||||
bool sendFull = false;
|
bool sendFull = false;
|
||||||
tDataMessage dm;
|
tDataMessage dm;
|
||||||
if (tiles.empty()) {
|
if(tiles.empty()) {
|
||||||
dm.tileCount = 1;
|
dm.tileCount = 1;
|
||||||
sendFull = true;
|
sendFull = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dm.tileCount = (u32)tiles.size();
|
dm.tileCount = (u32)tiles.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,22 +120,15 @@ public:
|
||||||
send(tcpSocket, (const char*)&header, sizeof(header), 0);
|
send(tcpSocket, (const char*)&header, sizeof(header), 0);
|
||||||
send(tcpSocket, (const char*)&dm, sizeof(dm), 0);
|
send(tcpSocket, (const char*)&dm, sizeof(dm), 0);
|
||||||
|
|
||||||
|
|
||||||
// send each tile
|
// send each tile
|
||||||
if (!sendFull) {
|
if(!sendFull) {
|
||||||
for (auto& tile : tiles) {
|
for(auto& tile : tiles) {
|
||||||
tTile tile_wire{
|
tTile tile_wire { tile.x, tile.y, tile.width, tile.height };
|
||||||
tile.x,
|
|
||||||
tile.y,
|
|
||||||
tile.width,
|
|
||||||
tile.height
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<u32> data;
|
std::vector<u32> data;
|
||||||
data.resize(tile.width * tile.height * 4);
|
data.resize(tile.width * tile.height * 4);
|
||||||
|
|
||||||
for (u32 y = 0; y < tile.height; ++y) {
|
for(u32 y = 0; y < tile.height; ++y) {
|
||||||
auto* pTileLineStart = &pData[(tile.y + y) * width + tile.x];
|
auto* pTileLineStart = &pData[(tile.y + y) * width + tile.x];
|
||||||
memcpy(&data[y * tile.width], pTileLineStart, tile.width * sizeof(u32));
|
memcpy(&data[y * tile.width], pTileLineStart, tile.width * sizeof(u32));
|
||||||
}
|
}
|
||||||
|
@ -152,32 +144,25 @@ public:
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tTile tDummyTile{
|
tTile tDummyTile { 0, 0, width, height };
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
};
|
|
||||||
|
|
||||||
send(tcpSocket, (const char*)&tDummyTile, sizeof(tDummyTile), 0);
|
send(tcpSocket, (const char*)&tDummyTile, sizeof(tDummyTile), 0);
|
||||||
send(tcpSocket, (const char*)&data.data()[0], (i32)(data.get_size() * sizeof(u32)), 0);
|
send(tcpSocket, (const char*)&data.data()[0], (i32)(data.get_size() * sizeof(u32)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send(tcpSocket, (const char*)&data.data()[0], data.get_size() * sizeof(UINT32), 0);
|
||||||
//send(tcpSocket, (const char*)&data.data()[0], data.get_size() * sizeof(UINT32), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: make this a class, I've clearly got the ability to pull it into one
|
// FIXME: make this a class, I've clearly got the ability to pull it into one
|
||||||
|
|
||||||
// stuff
|
// stuff
|
||||||
NvFBCLibrary* nvfbcLibrary = nullptr;
|
NvFBCLibrary* nvfbcLibrary = nullptr;
|
||||||
NvFBCToSys *nvfbcToSys = nullptr;
|
NvFBCToSys* nvfbcToSys = nullptr;
|
||||||
|
|
||||||
// filled in by NVFBC
|
// filled in by NVFBC
|
||||||
unsigned char *frameBuffer = nullptr;
|
unsigned char* frameBuffer = nullptr;
|
||||||
unsigned char *diffMap = nullptr;
|
unsigned char* diffMap = nullptr;
|
||||||
|
|
||||||
bool nvfbcSetup() {
|
bool nvfbcSetup() {
|
||||||
//! Setup the frame grab
|
//! Setup the frame grab
|
||||||
|
@ -185,7 +170,7 @@ bool nvfbcSetup() {
|
||||||
fbcSysSetupParams.dwVersion = NVFBC_TOSYS_SETUP_PARAMS_VER;
|
fbcSysSetupParams.dwVersion = NVFBC_TOSYS_SETUP_PARAMS_VER;
|
||||||
fbcSysSetupParams.eMode = NVFBC_TOSYS_ARGB;
|
fbcSysSetupParams.eMode = NVFBC_TOSYS_ARGB;
|
||||||
fbcSysSetupParams.bWithHWCursor = true;
|
fbcSysSetupParams.bWithHWCursor = true;
|
||||||
fbcSysSetupParams.ppBuffer = (void **)&frameBuffer;
|
fbcSysSetupParams.ppBuffer = (void**)&frameBuffer;
|
||||||
|
|
||||||
// enable a 32x32 difference map
|
// enable a 32x32 difference map
|
||||||
fbcSysSetupParams.bDiffMap = TRUE;
|
fbcSysSetupParams.bDiffMap = TRUE;
|
||||||
|
@ -197,7 +182,7 @@ bool nvfbcSetup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvfbcDestroy() {
|
void nvfbcDestroy() {
|
||||||
if (nvfbcToSys) {
|
if(nvfbcToSys) {
|
||||||
nvfbcToSys->NvFBCToSysRelease();
|
nvfbcToSys->NvFBCToSysRelease();
|
||||||
diffMap = nullptr;
|
diffMap = nullptr;
|
||||||
frameBuffer = nullptr;
|
frameBuffer = nullptr;
|
||||||
|
@ -205,16 +190,15 @@ void nvfbcDestroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nvfbcCreate() {
|
bool nvfbcCreate() {
|
||||||
if (nvfbcToSys) {
|
if(nvfbcToSys) {
|
||||||
nvfbcDestroy();
|
nvfbcDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD maxDisplayWidth = -1, maxDisplayHeight = -1;
|
DWORD maxDisplayWidth = -1, maxDisplayHeight = -1;
|
||||||
|
|
||||||
//! Create an instance of NvFBCToSys
|
//! Create an instance of NvFBCToSys
|
||||||
nvfbcToSys = (NvFBCToSys *)nvfbcLibrary->create(NVFBC_TO_SYS, &maxDisplayWidth, &maxDisplayHeight);
|
nvfbcToSys = (NvFBCToSys*)nvfbcLibrary->create(NVFBC_TO_SYS, &maxDisplayWidth, &maxDisplayHeight);
|
||||||
if (!nvfbcToSys)
|
if(!nvfbcToSys) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,13 +207,13 @@ bool nvfbcCreate() {
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
WSADATA data;
|
WSADATA data;
|
||||||
if (WSAStartup(MAKEWORD(2, 2), &data) != NO_ERROR) {
|
if(WSAStartup(MAKEWORD(2, 2), &data) != NO_ERROR) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cStreamClient* client = new cStreamClient();
|
cStreamClient* client = new cStreamClient();
|
||||||
|
|
||||||
if (!client->Connect("192.168.1.149", 9438)) {
|
if(!client->Connect("192.168.1.149", 9438)) {
|
||||||
printf("conn failed\n");
|
printf("conn failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -237,12 +221,12 @@ int main(int argc, char** argv) {
|
||||||
nvfbcLibrary = new NvFBCLibrary();
|
nvfbcLibrary = new NvFBCLibrary();
|
||||||
|
|
||||||
//! Load NvFBC
|
//! Load NvFBC
|
||||||
if (!nvfbcLibrary->load()) {
|
if(!nvfbcLibrary->load()) {
|
||||||
fprintf(stderr, "Unable to load the NvFBC library\n");
|
fprintf(stderr, "Unable to load the NvFBC library\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nvfbcCreate()) {
|
if(!nvfbcCreate()) {
|
||||||
fprintf(stderr, "Unable to create an instance of NvFBC\n");
|
fprintf(stderr, "Unable to create an instance of NvFBC\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -257,14 +241,13 @@ int main(int argc, char** argv) {
|
||||||
NvFBCFrameGrabInfo grabInfo;
|
NvFBCFrameGrabInfo grabInfo;
|
||||||
unique_buffer<u32> buffer;
|
unique_buffer<u32> buffer;
|
||||||
|
|
||||||
if (nvfbcSetup())
|
if(nvfbcSetup()) {
|
||||||
{
|
|
||||||
// Sleep so that ToSysSetUp forces a framebuffer update
|
// Sleep so that ToSysSetUp forces a framebuffer update
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
|
|
||||||
NVFBC_TOSYS_GRAB_FRAME_PARAMS fbcSysGrabParams = { 0 };
|
NVFBC_TOSYS_GRAB_FRAME_PARAMS fbcSysGrabParams = { 0 };
|
||||||
|
|
||||||
std::vector<tileRect> tiles{};
|
std::vector<tileRect> tiles {};
|
||||||
|
|
||||||
// set up grab parameters
|
// set up grab parameters
|
||||||
fbcSysGrabParams.dwVersion = NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER;
|
fbcSysGrabParams.dwVersion = NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER;
|
||||||
|
@ -277,45 +260,45 @@ int main(int argc, char** argv) {
|
||||||
fbcSysGrabParams.pNvFBCFrameGrabInfo = &grabInfo;
|
fbcSysGrabParams.pNvFBCFrameGrabInfo = &grabInfo;
|
||||||
fbcSysGrabParams.dwWaitTime = 16;
|
fbcSysGrabParams.dwWaitTime = 16;
|
||||||
|
|
||||||
while (true) {
|
while(true) {
|
||||||
// Grab the frame
|
// Grab the frame
|
||||||
status = nvfbcToSys->NvFBCToSysGrabFrame(&fbcSysGrabParams);
|
status = nvfbcToSys->NvFBCToSysGrabFrame(&fbcSysGrabParams);
|
||||||
if (status == NVFBC_SUCCESS) {
|
if(status == NVFBC_SUCCESS) {
|
||||||
bRecoveryDone = FALSE;
|
bRecoveryDone = FALSE;
|
||||||
|
|
||||||
// handle resizing the buffer
|
// handle resizing the buffer
|
||||||
if (width != grabInfo.dwWidth || height != grabInfo.dwHeight) {
|
if(width != grabInfo.dwWidth || height != grabInfo.dwHeight) {
|
||||||
width = grabInfo.dwWidth;
|
width = grabInfo.dwWidth;
|
||||||
height = grabInfo.dwHeight;
|
height = grabInfo.dwHeight;
|
||||||
|
|
||||||
buffer.resize(grabInfo.dwWidth * grabInfo.dwHeight);
|
buffer.resize(grabInfo.dwWidth * grabInfo.dwHeight);
|
||||||
|
|
||||||
firstFrame = true;
|
firstFrame = true;
|
||||||
client->SendResize(tResizeMessage{ width, height });
|
client->SendResize(tResizeMessage { width, height });
|
||||||
}
|
}
|
||||||
|
|
||||||
// splat the data into an unpadded buffer
|
// splat the data into an unpadded buffer
|
||||||
// REMOVE THIS
|
// REMOVE THIS
|
||||||
for (u32 y = 0; y < grabInfo.dwHeight; ++y) {
|
for(u32 y = 0; y < grabInfo.dwHeight; ++y) {
|
||||||
memcpy(&buffer.data()[y * grabInfo.dwWidth], &frameBuffer[(y * grabInfo.dwBufferWidth) * 4], grabInfo.dwWidth * 4);
|
memcpy(&buffer.data()[y * grabInfo.dwWidth], &frameBuffer[(y * grabInfo.dwBufferWidth) * 4], grabInfo.dwWidth * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles.clear();
|
tiles.clear();
|
||||||
|
|
||||||
// diffmap
|
// diffmap
|
||||||
if (firstFrame == false) {
|
if(firstFrame == false) {
|
||||||
u32 dwDiffMapWidth = (u32)ceil((f32)width / 32);
|
u32 dwDiffMapWidth = (u32)ceil((f32)width / 32);
|
||||||
u32 dwDiffMapHeight = (u32)ceil((f32)height / 32);
|
u32 dwDiffMapHeight = (u32)ceil((f32)height / 32);
|
||||||
|
|
||||||
for (u32 y = 0; y < dwDiffMapHeight; ++y) {
|
for(u32 y = 0; y < dwDiffMapHeight; ++y) {
|
||||||
for (u32 x = 0; x < dwDiffMapWidth; ++x) {
|
for(u32 x = 0; x < dwDiffMapWidth; ++x) {
|
||||||
auto& bl = diffMap[y * dwDiffMapWidth + x];
|
auto& bl = diffMap[y * dwDiffMapWidth + x];
|
||||||
if (bl != 0) {
|
if(bl != 0) {
|
||||||
tiles.push_back(tileRect{
|
tiles.push_back(tileRect {
|
||||||
x * (width / dwDiffMapWidth), // x
|
x * (width / dwDiffMapWidth), // x
|
||||||
y * (height / dwDiffMapHeight), // y
|
y * (height / dwDiffMapHeight), // y
|
||||||
width / dwDiffMapWidth, // width
|
width / dwDiffMapWidth, // width
|
||||||
height / dwDiffMapHeight // height
|
height / dwDiffMapHeight // height
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,43 +308,40 @@ int main(int argc, char** argv) {
|
||||||
// send that to the server
|
// send that to the server
|
||||||
client->SendData(buffer, width, height, tiles);
|
client->SendData(buffer, width, height, tiles);
|
||||||
|
|
||||||
if (firstFrame)
|
if(firstFrame)
|
||||||
firstFrame = false;
|
firstFrame = false;
|
||||||
} else {
|
} else {
|
||||||
if (bRecoveryDone == TRUE) {
|
if(bRecoveryDone == TRUE) {
|
||||||
fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n");
|
fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == NVFBC_ERROR_DYNAMIC_DISABLE) {
|
if(status == NVFBC_ERROR_DYNAMIC_DISABLE) {
|
||||||
fprintf(stderr, "NvFBC disabled. Quitting\n");
|
fprintf(stderr, "NvFBC disabled. Quitting\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to recover the session
|
// Try to recover the session
|
||||||
if (status == NVFBC_ERROR_INVALIDATED_SESSION) {
|
if(status == NVFBC_ERROR_INVALIDATED_SESSION) {
|
||||||
fprintf(stderr, "Session Invalidated. Attempting recovery\n");
|
fprintf(stderr, "Session Invalidated. Attempting recovery\n");
|
||||||
|
|
||||||
if (!nvfbcCreate()) {
|
if(!nvfbcCreate()) {
|
||||||
fprintf(stderr, "Unable to re-create NvFBC\n");
|
fprintf(stderr, "Unable to re-create NvFBC\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvfbcSetup()) {
|
if(nvfbcSetup()) {
|
||||||
bRecoveryDone = TRUE;
|
bRecoveryDone = TRUE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n");
|
fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != NVFBC_SUCCESS)
|
if(status != NVFBC_SUCCESS) {
|
||||||
{
|
|
||||||
fprintf(stderr, "Unable to setup frame grab.\n");
|
fprintf(stderr, "Unable to setup frame grab.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,236 +3,199 @@
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
#define WINDOWS_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "NvFBC/nvFBC.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "NvFBC/nvFBC.h"
|
||||||
|
|
||||||
|
|
||||||
#define NVFBC64_LIBRARY_NAME "NvFBC64.dll"
|
#define NVFBC64_LIBRARY_NAME "NvFBC64.dll"
|
||||||
#define NVFBC_LIBRARY_NAME "NvFBC.dll"
|
#define NVFBC_LIBRARY_NAME "NvFBC.dll"
|
||||||
|
|
||||||
// Wraps loading and using NvFBC
|
// Wraps loading and using NvFBC
|
||||||
class NvFBCLibrary
|
class NvFBCLibrary {
|
||||||
{
|
NvFBCLibrary(const NvFBCLibrary&);
|
||||||
NvFBCLibrary(const NvFBCLibrary &);
|
NvFBCLibrary& operator=(const NvFBCLibrary&);
|
||||||
NvFBCLibrary &operator=(const NvFBCLibrary &);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NvFBCLibrary()
|
NvFBCLibrary() : m_handle(NULL), pfn_get_status(NULL), pfn_create(NULL), pfn_enable(NULL) {}
|
||||||
: m_handle(NULL)
|
|
||||||
, pfn_get_status(NULL)
|
|
||||||
, pfn_create(NULL)
|
|
||||||
, pfn_enable(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~NvFBCLibrary()
|
~NvFBCLibrary() {
|
||||||
{
|
if(NULL != m_handle)
|
||||||
if(NULL != m_handle)
|
close();
|
||||||
close();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Attempts to load NvFBC from system directory.
|
// Attempts to load NvFBC from system directory.
|
||||||
// on 32-bit OS: looks for NvFBC.dll in system32
|
// 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 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
|
// for 64-bit app on 64-bit OS: looks for NvFBC64.dll in system32
|
||||||
bool load(std::string fileName = std::string())
|
bool load(std::string fileName = std::string()) {
|
||||||
{
|
if(NULL != m_handle)
|
||||||
if(NULL != m_handle)
|
return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
if(!fileName.empty())
|
if(!fileName.empty())
|
||||||
m_handle = ::LoadLibraryA(fileName.c_str());
|
m_handle = ::LoadLibraryA(fileName.c_str());
|
||||||
|
|
||||||
if(NULL == m_handle)
|
if(NULL == m_handle) {
|
||||||
{
|
m_handle = ::LoadLibraryA(getDefaultPath().c_str());
|
||||||
m_handle = ::LoadLibraryA(getDefaultPath().c_str());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(NULL == m_handle)
|
if(NULL == m_handle) {
|
||||||
{
|
fprintf(stderr, "Unable to load NvFBC.\n");
|
||||||
fprintf(stderr, "Unable to load NvFBC.\n");
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Load the three functions exported by NvFBC
|
// Load the three functions exported by NvFBC
|
||||||
pfn_create = (NvFBC_CreateFunctionExType)::GetProcAddress(m_handle, "NvFBC_CreateEx");
|
pfn_create = (NvFBC_CreateFunctionExType)::GetProcAddress(m_handle, "NvFBC_CreateEx");
|
||||||
pfn_set_global_flags = (NvFBC_SetGlobalFlagsType)::GetProcAddress(m_handle, "NvFBC_SetGlobalFlags");
|
pfn_set_global_flags = (NvFBC_SetGlobalFlagsType)::GetProcAddress(m_handle, "NvFBC_SetGlobalFlags");
|
||||||
pfn_get_status = (NvFBC_GetStatusExFunctionType)::GetProcAddress(m_handle, "NvFBC_GetStatusEx");
|
pfn_get_status = (NvFBC_GetStatusExFunctionType)::GetProcAddress(m_handle, "NvFBC_GetStatusEx");
|
||||||
pfn_enable = (NvFBC_EnableFunctionType)::GetProcAddress(m_handle,"NvFBC_Enable");
|
pfn_enable = (NvFBC_EnableFunctionType)::GetProcAddress(m_handle, "NvFBC_Enable");
|
||||||
|
|
||||||
if((NULL == pfn_create) || (NULL == pfn_set_global_flags) || (NULL == pfn_get_status) || (NULL == pfn_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");
|
||||||
fprintf(stderr, "Unable to load the NvFBC function pointers.\n");
|
close();
|
||||||
close();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the NvFBC dll
|
// Close the NvFBC dll
|
||||||
void close()
|
void close() {
|
||||||
{
|
if(NULL != m_handle)
|
||||||
if(NULL != m_handle)
|
FreeLibrary(m_handle);
|
||||||
FreeLibrary(m_handle);
|
|
||||||
|
|
||||||
m_handle = NULL;
|
m_handle = NULL;
|
||||||
pfn_create = NULL;
|
pfn_create = NULL;
|
||||||
pfn_get_status = NULL;
|
pfn_get_status = NULL;
|
||||||
pfn_enable = NULL;
|
pfn_enable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the status for the provided adapter, if no adapter is
|
// Get the status for the provided adapter, if no adapter is
|
||||||
// provided the default adapter is used.
|
// provided the default adapter is used.
|
||||||
NVFBCRESULT getStatus(NvFBCStatusEx *status)
|
NVFBCRESULT getStatus(NvFBCStatusEx* status) { return pfn_get_status((void*)status); }
|
||||||
{
|
|
||||||
return pfn_get_status((void*)status);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the global flags for the provided adapter, if
|
// Sets the global flags for the provided adapter, if
|
||||||
// no adapter is provided the default adapter is used
|
// no adapter is provided the default adapter is used
|
||||||
void setGlobalFlags(DWORD flags, int adapter = 0)
|
void setGlobalFlags(DWORD flags, int adapter = 0) {
|
||||||
{
|
setTargetAdapter(adapter);
|
||||||
setTargetAdapter(adapter);
|
pfn_set_global_flags(flags);
|
||||||
pfn_set_global_flags(flags);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Creates an instance of the provided NvFBC type if possible
|
// Creates an instance of the provided NvFBC type if possible
|
||||||
NVFBCRESULT createEx(NvFBCCreateParams *pParams)
|
NVFBCRESULT createEx(NvFBCCreateParams* pParams) { return pfn_create((void*)pParams); }
|
||||||
{
|
// Creates an instance of the provided NvFBC type if possible.
|
||||||
return pfn_create((void *)pParams);
|
void* create(DWORD type, DWORD* maxWidth, DWORD* maxHeight, int adapter = 0, void* devicePtr = NULL) {
|
||||||
}
|
if(NULL == m_handle)
|
||||||
// Creates an instance of the provided NvFBC type if possible.
|
return NULL;
|
||||||
void *create(DWORD type, DWORD *maxWidth, DWORD *maxHeight, int adapter = 0, void *devicePtr = NULL)
|
|
||||||
{
|
|
||||||
if(NULL == m_handle)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
NVFBCRESULT res = NVFBC_SUCCESS;
|
NVFBCRESULT res = NVFBC_SUCCESS;
|
||||||
NvFBCStatusEx status = {0};
|
NvFBCStatusEx status = { 0 };
|
||||||
status.dwVersion = NVFBC_STATUS_VER;
|
status.dwVersion = NVFBC_STATUS_VER;
|
||||||
status.dwAdapterIdx = adapter;
|
status.dwAdapterIdx = adapter;
|
||||||
res = getStatus(&status);
|
res = getStatus(&status);
|
||||||
|
|
||||||
if (res != NVFBC_SUCCESS)
|
if(res != NVFBC_SUCCESS) {
|
||||||
{
|
fprintf(stderr, "NvFBC not supported on this device + driver.\r\n");
|
||||||
fprintf(stderr, "NvFBC not supported on this device + driver.\r\n");
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if the device and driver are supported
|
// Check to see if the device and driver are supported
|
||||||
if(!status.bIsCapturePossible)
|
if(!status.bIsCapturePossible) {
|
||||||
{
|
fprintf(stderr, "Unsupported device or driver.\r\n");
|
||||||
fprintf(stderr, "Unsupported device or driver.\r\n");
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if an instance can be created
|
// Check to see if an instance can be created
|
||||||
if(!status.bCanCreateNow)
|
if(!status.bCanCreateNow) {
|
||||||
{
|
fprintf(stderr, "Unable to create an instance of NvFBC.\r\n");
|
||||||
fprintf(stderr, "Unable to create an instance of NvFBC.\r\n");
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NvFBCCreateParams createParams;
|
NvFBCCreateParams createParams;
|
||||||
memset(&createParams, 0, sizeof(createParams));
|
memset(&createParams, 0, sizeof(createParams));
|
||||||
createParams.dwVersion = NVFBC_CREATE_PARAMS_VER;
|
createParams.dwVersion = NVFBC_CREATE_PARAMS_VER;
|
||||||
createParams.dwInterfaceType = type;
|
createParams.dwInterfaceType = type;
|
||||||
createParams.pDevice = devicePtr;
|
createParams.pDevice = devicePtr;
|
||||||
createParams.dwAdapterIdx = adapter;
|
createParams.dwAdapterIdx = adapter;
|
||||||
|
|
||||||
res = pfn_create(&createParams);
|
res = pfn_create(&createParams);
|
||||||
|
|
||||||
*maxWidth = createParams.dwMaxDisplayWidth;
|
|
||||||
*maxHeight = createParams.dwMaxDisplayHeight;
|
|
||||||
|
|
||||||
return createParams.pNvFBC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable/disable NVFBC
|
*maxWidth = createParams.dwMaxDisplayWidth;
|
||||||
void enable(NVFBC_STATE nvFBCState)
|
*maxHeight = createParams.dwMaxDisplayHeight;
|
||||||
{
|
|
||||||
NVFBCRESULT res = NVFBC_SUCCESS;
|
|
||||||
res = pfn_enable(nvFBCState);
|
|
||||||
|
|
||||||
if (res != NVFBC_SUCCESS)
|
return createParams.pNvFBC;
|
||||||
{
|
}
|
||||||
fprintf(stderr, "Failed to %s. Insufficient privilege\n", nvFBCState == 0?"disable":"enable");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stdout, "NvFBC is %s\n", nvFBCState == 0 ? "disabled" : "enabled");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
// enable/disable NVFBC
|
||||||
// Get the default NvFBC library path
|
void enable(NVFBC_STATE nvFBCState) {
|
||||||
typedef BOOL (WINAPI *pfnIsWow64Process) (HANDLE, PBOOL);
|
NVFBCRESULT res = NVFBC_SUCCESS;
|
||||||
pfnIsWow64Process fnIsWow64Process;
|
res = pfn_enable(nvFBCState);
|
||||||
|
|
||||||
BOOL IsWow64()
|
if(res != NVFBC_SUCCESS) {
|
||||||
{
|
fprintf(stderr, "Failed to %s. Insufficient privilege\n", nvFBCState == 0 ? "disable" : "enable");
|
||||||
BOOL bIsWow64 = FALSE;
|
return;
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "NvFBC is %s\n", nvFBCState == 0 ? "disabled" : "enabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fnIsWow64Process = (pfnIsWow64Process) GetProcAddress(
|
protected:
|
||||||
GetModuleHandle(TEXT("kernel32.dll")),"IsWow64Process");
|
// Get the default NvFBC library path
|
||||||
|
typedef BOOL(WINAPI* pfnIsWow64Process)(HANDLE, PBOOL);
|
||||||
if (NULL != fnIsWow64Process)
|
pfnIsWow64Process fnIsWow64Process;
|
||||||
{
|
|
||||||
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
|
|
||||||
{
|
|
||||||
bIsWow64 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bIsWow64;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getDefaultPath()
|
BOOL IsWow64() {
|
||||||
{
|
BOOL bIsWow64 = FALSE;
|
||||||
std::string defaultPath;
|
|
||||||
|
|
||||||
size_t pathSize;
|
fnIsWow64Process = (pfnIsWow64Process)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "IsWow64Process");
|
||||||
char *libPath;
|
|
||||||
|
|
||||||
if(0 != _dupenv_s(&libPath, &pathSize, "SystemRoot"))
|
if(NULL != fnIsWow64Process) {
|
||||||
{
|
if(!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
|
||||||
fprintf(stderr, "Unable to get the SystemRoot environment variable\n");
|
bIsWow64 = false;
|
||||||
return defaultPath;
|
}
|
||||||
}
|
}
|
||||||
|
return bIsWow64;
|
||||||
|
}
|
||||||
|
|
||||||
if(0 == pathSize)
|
std::string getDefaultPath() {
|
||||||
{
|
std::string defaultPath;
|
||||||
fprintf(stderr, "The SystemRoot environment variable is not set\n");
|
|
||||||
return defaultPath;
|
size_t pathSize;
|
||||||
}
|
char* libPath;
|
||||||
|
|
||||||
|
if(0 != _dupenv_s(&libPath, &pathSize, "SystemRoot")) {
|
||||||
|
fprintf(stderr, "Unable to get the SystemRoot environment variable\n");
|
||||||
|
return defaultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 == pathSize) {
|
||||||
|
fprintf(stderr, "The SystemRoot environment variable is not set\n");
|
||||||
|
return defaultPath;
|
||||||
|
}
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
defaultPath = std::string(libPath) + "\\System32\\" + NVFBC64_LIBRARY_NAME;
|
defaultPath = std::string(libPath) + "\\System32\\" + NVFBC64_LIBRARY_NAME;
|
||||||
#else
|
#else
|
||||||
if (IsWow64())
|
if(IsWow64()) {
|
||||||
{
|
defaultPath = std::string(libPath) + "\\Syswow64\\" + NVFBC_LIBRARY_NAME;
|
||||||
defaultPath = std::string(libPath) + "\\Syswow64\\" + NVFBC_LIBRARY_NAME;
|
} else {
|
||||||
}
|
defaultPath = std::string(libPath) + "\\System32\\" + NVFBC_LIBRARY_NAME;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
defaultPath = std::string(libPath) + "\\System32\\" + NVFBC_LIBRARY_NAME;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return defaultPath;
|
return defaultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTargetAdapter(int adapter = 0)
|
void setTargetAdapter(int adapter = 0) {
|
||||||
{
|
char targetAdapter[10] = { 0 };
|
||||||
char targetAdapter[10] = {0};
|
_snprintf_s(targetAdapter, 10, 9, "%d", adapter);
|
||||||
_snprintf_s(targetAdapter, 10, 9, "%d", adapter);
|
SetEnvironmentVariableA("NVFBC_TARGET_ADAPTER", targetAdapter);
|
||||||
SetEnvironmentVariableA("NVFBC_TARGET_ADAPTER", targetAdapter);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
protected:
|
||||||
protected:
|
HMODULE m_handle;
|
||||||
HMODULE m_handle;
|
NvFBC_GetStatusExFunctionType pfn_get_status;
|
||||||
NvFBC_GetStatusExFunctionType pfn_get_status;
|
NvFBC_SetGlobalFlagsType pfn_set_global_flags;
|
||||||
NvFBC_SetGlobalFlagsType pfn_set_global_flags;
|
NvFBC_CreateFunctionExType pfn_create;
|
||||||
NvFBC_CreateFunctionExType pfn_create;
|
NvFBC_EnableFunctionType pfn_enable;
|
||||||
NvFBC_EnableFunctionType pfn_enable;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,11 +16,12 @@ using f32 = float;
|
||||||
using f64 = double;
|
using f64 = double;
|
||||||
|
|
||||||
/// like vector<T> but doesn't grow on its own
|
/// like vector<T> but doesn't grow on its own
|
||||||
template<class T>
|
template <class T>
|
||||||
struct unique_buffer {
|
struct unique_buffer {
|
||||||
T* m_buffer;
|
T* m_buffer;
|
||||||
size_t size;
|
size_t size;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
unique_buffer() {
|
unique_buffer() {
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -30,20 +31,18 @@ public:
|
||||||
unique_buffer(const unique_buffer&) = delete;
|
unique_buffer(const unique_buffer&) = delete;
|
||||||
unique_buffer(unique_buffer&&) = delete;
|
unique_buffer(unique_buffer&&) = delete;
|
||||||
|
|
||||||
~unique_buffer() {
|
~unique_buffer() { resize(0); }
|
||||||
resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t get_size() const { return this->size; }
|
size_t get_size() const { return this->size; }
|
||||||
|
|
||||||
void resize(size_t new_size) {
|
void resize(size_t new_size) {
|
||||||
if (m_buffer) {
|
if(m_buffer) {
|
||||||
delete[] m_buffer;
|
delete[] m_buffer;
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_size) {
|
if(new_size) {
|
||||||
m_buffer = new T[new_size];
|
m_buffer = new T[new_size];
|
||||||
size = new_size;
|
size = new_size;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue