Listen local control port to control some settings.

Many debug codes.
This commit is contained in:
polygraphene 2018-05-19 02:39:29 +09:00
parent 9a92d5708f
commit 6e7e657706
14 changed files with 424 additions and 264 deletions

View File

@ -0,0 +1,119 @@
#include <WS2tcpip.h>
#include "ControlSocket.h"
#include "Logger.h"
ControlSocket::ControlSocket(std::string host, int port, std::shared_ptr<Poller> poller) :
m_Host(host)
, m_Port(port)
, m_Poller(poller)
, m_Socket(INVALID_SOCKET)
, m_ClientSocket(INVALID_SOCKET)
{
}
ControlSocket::~ControlSocket() {
}
void ControlSocket::Startup() {
m_Socket = socket(AF_INET, SOCK_STREAM, 0);
if (m_Socket == INVALID_SOCKET) {
return;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(m_Port);
inet_pton(AF_INET, m_Host.c_str(), &addr.sin_addr);
if (bind(m_Socket, (sockaddr *)&addr, sizeof(addr))) {
Log("ControlSocket::Startup bind error : %d", WSAGetLastError());
return;
}
if (listen(m_Socket, 10)) {
Log("ControlSocket::Startup listen error : %d", WSAGetLastError());
return;
}
m_Poller->AddSocket(m_Socket);
}
void ControlSocket::Accept() {
if (!m_Poller->IsPending(m_Socket)) {
return;
}
sockaddr_in addr;
int len = sizeof(addr);
SOCKET s = accept(m_Socket, (sockaddr *)&addr, &len);
uint32_t local_addr;
inet_pton(AF_INET, "127.0.0.1", &local_addr);
if (addr.sin_addr.S_un.S_addr != local_addr) {
// block connection
closesocket(s);
return;
}
if (m_ClientSocket != INVALID_SOCKET) {
Log("Closing old control client");
m_Buf = "";
CloseClient();
}
m_ClientSocket = s;
m_Poller->AddSocket(m_ClientSocket);
}
bool ControlSocket::Recv(std::vector<std::string> &commands) {
if (m_ClientSocket == INVALID_SOCKET || !m_Poller->IsPending(m_ClientSocket)) {
return false;
}
char buf[1000];
int ret = recv(m_ClientSocket, buf, sizeof(buf), 0);
if (ret == 0) {
Log("Control connection has closed");
m_Buf = "";
CloseClient();
return false;
}
if (ret < 0) {
Log("Error on recv. close control client: %d", WSAGetLastError());
m_Buf = "";
CloseClient();
return false;
}
buf[ret] = 0;
m_Buf += buf;
Log("Control buf: %s", m_Buf.c_str());
int index;
while ((index = m_Buf.find("\n")) != -1) {
commands.push_back(m_Buf.substr(0, index));
m_Buf.replace(0, index + 1, "");
}
return commands.size() > 0;
}
void ControlSocket::CloseClient() {
if (m_ClientSocket != INVALID_SOCKET) {
m_Poller->RemoveSocket(m_ClientSocket);
closesocket(m_ClientSocket);
m_ClientSocket = INVALID_SOCKET;
}
}
void ControlSocket::Shutdown() {
CloseClient();
if (m_Socket != INVALID_SOCKET) {
m_Poller->RemoveSocket(m_Socket);
closesocket(m_Socket);
m_Socket = INVALID_SOCKET;
}
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <WinSock2.h>
#include <memory>
#include <string>
#include <vector>
#include "Poller.h"
class ControlSocket {
public:
ControlSocket(std::string host, int port, std::shared_ptr<Poller> poller);
~ControlSocket();
void Startup();
void Accept();
bool Recv(std::vector<std::string> &commands);
void CloseClient();
void Shutdown();
private:
std::string m_Host;
int m_Port;
std::shared_ptr<Poller> m_Poller;
SOCKET m_Socket;
SOCKET m_ClientSocket;
std::string m_Buf;
};

View File

@ -3,7 +3,6 @@
class ISocket {
public:
virtual bool Startup() = 0;
virtual bool Poll() = 0;
virtual bool NewClient(std::string &host, int &port) = 0;
virtual bool Recv(char *buf, int *buflen) = 0;
virtual bool Send(char *buf, int len) = 0;

View File

@ -12,6 +12,8 @@
#include "SrtSocket.h"
#include "UdpSocket.h"
#include "Utils.h"
#include "Poller.h"
#include "ControlSocket.h"
class Listener : public CThread {
public:
@ -75,16 +77,24 @@ public:
uint64_t serverTime;
uint64_t clientTime;
};
struct ChangeSettings {
uint32_t type; // 4
uint32_t enableTestMode;
};
#pragma pack(pop)
Listener(std::string host, int port, std::string SrtOptions, std::function<void(sockaddr_in *)> callback, std::function<void()> poseCallback) : m_bExiting(false)
Listener(std::string host, int port, std::string control_host, int control_port, std::string SrtOptions, std::function<void(sockaddr_in *)> callback, std::function<void()> poseCallback) : m_bExiting(false)
//, m_Socket(host, port, SrtOptions) {
{
m_LastSeen = 0;
m_NewClientCallback = callback;
m_PoseUpdatedCallback = poseCallback;
memset(&m_TrackingInfo, 0, sizeof(m_TrackingInfo));
m_Socket.reset(new UdpSocket(host, port));
m_Poller.reset(new Poller());
m_Socket.reset(new UdpSocket(host, port, m_Poller));
m_ControlSocket.reset(new ControlSocket(control_host, control_port, m_Poller));
m_UseUdp = true;
}
@ -93,11 +103,14 @@ public:
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
m_Socket->Startup();
m_ControlSocket->Startup();
while (!m_bExiting) {
if (!m_Socket->Poll()) {
m_Socket->CheckTimeout();
if (m_Poller->Do() <= 0) {
continue;
}
char buf[2000];
int len = sizeof(buf);
if (m_Socket->Recv(buf, &len)) {
@ -150,6 +163,22 @@ public:
m_NewClientCallback(&m_Socket->GetClientAddr());
}
m_ControlSocket->Accept();
std::vector<std::string> commands;
if (m_ControlSocket->Recv(commands)) {
for (auto it = commands.begin(); it != commands.end(); ++it) {
if (*it == "EnableTestMode 0") {
SendChangeSettings(0);
}else if (*it == "EnableTestMode 1") {
SendChangeSettings(1);
}else if (*it == "EnableTestMode 2") {
SendChangeSettings(2);
}
else {
}
}
}
}
}
@ -198,10 +227,22 @@ public:
}
}
void SendChangeSettings(int EnableTestMode) {
ChangeSettings settings;
settings.type = 4;
settings.enableTestMode = EnableTestMode;
if (!m_Socket->IsClientValid()) {
return;
}
m_Socket->Send((char *)&settings, sizeof(settings));
}
void Stop()
{
m_bExiting = true;
m_Socket->Shutdown();
m_ControlSocket->Shutdown();
Join();
}
@ -224,7 +265,9 @@ public:
private:
bool m_bExiting;
bool m_UseUdp;
std::shared_ptr<ISocket> m_Socket;
std::shared_ptr<Poller> m_Poller;
std::shared_ptr<UdpSocket> m_Socket;
std::shared_ptr<ControlSocket> m_ControlSocket;
// Maximum SRT(or UDP) payload is PACKET_SIZE + 16
static const int PACKET_SIZE = 1000;

View File

@ -62,10 +62,6 @@ inline NVENCException NVENCException::makeNVENCException(const std::string& erro
NVENCSTATUS errorCode = nvencAPI; \
if( errorCode != NV_ENC_SUCCESS) \
{ \
FILE *fp;\
fopen_s(&fp, "C:\\src\\virtual_display\\driver.log", "a");\
fprintf(fp, "nvenc error: %s %d", #nvencAPI, errorCode);\
fclose(fp);\
std::ostringstream errorLog; \
errorLog << #nvencAPI << " returned error " << errorCode; \
throw NVENCException::makeNVENCException(errorLog.str(), errorCode, __FUNCTION__, __FILE__, __LINE__); \

View File

@ -0,0 +1,35 @@
#include "Poller.h"
#include "Logger.h"
#include "Utils.h"
Poller::Poller() {
FD_ZERO(&m_org_fds);
}
Poller::~Poller() {
}
int Poller::Do() {
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 10 * 1000;
memcpy(&m_fds, &m_org_fds, sizeof(fd_set));
int ret = select(0, &m_fds, NULL, NULL, &timeout);
if (ret == SOCKET_ERROR) {
Log("select error : %d %s", WSAGetLastError(), GetDxErrorStr(WSAGetLastError()));
}
return ret;
}
void Poller::AddSocket(SOCKET s) {
FD_SET(s, &m_org_fds);
}
bool Poller::IsPending(SOCKET s) {
return FD_ISSET(s, &m_fds);
}
void Poller::RemoveSocket(SOCKET s) {
FD_CLR(s, &m_org_fds);
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <WinSock2.h>
class Poller {
public:
Poller();
~Poller();
int Do();
void AddSocket(SOCKET s);
bool IsPending(SOCKET s);
void RemoveSocket(SOCKET s);
private:
fd_set m_org_fds;
fd_set m_fds;
};

View File

@ -6,13 +6,14 @@
#include "Utils.h"
UdpSocket::UdpSocket(std::string host, int port)
UdpSocket::UdpSocket(std::string host, int port, std::shared_ptr<Poller> poller)
: m_Host(host)
, m_Port(port)
, m_Socket(INVALID_SOCKET)
, m_PendingData(false)
, m_NewClient(false)
, m_LastSeen(0)
, m_Poller(poller)
{
m_ClientAddr.sin_family = 0;
@ -45,33 +46,13 @@ bool UdpSocket::Startup() {
return false;
}
FD_ZERO(&m_fds);
FD_SET(m_Socket, &m_fds);
m_Poller->AddSocket(m_Socket);
Log("UdpSocket::Startup success");
return true;
}
bool UdpSocket::Poll() {
fd_set fds;
CheckTimeout();
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 10 * 1000;
memcpy(&fds, &m_fds, sizeof(fd_set));
int ret = select(0, &fds, NULL, NULL, &timeout);
if (FD_ISSET(m_Socket, &fds)) {
m_PendingData = true;
return true;
}
return false;
}
bool UdpSocket::NewClient(std::string &host, int &port) {
if (m_NewClient) {
m_NewClient = false;
@ -96,7 +77,7 @@ bool UdpSocket::IsClientValid()const {
}
bool UdpSocket::Recv(char *buf, int *buflen) {
if (!m_PendingData) {
if (!m_Poller->IsPending(m_Socket)) {
return false;
}

View File

@ -3,16 +3,19 @@
#include <WinSock2.h>
#include <WinInet.h>
#include <string>
#include <memory>
#include "ISocket.h"
#include "Poller.h"
#define CONTROL_NAMED_PIPE "\\\\.\\pipe\\RemoteGlass_Control"
class UdpSocket : public ISocket
{
public:
UdpSocket(std::string host, int port);
UdpSocket(std::string host, int port, std::shared_ptr<Poller> poller);
virtual ~UdpSocket();
virtual bool Startup();
virtual bool Poll();
virtual bool NewClient(std::string &host, int &port);
virtual bool Recv(char *buf, int *buflen);
virtual bool Send(char *buf, int len);
@ -29,12 +32,12 @@ private:
std::string m_Host;
int m_Port;
SOCKET m_Socket;
fd_set m_fds;
sockaddr_in m_ClientAddr;
bool m_PendingData;
bool m_NewClient;
uint64_t m_LastSeen;
std::shared_ptr<Poller> m_Poller;
};

View File

@ -22,14 +22,14 @@ inline uint64_t GetTimestampUs() {
inline std::string DumpMatrix(const float *m) {
char buf[200];
snprintf(buf, sizeof(buf),
"%.3f %.3f %.3f %.3f\n"
"%.3f %.3f %.3f %.3f\n"
"%.3f %.3f %.3f %.3f\n"
"%.3f %.3f %.3f %.3f\n"
, m[0], m[4], m[8], m[12]
, m[1], m[5], m[9], m[13]
, m[2], m[6], m[10], m[14]
, m[3], m[7], m[11], m[15]);
"%.5f, %.5f, %.5f, %.5f,\n"
"%.5f, %.5f, %.5f, %.5f,\n"
"%.5f, %.5f, %.5f, %.5f,\n"
"%.5f, %.5f, %.5f, %.5f,\n"
, m[0], m[1], m[2], m[3]
, m[4], m[5], m[6], m[7]
, m[8], m[9], m[10], m[11]
, m[12], m[13], m[14], m[15]);
return std::string(buf);
}

View File

@ -37,36 +37,11 @@ namespace
using Microsoft::WRL::ComPtr;
const char *VERTEX_SHADER = "//--------------------------------------------------------------------------------------\n"
"// File: Tutorial07.fx\n"
"//\n"
"// Copyright (c) Microsoft Corporation. All rights reserved.\n"
"//--------------------------------------------------------------------------------------\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Constant Buffer Variables\n"
"//--------------------------------------------------------------------------------------\n"
"Texture2D txDiffuse : register(t0);\n"
const char *VERTEX_SHADER =
"Texture2D txLeft : register(t0);\n"
"Texture2D txRight : register(t1);\n"
"SamplerState samLinear : register(s0);\n"
"\n"
"cbuffer cbNeverChanges : register(b0)\n"
"{\n"
" matrix View;\n"
"};\n"
"\n"
"cbuffer cbChangeOnResize : register(b1)\n"
"{\n"
" matrix Projection;\n"
"};\n"
"\n"
"cbuffer cbChangesEveryFrame : register(b2)\n"
"{\n"
" matrix World;\n"
" float4 vMeshColor;\n"
"};\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"struct VS_INPUT\n"
"{\n"
" float4 Pos : POSITION;\n"
@ -78,30 +53,32 @@ namespace
" float4 Pos : SV_POSITION;\n"
" float2 Tex : TEXCOORD0;\n"
"};\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Vertex Shader\n"
"//--------------------------------------------------------------------------------------\n"
"PS_INPUT VS(VS_INPUT input)\n"
"{\n"
" PS_INPUT output = (PS_INPUT)0;\n"
" output.Pos = mul(input.Pos, World);\n"
" output.Pos = mul(output.Pos, View);\n"
" output.Pos = mul(output.Pos, Projection);\n"
" output.Pos = input.Pos;\n"
" output.Tex = input.Tex;\n"
"\n"
" return output;\n"
"}\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Pixel Shader\n"
"//--------------------------------------------------------------------------------------\n"
"float4 PS(PS_INPUT input) : SV_Target\n"
"{\n"
//" return txDiffuse.Sample(samLinear, input.Tex) * vMeshColor;\n"
" return float4(1.0, 0.4, 0.6, 1.0);\n"
//"float offset = (1448.0 - 1024.0) / 2 / 1448.0;\n"
"float offset = 0.0;\n"
"float shrink_to = 1.0 - offset * 2;\n"
"float x = input.Tex.x;\n"
"float y = input.Tex.y;\n"
" if (input.Tex.x < 0.5){\n"
" x = x * 2;\n"
" x = x * shrink_to + offset;\n"
" y = y * shrink_to + offset;\n"
" return txLeft.Sample(samLinear, float2(1.0 - x, 1.0 - y)); // We need this hack, because We cloud not resolve upside down issue by changing texcoord in buffer.\n"
" }else{\n"
" x = x * 2 - 1.0;\n"
" x = x * shrink_to + offset;\n"
" y = y * shrink_to + offset;\n"
" return txLeft.Sample(samLinear, float2(1.0 - x, 1.0 - y)); // We need this hack, because We cloud not resolve upside down issue by changing texcoord in buffer.\n"
" }\n"
"}\n";
const char *PIXEL_SHADER = VERTEX_SHADER;
@ -266,6 +243,7 @@ namespace
static const char * const k_pch_Settings_WindowHeight_Int32 = "windowHeight";
static const char * const k_pch_Settings_RenderWidth_Int32 = "renderWidth";
static const char * const k_pch_Settings_RenderHeight_Int32 = "renderHeight";
static const char * const k_pch_Settings_IPD_Float = "IPD";
static const char * const k_pch_Settings_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons";
static const char * const k_pch_Settings_DisplayFrequency_Float = "displayFrequency";
static const char * const k_pch_Settings_EncoderOptions_String = "nvencOptions";
@ -275,6 +253,8 @@ namespace
static const char * const k_pch_Settings_DebugTimestamp_Bool = "debugTimestamp";
static const char * const k_pch_Settings_ListenHost_String = "listenHost";
static const char * const k_pch_Settings_ListenPort_Int32 = "listenPort";
static const char * const k_pch_Settings_ControlListenHost_String = "controlListenHost";
static const char * const k_pch_Settings_ControlListenPort_Int32 = "controlListenPort";
static const char * const k_pch_Settings_AdditionalLatencyInSeconds_Float = "additionalLatencyInSeconds";
static const char * const k_pch_Settings_DisplayWidth_Int32 = "displayWidth";
@ -636,7 +616,7 @@ namespace
HRESULT hr = m_pD3DRender->GetDevice()->CreateRenderTargetView(m_pStagingTexture.Get(), NULL, &m_pRenderTargetView);
if (FAILED(hr)) {
Log("CreateRenderTargetView %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
// Create depth stencil texture
@ -656,7 +636,7 @@ namespace
hr = m_pD3DRender->GetDevice()->CreateTexture2D(&descDepth, nullptr, &m_pDepthStencil);
if (FAILED(hr)) {
Log("CreateTexture2D %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
@ -669,7 +649,7 @@ namespace
hr = m_pD3DRender->GetDevice()->CreateDepthStencilView(m_pDepthStencil.Get(), &descDSV, &m_pDepthStencilView);
if (FAILED(hr)) {
Log("CreateDepthStencilView %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
m_pD3DRender->GetContext()->OMSetRenderTargets(1, m_pRenderTargetView.GetAddressOf(), m_pDepthStencilView.Get());
@ -684,27 +664,13 @@ namespace
m_pD3DRender->GetContext()->RSSetViewports(1, &viewport);
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = srcDesc.Format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = 1;
hr = m_pD3DRender->GetDevice()->CreateShaderResourceView(pTexture[0], &SRVDesc, &m_pShaderResourceView);
if (FAILED(hr)) {
Log("CreateShaderResourceView %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
}
ID3DBlob *vshader, *pshader, *error;
hr = D3DCompile(VERTEX_SHADER, strlen(VERTEX_SHADER), "vs", NULL, NULL, "VS", "vs_4_0", 0, 0, &vshader, &error);
//hr = D3DXCompileShader(VERTEX_SHADER, strlen(VERTEX_SHADER), 0, 0, "main", "vs_4_0", 0, &vshader, &error, NULL);
Log("D3DCompile vs %p %s", hr, GetDxErrorStr(hr).c_str());
if (FAILED(hr)) {
Log("%s", error->GetBufferPointer());
return hr;
return false;
}
if (error != NULL) {
error->Release();
@ -714,14 +680,13 @@ namespace
hr = m_pD3DRender->GetDevice()->CreateVertexShader((const DWORD*)vshader->GetBufferPointer(), vshader->GetBufferSize(), NULL, &m_pVertexShader);
if (FAILED(hr)) {
Log("CreateVertexShader %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
hr = D3DCompile(VERTEX_SHADER, strlen(VERTEX_SHADER), "ps", NULL, NULL, "PS", "ps_4_0", 0, 0, &pshader, &error);
// hr = D3DXCompileShader(PIXEL_SHADER, strlen(PIXEL_SHADER), 0, 0, "main", "ps_4_0", 0, &pshader, &error, NULL);
Log("D3DCompile ps %p %s", hr, GetDxErrorStr(hr).c_str());
if (FAILED(hr)) {
Log("%s", error->GetBufferPointer());
return hr;
return false;
}
if (error != NULL) {
error->Release();
@ -730,7 +695,7 @@ namespace
hr = m_pD3DRender->GetDevice()->CreatePixelShader((const DWORD*)pshader->GetBufferPointer(), pshader->GetBufferSize(), NULL, &m_pPixelShader);
if (FAILED(hr)) {
Log("CreatePixelShader %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
// Define the input layout
@ -747,51 +712,31 @@ namespace
vshader->GetBufferSize(), &m_pVertexLayout);
if (FAILED(hr)) {
Log("CreateInputLayout %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
vshader->Release();
// Set the input layout
m_pD3DRender->GetContext()->IASetInputLayout(m_pVertexLayout.Get());
// src textures has 1448x1448 pixels but dest texture(remote display) has 1024x1024 pixels.
// Apply offset to crop center of src textures.
float tex_offset = (1448 - 1024) / 2 / 1448.0;
tex_offset = 0;
// Create vertex buffer
SimpleVertex vertices[] =
{
{ DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 0.5f), DirectX::XMFLOAT2(1.0f - tex_offset, 0.0f + tex_offset) },
{ DirectX::XMFLOAT3( 1.0f, 1.0f, 0.5f), DirectX::XMFLOAT2(0.0f + tex_offset, 1.0f - tex_offset) },
{ DirectX::XMFLOAT3( 1.0f, -1.0f, 0.5f), DirectX::XMFLOAT2(0.0f + tex_offset, 0.0f + tex_offset) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 0.5f), DirectX::XMFLOAT2(1.0f - tex_offset, 1.0f - tex_offset) },
};
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(SimpleVertex) * 24;
bd.ByteWidth = sizeof(SimpleVertex) * 4;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
@ -800,7 +745,7 @@ namespace
hr = m_pD3DRender->GetDevice()->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);
if (FAILED(hr)) {
Log("CreateBuffer 1 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
// Set vertex buffer
@ -812,34 +757,19 @@ namespace
// Create vertex buffer
WORD indices[] =
{
3,1,0,
2,1,3,
6,4,5,
7,4,6,
11,9,8,
10,9,11,
14,12,13,
15,12,14,
19,17,16,
18,17,19,
22,20,21,
23,20,22
0,1,2,
0,3,1
};
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(WORD) * 36;
bd.ByteWidth = sizeof(WORD) * 6;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = m_pD3DRender->GetDevice()->CreateBuffer(&bd, &InitData, &m_pIndexBuffer);
if (FAILED(hr)) {
Log("CreateBuffer 2 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
// Set index buffer
@ -848,32 +778,6 @@ namespace
// Set primitive topology
m_pD3DRender->GetContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Create the constant buffers
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(CBNeverChanges);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = m_pD3DRender->GetDevice()->CreateBuffer(&bd, nullptr, &m_pCBNeverChanges);
if (FAILED(hr)) {
Log("CreateBuffer 3 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
}
bd.ByteWidth = sizeof(CBChangeOnResize);
hr = m_pD3DRender->GetDevice()->CreateBuffer(&bd, nullptr, &m_pCBChangeOnResize);
if (FAILED(hr)) {
Log("CreateBuffer 4 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
}
bd.ByteWidth = sizeof(CBChangesEveryFrame);
hr = m_pD3DRender->GetDevice()->CreateBuffer(&bd, nullptr, &m_pCBChangesEveryFrame);
if (FAILED(hr)) {
Log("CreateBuffer 5 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
}
// Create the sample state
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
@ -887,30 +791,9 @@ namespace
hr = m_pD3DRender->GetDevice()->CreateSamplerState(&sampDesc, &m_pSamplerLinear);
if (FAILED(hr)) {
Log("CreateSamplerState 5 %p %s", hr, GetDxErrorStr(hr).c_str());
return hr;
return false;
}
// Initialize the world matrices
g_World = DirectX::XMMatrixIdentity();
// Initialize the view matrix
DirectX::XMVECTOR Eye = DirectX::XMVectorSet(0.0f, 3.0f, -6.0f, 0.0f);
DirectX::XMVECTOR At = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
DirectX::XMVECTOR Up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
g_View = DirectX::XMMatrixLookAtLH(Eye, At, Up);
g_vMeshColor = DirectX::XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
CBNeverChanges cbNeverChanges;
cbNeverChanges.mView = DirectX::XMMatrixTranspose(g_View);
m_pD3DRender->GetContext()->UpdateSubresource(m_pCBNeverChanges.Get(), 0, nullptr, &cbNeverChanges, 0, 0);
// Initialize the projection matrix
g_Projection = DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV4, 1, 0.01f, 100.0f);
CBChangeOnResize cbChangesOnResize;
cbChangesOnResize.mProjection = DirectX::XMMatrixTranspose(g_Projection);
m_pD3DRender->GetContext()->UpdateSubresource(m_pCBChangeOnResize.Get(), 0, nullptr, &cbChangesOnResize, 0, 0);
Log("Staging Texture created");
}
@ -954,14 +837,22 @@ namespace
t = (timeCur - timeStart) / 1000.0f;
float col = (GetTimestampUs() / 1000) / 10 % 256 / 256.0;
// Rotate cube around the origin
g_World = DirectX::XMMatrixRotationY(t);
// Modify the color
g_vMeshColor.x = (sinf(t * 1.0f) + 1.0f) * 0.5f;
g_vMeshColor.y = (cosf(t * 3.0f) + 1.0f) * 0.5f;
g_vMeshColor.z = (sinf(t * 5.0f) + 1.0f) * 0.5f;
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = srcDesc.Format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = 1;
HRESULT hr = m_pD3DRender->GetDevice()->CreateShaderResourceView(pTexture[0], &SRVDesc, m_pShaderResourceView[0].ReleaseAndGetAddressOf());
if (FAILED(hr)) {
Log("CreateShaderResourceView %p %s", hr, GetDxErrorStr(hr).c_str());
return false;
}
hr = m_pD3DRender->GetDevice()->CreateShaderResourceView(pTexture[1], &SRVDesc, m_pShaderResourceView[1].ReleaseAndGetAddressOf());
if (FAILED(hr)) {
Log("CreateShaderResourceView %p %s", hr, GetDxErrorStr(hr).c_str());
return false;
}
//
// Clear the back buffer
@ -974,26 +865,18 @@ namespace
//
m_pD3DRender->GetContext()->ClearDepthStencilView(m_pDepthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
//
// Update variables that change once per frame
//
CBChangesEveryFrame cb;
cb.mWorld = DirectX::XMMatrixTranspose(g_World);
cb.vMeshColor = g_vMeshColor;
m_pD3DRender->GetContext()->UpdateSubresource(m_pCBChangesEveryFrame.Get(), 0, nullptr, &cb, 0, 0);
//
// Render the cube
//
m_pD3DRender->GetContext()->VSSetShader(m_pVertexShader.Get(), nullptr, 0);
m_pD3DRender->GetContext()->VSSetConstantBuffers(0, 1, m_pCBNeverChanges.GetAddressOf());
m_pD3DRender->GetContext()->VSSetConstantBuffers(1, 1, m_pCBChangeOnResize.GetAddressOf());
m_pD3DRender->GetContext()->VSSetConstantBuffers(2, 1, m_pCBChangesEveryFrame.GetAddressOf());
m_pD3DRender->GetContext()->PSSetShader(m_pPixelShader.Get(), nullptr, 0);
m_pD3DRender->GetContext()->PSSetConstantBuffers(2, 1, m_pCBChangesEveryFrame.GetAddressOf());
m_pD3DRender->GetContext()->PSSetShaderResources(0, 1, m_pShaderResourceView.GetAddressOf());
ID3D11ShaderResourceView *shaderResourceView[2] = { m_pShaderResourceView[0].Get(), m_pShaderResourceView[1].Get() };
m_pD3DRender->GetContext()->PSSetShaderResources(0, 2, shaderResourceView);
//m_pD3DRender->GetContext()->PSSetShaderResources(0, 1, shaderResourceView);
m_pD3DRender->GetContext()->PSSetSamplers(0, 1, m_pSamplerLinear.GetAddressOf());
m_pD3DRender->GetContext()->DrawIndexed(36, 0, 0);
m_pD3DRender->GetContext()->DrawIndexed(6, 0, 0);
m_pD3DRender->GetContext()->Flush();
}
@ -1062,18 +945,10 @@ namespace
ComPtr<ID3D11Buffer> m_pVertexBuffer;
ComPtr<ID3D11Buffer> m_pIndexBuffer;
ComPtr<ID3D11Buffer> m_pCBNeverChanges;
ComPtr<ID3D11Buffer> m_pCBChangeOnResize;
ComPtr<ID3D11Buffer> m_pCBChangesEveryFrame;
ComPtr<ID3D11SamplerState> m_pSamplerLinear;
DirectX::XMMATRIX g_World;
DirectX::XMMATRIX g_View;
DirectX::XMMATRIX g_Projection;
DirectX::XMFLOAT4 g_vMeshColor;
ComPtr<ID3D11Texture2D> m_pDepthStencil;
ComPtr<ID3D11ShaderResourceView> m_pShaderResourceView;
ComPtr<ID3D11ShaderResourceView> m_pShaderResourceView[2];
ComPtr<ID3D11RenderTargetView> m_pRenderTargetView;
ComPtr<ID3D11DepthStencilView> m_pDepthStencilView;
@ -1082,23 +957,6 @@ namespace
DirectX::XMFLOAT3 Pos;
DirectX::XMFLOAT2 Tex;
};
struct CBNeverChanges
{
DirectX::XMMATRIX mView;
};
struct CBChangeOnResize
{
DirectX::XMMATRIX mProjection;
};
struct CBChangesEveryFrame
{
DirectX::XMMATRIX mWorld;
DirectX::XMFLOAT4 vMeshColor;
};
};
}
@ -1144,16 +1002,16 @@ public:
, m_DebugTimestamp(false)
, m_Listener(NULL)
, m_VSyncThread(NULL)
, m_poseMutex(NULL)
{
std::string logFile;
std::string host;
int port;
std::string host, control_host;
int port, control_port;
m_unObjectId = vr::k_unTrackedDeviceIndexInvalid;
m_ulPropertyContainer = vr::k_ulInvalidPropertyContainer;
Log("Using settings values");
m_flIPD = vr::VRSettings()->GetFloat(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_IPD_Float);
char buf[10240];
vr::VRSettings()->GetString(k_pch_Settings_Section, k_pch_Settings_SerialNumber_String, buf, sizeof(buf));
@ -1186,12 +1044,22 @@ public:
vr::VRSettings()->GetString(k_pch_Settings_Section, k_pch_Settings_ListenHost_String, buf, sizeof(buf));
host = buf;
port = vr::VRSettings()->GetInt32(k_pch_Settings_Section, k_pch_Settings_ListenPort_Int32);
vr::VRSettings()->GetString(k_pch_Settings_Section, k_pch_Settings_ControlListenHost_String, buf, sizeof(buf));
control_host = buf;
control_port = vr::VRSettings()->GetInt32(k_pch_Settings_Section, k_pch_Settings_ControlListenPort_Int32);
m_DebugTimestamp = vr::VRSettings()->GetBool(k_pch_Settings_Section, k_pch_Settings_DebugTimestamp_Bool);
logger = simplelogger::LoggerFactory::CreateFileLogger(logFile);
float originalIPD = vr::VRSettings()->GetFloat(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_IPD_Float);
m_flIPD = vr::VRSettings()->GetFloat(k_pch_Settings_Section, k_pch_Settings_IPD_Float);
vr::VRSettings()->SetFloat(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_IPD_Float, m_flIPD);
Log("driver_null: Serial Number: %s", m_sSerialNumber.c_str());
Log("driver_null: Model Number: %s", m_sModelNumber.c_str());
Log("driver_null: Window: %d %d %d %d", m_nWindowX, m_nWindowY, m_nWindowWidth, m_nWindowHeight);
@ -1296,7 +1164,7 @@ public:
std::function<void(sockaddr_in *)> Callback = [&](sockaddr_in *a) { ListenerCallback(a); };
std::function<void()> poseCallback = [&]() { OnPoseUpdated(); };
m_Listener = new Listener(host, port, SrtOptions, Callback, poseCallback);
m_Listener = new Listener(host, port, control_host, control_port, SrtOptions, Callback, poseCallback);
m_Listener->Start();
// Spawn our separate process to manage headset presentation.
@ -1516,12 +1384,12 @@ public:
if (eEye == vr::Eye_Left)
{
*pfLeft = -1.0;
*pfRight = 0.0;
*pfRight = 1.0;
*pfTop = -1.0;
*pfBottom = 1.0;
}
else {
*pfLeft = 0.0;
*pfLeft = -1.0;
*pfRight = 1.0;
*pfTop = -1.0;
*pfBottom = 1.0;
@ -1561,7 +1429,7 @@ public:
auto& info = m_Listener->GetTrackingInfo();
uint64_t trackingDelay = GetTimestampUs() - m_Listener->clientToServerTime(info.clientTime);
Log("Tracking elapsed:%lld us %lld %f,%f,%f,%f %f,%f,%f\nView[0]:\n%sProj[0]:\n%sView[1]:\n%sProj[1]:\n%s",
Log("Tracking elapsed:%lld us %lld quot:%f,%f,%f,%f\nposition:%f,%f,%f\nView[0]:\n%sProj[0]:\n%sView[1]:\n%sProj[1]:\n%s",
trackingDelay,
info.FrameIndex,
info.HeadPose_Pose_Orientation.x,
@ -1608,6 +1476,21 @@ public:
m_LastReferencedFrameIndex = info.FrameIndex;
m_LastReferencedClientTime = info.clientTime;
m_poseMutex.Wait(INFINITE);
if (m_poseBuffer.size() != 0) {
m_poseBuffer.push_back(info);
}
else {
if (m_poseBuffer.back().FrameIndex != info.FrameIndex) {
// New track info
m_poseBuffer.push_back(info);
}
}
if (m_poseBuffer.size() > 10) {
m_poseBuffer.pop_front();
}
m_poseMutex.Release();
}
return pose;
@ -1652,6 +1535,10 @@ private:
uint64_t m_LastReferencedFrameIndex;
uint64_t m_LastReferencedClientTime;
IPCMutex m_poseMutex;
std::list<Listener::TrackingInfo> m_poseBuffer;
public:
bool IsValid() const
{
@ -1937,13 +1824,50 @@ public:
/** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created
* using CreateSwapTextureSet and should be alternated per frame. Call Present once all layers have been submitted. */
virtual void SubmitLayer(vr::SharedTextureHandle_t sharedTextureHandles[2], const vr::VRTextureBounds_t(&bounds)[2], const vr::HmdMatrix34_t *pPose) {
Log("SubmitLayer %p %p %f-%f,%f-%f %f-%f,%f-%f (%f,%f,%f,%f | %f,%f,%f,%f | %f,%f,%f,%f)", sharedTextureHandles[0], sharedTextureHandles[1]
Log("SubmitLayer %p %p %f-%f,%f-%f %f-%f,%f-%f \n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f", sharedTextureHandles[0], sharedTextureHandles[1]
, bounds[0].uMin, bounds[0].uMax, bounds[0].vMin, bounds[0].vMax
, bounds[1].uMin, bounds[1].uMax, bounds[1].vMin, bounds[1].vMax
, pPose->m[0][0], pPose->m[0][1], pPose->m[0][2], pPose->m[0][3]
, pPose->m[1][0], pPose->m[1][1], pPose->m[1][2], pPose->m[1][3]
, pPose->m[2][0], pPose->m[2][1], pPose->m[2][2], pPose->m[2][3]
);
// 3x3 rotation matrix
//pPose->m[0][0], pPose->m[0][1], pPose->m[0][2],
//pPose->m[1][0], pPose->m[1][1], pPose->m[1][2],
//pPose->m[2][0], pPose->m[2][1], pPose->m[2][2],
// position
// x = pPose->m[0][3], y = pPose->m[1][3], z = pPose->m[2][3]
m_framePose = *pPose;
m_poseMutex.Wait(INFINITE);
float diff = 100000;
int index = 0;
int minIndex = 0;
auto minIt = m_poseBuffer.begin();
for (auto it = m_poseBuffer.begin(); it != m_poseBuffer.end(); it++, index++) {
float distance = 0;
// rotation matrix composes parts of ViewMatrix
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
distance += pow(it->Eye[0].ViewMatrix.M[j * 3 + i] - pPose->m[i][j], 2);
}
}
if (diff > distance) {
minIndex = index;
minIt = it;
}
}
if (minIt != m_poseBuffer.end()) {
// found the frameIndex
m_submitFrameIndex = minIt->FrameIndex;
m_submitClientTime = minIt->clientTime;
}
else {
m_submitFrameIndex = 0;
m_submitClientTime = 0;
}
m_poseMutex.Release();
m_submitTextures[0] = sharedTextureHandles[0];
m_submitTextures[1] = sharedTextureHandles[1];
}
@ -2003,7 +1927,8 @@ public:
//Log("[VDispDvr] Flush-End");
// Copy entire texture to staging so we can read the pixels to send to remote device.
m_pEncoder->CopyToStaging(pTexture, 2, presentationTime, m_LastReferencedFrameIndex, m_LastReferencedClientTime);
Log("FrameIndex diff LastRef: %llu render:%llu diff:%llu", m_LastReferencedFrameIndex, m_submitFrameIndex, m_LastReferencedFrameIndex - m_submitFrameIndex);
m_pEncoder->CopyToStaging(pTexture, 2, presentationTime, m_submitFrameIndex, m_submitClientTime);
//Log("[VDispDvr] Flush-Staging(begin)");
@ -2031,6 +1956,9 @@ private:
std::map<HANDLE, std::pair<ProcessResource *, int> > m_handleMap;
vr::SharedTextureHandle_t m_submitTextures[2];
vr::HmdMatrix34_t m_framePose;
uint64_t m_submitFrameIndex;
uint64_t m_submitClientTime;
};
//-----------------------------------------------------------------------------

View File

@ -150,9 +150,11 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ControlSocket.cpp" />
<ClCompile Include="driver_virtual_display.cpp" />
<ClCompile Include="NvEncoder.cpp" />
<ClCompile Include="NvEncoderD3D11.cpp" />
<ClCompile Include="Poller.cpp" />
<ClCompile Include="SrtSocket.cpp" />
<ClCompile Include="UdpSocket.cpp" />
</ItemGroup>
@ -162,6 +164,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ControlSocket.h" />
<ClInclude Include="ISocket.h" />
<ClInclude Include="Listener.h" />
<ClInclude Include="Logger.h" />
@ -170,6 +173,7 @@
<ClInclude Include="NvEncoder.h" />
<ClInclude Include="nvencoderclioptions.h" />
<ClInclude Include="NvEncoderD3D11.h" />
<ClInclude Include="Poller.h" />
<ClInclude Include="SrtSocket.h" />
<ClInclude Include="UdpSocket.h" />
<ClInclude Include="UdpSender.h" />

View File

@ -155,7 +155,7 @@ public:
<< std::endl << "\taq : " << (pParams->encodeConfig->rcParams.enableAQ ? (pParams->encodeConfig->rcParams.aqStrength ? std::to_string(pParams->encodeConfig->rcParams.aqStrength) : "auto") : "disabled")
<< std::endl << "\ttemporalaq : " << (pParams->encodeConfig->rcParams.enableTemporalAQ ? "enabled" : "disabled")
<< std::endl << "\tlookahead : " << (pParams->encodeConfig->rcParams.enableLookahead ? std::to_string(pParams->encodeConfig->rcParams.lookaheadDepth) : "disabled")
<< std::endl << "\tcq : " << pParams->encodeConfig->rcParams.targetQuality
<< std::endl << "\tcq : " << (int)pParams->encodeConfig->rcParams.targetQuality
<< std::endl << "\tqmin : P,B,I=" << pParams->encodeConfig->rcParams.minQP.qpInterP << "," << pParams->encodeConfig->rcParams.minQP.qpInterB << "," << pParams->encodeConfig->rcParams.minQP.qpIntra
<< std::endl << "\tqmax : P,B,I=" << pParams->encodeConfig->rcParams.maxQP.qpInterP << "," << pParams->encodeConfig->rcParams.maxQP.qpInterB << "," << pParams->encodeConfig->rcParams.maxQP.qpIntra
<< std::endl << "\tinitqp : P,B,I=" << pParams->encodeConfig->rcParams.initialRCQP.qpInterP << "," << pParams->encodeConfig->rcParams.initialRCQP.qpInterB << "," << pParams->encodeConfig->rcParams.initialRCQP.qpIntra

View File

@ -15,6 +15,7 @@
"windowHeight" : 1024,
"renderWidth" : 1024,
"renderHeight" : 1024,
"IPD": 0.064,
"secondsFromVsyncToPhotons" : 0.005, // 5ms
"displayFrequency" : 60,
"nvencOptions": "-codec h264 -preset ll_hq -rc cbr_ll_hq -bitrate 10M -gop 240 -maxbitrate 10M -fps 60",
@ -23,6 +24,8 @@
"logFile": "C:\\src\\virtual_display\\driver.log",
"listenPort": 9944,
"listenHost": "0.0.0.0",
"controlListenPort": 9944,
"controlListenHost": "127.0.0.1",
"debugTimestamp": false,
"srtOptions": "TSBPDDELAY=1 RCVLATENCY=1"
}