[host] removed old host application from the project, see c-host

This commit is contained in:
Geoffrey McRae 2019-05-28 14:47:09 +10:00
parent 7d26027752
commit 373d4ac932
35 changed files with 1 additions and 5885 deletions

View File

@ -1 +1 @@
B1-rc3-6-g3d426ccef8+1 B1-rc3-7-g7d26027752+1

308
host/.gitignore vendored
View File

@ -1,308 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# compiled shader headers
Shaders/*.h
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/

View File

@ -1,829 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Capture/DXGI.h"
using namespace Capture;
#include "WinDebug.h"
#include "common/memcpySSE.h"
static const char * DXGI_FORMAT_STR[] = {
"DXGI_FORMAT_UNKNOWN",
"DXGI_FORMAT_R32G32B32A32_TYPELESS",
"DXGI_FORMAT_R32G32B32A32_FLOAT",
"DXGI_FORMAT_R32G32B32A32_UINT",
"DXGI_FORMAT_R32G32B32A32_SINT",
"DXGI_FORMAT_R32G32B32_TYPELESS",
"DXGI_FORMAT_R32G32B32_FLOAT",
"DXGI_FORMAT_R32G32B32_UINT",
"DXGI_FORMAT_R32G32B32_SINT",
"DXGI_FORMAT_R16G16B16A16_TYPELESS",
"DXGI_FORMAT_R16G16B16A16_FLOAT",
"DXGI_FORMAT_R16G16B16A16_UNORM",
"DXGI_FORMAT_R16G16B16A16_UINT",
"DXGI_FORMAT_R16G16B16A16_SNORM",
"DXGI_FORMAT_R16G16B16A16_SINT",
"DXGI_FORMAT_R32G32_TYPELESS",
"DXGI_FORMAT_R32G32_FLOAT",
"DXGI_FORMAT_R32G32_UINT",
"DXGI_FORMAT_R32G32_SINT",
"DXGI_FORMAT_R32G8X24_TYPELESS",
"DXGI_FORMAT_D32_FLOAT_S8X24_UINT",
"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",
"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT",
"DXGI_FORMAT_R10G10B10A2_TYPELESS",
"DXGI_FORMAT_R10G10B10A2_UNORM",
"DXGI_FORMAT_R10G10B10A2_UINT",
"DXGI_FORMAT_R11G11B10_FLOAT",
"DXGI_FORMAT_R8G8B8A8_TYPELESS",
"DXGI_FORMAT_R8G8B8A8_UNORM",
"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
"DXGI_FORMAT_R8G8B8A8_UINT",
"DXGI_FORMAT_R8G8B8A8_SNORM",
"DXGI_FORMAT_R8G8B8A8_SINT",
"DXGI_FORMAT_R16G16_TYPELESS",
"DXGI_FORMAT_R16G16_FLOAT",
"DXGI_FORMAT_R16G16_UNORM",
"DXGI_FORMAT_R16G16_UINT",
"DXGI_FORMAT_R16G16_SNORM",
"DXGI_FORMAT_R16G16_SINT",
"DXGI_FORMAT_R32_TYPELESS",
"DXGI_FORMAT_D32_FLOAT",
"DXGI_FORMAT_R32_FLOAT",
"DXGI_FORMAT_R32_UINT",
"DXGI_FORMAT_R32_SINT",
"DXGI_FORMAT_R24G8_TYPELESS",
"DXGI_FORMAT_D24_UNORM_S8_UINT",
"DXGI_FORMAT_R24_UNORM_X8_TYPELESS",
"DXGI_FORMAT_X24_TYPELESS_G8_UINT",
"DXGI_FORMAT_R8G8_TYPELESS",
"DXGI_FORMAT_R8G8_UNORM",
"DXGI_FORMAT_R8G8_UINT",
"DXGI_FORMAT_R8G8_SNORM",
"DXGI_FORMAT_R8G8_SINT",
"DXGI_FORMAT_R16_TYPELESS",
"DXGI_FORMAT_R16_FLOAT",
"DXGI_FORMAT_D16_UNORM",
"DXGI_FORMAT_R16_UNORM",
"DXGI_FORMAT_R16_UINT",
"DXGI_FORMAT_R16_SNORM",
"DXGI_FORMAT_R16_SINT",
"DXGI_FORMAT_R8_TYPELESS",
"DXGI_FORMAT_R8_UNORM",
"DXGI_FORMAT_R8_UINT",
"DXGI_FORMAT_R8_SNORM",
"DXGI_FORMAT_R8_SINT",
"DXGI_FORMAT_A8_UNORM",
"DXGI_FORMAT_R1_UNORM",
"DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
"DXGI_FORMAT_R8G8_B8G8_UNORM",
"DXGI_FORMAT_G8R8_G8B8_UNORM",
"DXGI_FORMAT_BC1_TYPELESS",
"DXGI_FORMAT_BC1_UNORM",
"DXGI_FORMAT_BC1_UNORM_SRGB",
"DXGI_FORMAT_BC2_TYPELESS",
"DXGI_FORMAT_BC2_UNORM",
"DXGI_FORMAT_BC2_UNORM_SRGB",
"DXGI_FORMAT_BC3_TYPELESS",
"DXGI_FORMAT_BC3_UNORM",
"DXGI_FORMAT_BC3_UNORM_SRGB",
"DXGI_FORMAT_BC4_TYPELESS",
"DXGI_FORMAT_BC4_UNORM",
"DXGI_FORMAT_BC4_SNORM",
"DXGI_FORMAT_BC5_TYPELESS",
"DXGI_FORMAT_BC5_UNORM",
"DXGI_FORMAT_BC5_SNORM",
"DXGI_FORMAT_B5G6R5_UNORM",
"DXGI_FORMAT_B5G5R5A1_UNORM",
"DXGI_FORMAT_B8G8R8A8_UNORM",
"DXGI_FORMAT_B8G8R8X8_UNORM",
"DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM",
"DXGI_FORMAT_B8G8R8A8_TYPELESS",
"DXGI_FORMAT_B8G8R8A8_UNORM_SRGB",
"DXGI_FORMAT_B8G8R8X8_TYPELESS",
"DXGI_FORMAT_B8G8R8X8_UNORM_SRGB",
"DXGI_FORMAT_BC6H_TYPELESS",
"DXGI_FORMAT_BC6H_UF16",
"DXGI_FORMAT_BC6H_SF16",
"DXGI_FORMAT_BC7_TYPELESS",
"DXGI_FORMAT_BC7_UNORM",
"DXGI_FORMAT_BC7_UNORM_SRGB",
"DXGI_FORMAT_AYUV",
"DXGI_FORMAT_Y410",
"DXGI_FORMAT_Y416",
"DXGI_FORMAT_NV12",
"DXGI_FORMAT_P010",
"DXGI_FORMAT_P016",
"DXGI_FORMAT_420_OPAQUE",
"DXGI_FORMAT_YUY2",
"DXGI_FORMAT_Y210",
"DXGI_FORMAT_Y216",
"DXGI_FORMAT_NV11",
"DXGI_FORMAT_AI44",
"DXGI_FORMAT_IA44",
"DXGI_FORMAT_P8",
"DXGI_FORMAT_A8P8",
"DXGI_FORMAT_B4G4R4A4_UNORM",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"DXGI_FORMAT_P208",
"DXGI_FORMAT_V208",
"DXGI_FORMAT_V408"
};
const char * GetDXGIFormatStr(DXGI_FORMAT format)
{
if (format > _countof(DXGI_FORMAT_STR))
return DXGI_FORMAT_STR[0];
return DXGI_FORMAT_STR[format];
}
DXGI::DXGI() :
m_options(NULL),
m_initialized(false),
m_dxgiFactory(),
m_device(),
m_deviceContext(),
m_dup()
{
}
DXGI::~DXGI()
{
}
bool DXGI::CanInitialize()
{
HDESK desktop = OpenInputDesktop(0, TRUE, GENERIC_READ);
if (!desktop)
return false;
CloseDesktop(desktop);
return true;
}
bool DXGI::Initialize(CaptureOptions * options)
{
if (m_initialized)
DeInitialize();
m_options = options;
HRESULT status;
m_cursorRPos = 0;
m_cursorWPos = 0;
for (int i = 0; i < _countof(m_cursorRing); ++i)
{
CursorInfo & cursor = m_cursorRing[i];
cursor.visible = false;
cursor.hasPos = false;
cursor.hasShape = false;
}
status = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)(&m_dxgiFactory));
if (FAILED(status))
{
DEBUG_ERROR("Failed to create DXGIFactory: %08x", (int)status);
return false;
}
bool done = false;
IDXGIAdapter1Ptr adapter;
for (int i = 0; m_dxgiFactory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
{
for (int i = 0; adapter->EnumOutputs(i, &m_output) != DXGI_ERROR_NOT_FOUND; i++)
{
DXGI_OUTPUT_DESC outputDesc;
m_output->GetDesc(&outputDesc);
if (!outputDesc.AttachedToDesktop)
{
m_output = NULL;
continue;
}
DXGI_ADAPTER_DESC1 adapterDesc;
adapter->GetDesc1(&adapterDesc);
DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description);
DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId);
DEBUG_INFO("Device Device ID : 0x%x" , adapterDesc.DeviceId);
DEBUG_INFO("Device Video Mem : %lld MB", adapterDesc.DedicatedVideoMemory / 1048576);
DEBUG_INFO("Device Sys Mem : %lld MB", adapterDesc.DedicatedSystemMemory / 1048576);
DEBUG_INFO("Shared Sys Mem : %lld MB", adapterDesc.SharedSystemMemory / 1048576);
m_width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left;
m_height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top;
DEBUG_INFO("Capture Size : %u x %u", m_width, m_height);
done = true;
break;
}
if (done)
break;
adapter = NULL;
}
if (!done)
{
DEBUG_ERROR("Failed to locate a valid output device");
DeInitialize();
return false;
}
static const D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
#ifdef _DEBUG
#define CREATE_FLAGS (D3D11_CREATE_DEVICE_DEBUG)
#else
#define CREATE_FLAGS (0)
#endif
status = D3D11CreateDevice(
adapter,
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
CREATE_FLAGS | D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
featureLevels, ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&m_device,
&m_featureLevel,
&m_deviceContext
);
#undef CREATE_FLAGS
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create D3D11 device", status);
DeInitialize();
return false;
}
DEBUG_INFO("Feature Level : 0x%x", m_featureLevel);
IDXGIDevicePtr dxgi;
status = m_device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgi);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to obtain the IDXGIDevice interface from the D3D11 device", status);
DeInitialize();
return false;
}
dxgi->SetGPUThreadPriority(7);
// first try to use the newer API
IDXGIOutput5Ptr output5 = m_output;
if (output5)
{
// we try this twice in case we still get an error on re-initialization
for (int i = 0; i < 2; ++i)
{
const DXGI_FORMAT supportedFormats[] = {
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R10G10B10A2_UNORM
};
status = output5->DuplicateOutput1(m_device, 0, _countof(supportedFormats), supportedFormats, &m_dup);
if (SUCCEEDED(status))
break;
Sleep(200);
}
if (FAILED(status))
{
DEBUG_WINERROR("DuplicateOutput1 Failed", status);
DeInitialize();
return false;
}
}
else
{
DEBUG_WARN("IDXGIOutput5 is not available, please update windows for improved performance!");
DEBUG_WARN("Falling back to IDXIGOutput1");
IDXGIOutput1Ptr output1 = m_output;
if (!output1)
{
DEBUG_ERROR("Failed to get IDXGIOutput1");
DeInitialize();
return false;
}
// we try this twice in case we still get an error on re-initialization
for (int i = 0; i < 2; ++i)
{
status = output1->DuplicateOutput(m_device, &m_dup);
if (SUCCEEDED(status))
break;
Sleep(200);
}
if (FAILED(status))
{
DEBUG_WINERROR("DuplicateOutput Failed", status);
DeInitialize();
return false;
}
}
DXGI_OUTDUPL_DESC dupDesc;
m_dup->GetDesc(&dupDesc);
DEBUG_INFO("Source Format : %s", GetDXGIFormatStr(dupDesc.ModeDesc.Format));
m_started = false;
m_initialized = true;
return true;
}
bool DXGI::InitRawCapture()
{
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = m_width;
texDesc.Height = m_height;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_STAGING;
texDesc.Format = m_pixelFormat;
texDesc.BindFlags = 0;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
texDesc.MiscFlags = 0;
HRESULT status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[0]);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create texture", status);
return false;
}
return true;
}
bool DXGI::InitYUV420Capture()
{
HRESULT status;
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = m_width;
texDesc.Height = m_height;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_STAGING;
texDesc.Format = DXGI_FORMAT_R8_UNORM;
texDesc.BindFlags = 0;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
texDesc.MiscFlags = 0;
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[0]);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create texture", status);
return false;
}
texDesc.Width /= 2;
texDesc.Height /= 2;
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[1]);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create texture", status);
return false;
}
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture[2]);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create texture", status);
return false;
}
m_textureConverter = new TextureConverter();
if (!m_textureConverter->Initialize(m_deviceContext, m_device, m_width, m_height, FRAME_TYPE_YUV420))
return false;
return true;
}
void DXGI::DeInitialize()
{
if (m_h264)
{
delete m_h264;
m_h264 = NULL;
}
if (m_textureConverter)
{
delete m_textureConverter;
m_textureConverter = NULL;
}
ReleaseFrame();
for(int i = 0; i < _countof(m_cursorRing); ++i)
{
if (m_cursorRing[i].shape.buffer)
delete[] m_cursorRing[i].shape.buffer;
m_cursorRing[i].shape.buffer = NULL;
m_cursorRing[i].shape.bufferSize = 0;
}
for(int i = 0; i < _countof(m_texture); ++i)
m_texture[i] = NULL;
m_dup = NULL;
m_output = NULL;
m_deviceContext = NULL;
m_device = NULL;
m_dxgiFactory = NULL;
m_initialized = false;
}
FrameType DXGI::GetFrameType()
{
if (!m_initialized)
return FRAME_TYPE_INVALID;
return m_frameType;
}
size_t DXGI::GetMaxFrameSize()
{
if (!m_initialized)
return 0;
return (m_width * m_height * 4);
}
unsigned int Capture::DXGI::Capture()
{
if (!m_initialized)
return GRAB_STATUS_ERROR;
CursorInfo & cursor = m_cursorRing[m_cursorWPos];
DXGI_OUTDUPL_FRAME_INFO frameInfo;
IDXGIResourcePtr res;
unsigned int ret;
HRESULT status;
for (int retryCount = 0; retryCount < 2; ++retryCount)
{
ret = ReleaseFrame();
if (ret != GRAB_STATUS_OK)
return ret;
status = m_dup->AcquireNextFrame(1000, &frameInfo, &res);
switch (status)
{
case S_OK:
m_releaseFrame = true;
break;
case DXGI_ERROR_WAIT_TIMEOUT:
return GRAB_STATUS_TIMEOUT;
// desktop switch, mode change, switch DWM on or off or Secure Desktop
case DXGI_ERROR_ACCESS_LOST:
case WAIT_ABANDONED:
return GRAB_STATUS_REINIT;
default:
// unknown failure
DEBUG_WINERROR("AcquireNextFrame failed", status);
return GRAB_STATUS_ERROR;
}
// if the pointer shape has changed
if (frameInfo.PointerShapeBufferSize > 0)
{
// resize the buffer if required
if (cursor.shape.bufferSize < frameInfo.PointerShapeBufferSize)
{
delete[] cursor.shape.buffer;
cursor.shape.buffer = new char[frameInfo.PointerShapeBufferSize];
cursor.shape.bufferSize = frameInfo.PointerShapeBufferSize;
}
cursor.shape.pointerSize = 0;
ret |= GRAB_STATUS_CURSOR;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
status = m_dup->GetFramePointerShape(cursor.shape.bufferSize, cursor.shape.buffer, &cursor.shape.pointerSize, &shapeInfo);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to get the new pointer shape", status);
return GRAB_STATUS_ERROR;
}
switch (shapeInfo.Type)
{
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR : cursor.type = CURSOR_TYPE_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR: cursor.type = CURSOR_TYPE_MASKED_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME : cursor.type = CURSOR_TYPE_MONOCHROME; break;
default:
DEBUG_ERROR("Invalid cursor type");
return GRAB_STATUS_ERROR;
}
cursor.hasShape = true;
cursor.w = shapeInfo.Width;
cursor.h = shapeInfo.Height;
cursor.pitch = shapeInfo.Pitch;
}
// if we have a mouse update
if (frameInfo.LastMouseUpdateTime.QuadPart)
{
if (
m_lastCursorX != frameInfo.PointerPosition.Position.x ||
m_lastCursorY != frameInfo.PointerPosition.Position.y
) {
ret |= GRAB_STATUS_CURSOR;
cursor.hasPos = true;
cursor.x = m_lastCursorX = frameInfo.PointerPosition.Position.x;
cursor.y = m_lastCursorY = frameInfo.PointerPosition.Position.y;
}
}
if (m_lastMouseVis != frameInfo.PointerPosition.Visible)
m_lastMouseVis = frameInfo.PointerPosition.Visible;
cursor.visible = m_lastMouseVis == TRUE;
if (ret & GRAB_STATUS_CURSOR && m_cursorWPos == m_cursorRPos)
{
// atomic advance so we don't have to worry about locking
m_cursorWPos = (m_cursorWPos + 1 == DXGI_CURSOR_RING_SIZE) ? 0 : m_cursorWPos + 1;
}
// if we don't have frame data
if (frameInfo.LastPresentTime.QuadPart == 0)
{
// if there is nothing to update, just start again
if (!ret)
{
--retryCount;
continue;
}
res = NULL;
ret |= GRAB_STATUS_OK;
return ret;
}
// success, break out of the retry loop
break;
}
ret |= GRAB_STATUS_FRAME;
// ensure we have a frame
if (!m_releaseFrame)
{
DEBUG_WINERROR("Failed to acquire next frame", status);
return GRAB_STATUS_ERROR;
}
// get the texture
res.QueryInterface(IID_PPV_ARGS(&m_ftexture));
res = NULL;
if (!m_ftexture)
{
DEBUG_ERROR("Failed to get src ID3D11Texture2D");
return GRAB_STATUS_ERROR;
}
if (!m_started)
{
m_started = true;
// determine the native pixel format
D3D11_TEXTURE2D_DESC dupDesc;
ZeroMemory(&dupDesc, sizeof(dupDesc));
m_ftexture->GetDesc(&dupDesc);
m_pixelFormat = dupDesc.Format;
switch(m_pixelFormat)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
m_frameType = FRAME_TYPE_RGBA;
break;
case DXGI_FORMAT_B8G8R8A8_UNORM:
m_frameType = FRAME_TYPE_BGRA;
break;
case DXGI_FORMAT_R10G10B10A2_UNORM:
m_frameType = FRAME_TYPE_RGBA10;
break;
default:
DEBUG_WARN("Unsupported pixel format %s, enabling conversions", GetDXGIFormatStr(m_pixelFormat));
return GRAB_STATUS_ERROR;
}
DEBUG_INFO("Pixel Format : %s", GetDXGIFormatStr(m_pixelFormat));
for(CaptureOptions::const_iterator it = m_options->cbegin(); it != m_options->cend(); ++it)
{
if (_stricmp(*it, "yuv420") == 0) m_frameType = FRAME_TYPE_YUV420;
}
bool ok = false;
switch (m_frameType)
{
case FRAME_TYPE_BGRA :
case FRAME_TYPE_RGBA :
case FRAME_TYPE_RGBA10: ok = InitRawCapture (); break;
case FRAME_TYPE_YUV420: ok = InitYUV420Capture(); break;
}
if (!ok)
return GRAB_STATUS_ERROR;
}
// initiate the texture copy as early as possible
if (m_frameType == FRAME_TYPE_YUV420)
{
TextureList planes;
if (!m_textureConverter->Convert(m_ftexture, planes))
return GRAB_STATUS_ERROR;
for (int i = 0; i < 3; ++i)
{
ID3D11Texture2DPtr t = planes.at(i);
m_deviceContext->CopyResource(m_texture[i], t);
}
}
else
m_deviceContext->CopyResource(m_texture[0], m_ftexture);
ret |= GRAB_STATUS_OK;
return ret;
}
GrabStatus Capture::DXGI::ReleaseFrame()
{
if (!m_releaseFrame)
return GRAB_STATUS_OK;
m_releaseFrame = false;
m_ftexture = NULL;
switch (m_dup->ReleaseFrame())
{
case S_OK:
break;
case DXGI_ERROR_INVALID_CALL:
DEBUG_ERROR("Frame was already released");
return GRAB_STATUS_ERROR;
case WAIT_ABANDONED:
case DXGI_ERROR_ACCESS_LOST:
return GRAB_STATUS_REINIT;
}
return GRAB_STATUS_OK;
}
GrabStatus Capture::DXGI::DiscardFrame()
{
return ReleaseFrame();
}
GrabStatus Capture::DXGI::GrabFrameRaw(FrameInfo & frame)
{
D3D11_MAPPED_SUBRESOURCE mapping;
HRESULT status;
status = m_deviceContext->Map(m_texture[0], 0, D3D11_MAP_READ, 0, &mapping);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to map the texture", status);
DeInitialize();
return GRAB_STATUS_ERROR;
}
frame.pitch = mapping.RowPitch;
frame.stride = mapping.RowPitch / 4;
memcpySSE(frame.buffer, mapping.pData, frame.pitch * m_height);
m_deviceContext->Unmap(m_texture[0], 0);
return GRAB_STATUS_OK;
}
GrabStatus Capture::DXGI::GrabFrameYUV420(struct FrameInfo & frame)
{
uint8_t * data = (uint8_t *)frame.buffer;
size_t remain = frame.bufferSize;
for(int i = 0; i < 3; ++i)
{
HRESULT status;
D3D11_MAPPED_SUBRESOURCE mapping;
D3D11_TEXTURE2D_DESC desc;
m_texture[i]->GetDesc(&desc);
status = m_deviceContext->Map(m_texture[i], 0, D3D11_MAP_READ, 0, &mapping);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to map the texture", status);
DeInitialize();
return GRAB_STATUS_ERROR;
}
const unsigned int size = desc.Height * desc.Width;
if (size > remain)
{
m_deviceContext->Unmap(m_texture[i], 0);
DEBUG_ERROR("Too much data to fit in buffer");
return GRAB_STATUS_ERROR;
}
const uint8_t * src = (uint8_t *)mapping.pData;
for(unsigned int y = 0; y < desc.Height; ++y)
{
memcpySSE(data, src, desc.Width);
data += desc.Width;
src += mapping.RowPitch;
}
m_deviceContext->Unmap(m_texture[i], 0);
remain -= size;
}
frame.pitch = m_width;
frame.stride = m_width;
return GRAB_STATUS_OK;
}
GrabStatus DXGI::GetFrame(struct FrameInfo & frame)
{
if (!m_ftexture)
{
DEBUG_ERROR("A frame has not been captured");
return GRAB_STATUS_ERROR;
}
frame.width = m_width;
frame.height = m_height;
if (m_frameType == FRAME_TYPE_YUV420)
return GrabFrameYUV420(frame);
return GrabFrameRaw(frame);
}
bool DXGI::GetCursor(CursorInfo & cursor)
{
if (m_cursorRPos == m_cursorWPos)
return false;
cursor = m_cursorRing[m_cursorRPos];
return true;
}
void DXGI::FreeCursor()
{
assert(m_cursorRPos != m_cursorWPos);
CursorInfo & cursor = m_cursorRing[m_cursorRPos];
cursor.visible = false;
cursor.hasPos = false;
cursor.hasShape = false;
m_cursorRPos = (m_cursorRPos + 1 == DXGI_CURSOR_RING_SIZE) ? 0 : m_cursorRPos + 1;
}

View File

@ -1,106 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include "ICapture.h"
#include "Com.h"
#include "TextureConverter.h"
#include "MFT/H264.h"
#include <list>
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>
#define DXGI_CURSOR_RING_SIZE 3
namespace Capture
{
class DXGI : public ICapture
{
public:
DXGI();
virtual ~DXGI();
const char * GetName() { return "DXGI"; }
bool CanInitialize();
bool Initialize(CaptureOptions * options);
void DeInitialize();
bool ReInitialize()
{
DeInitialize();
/*
DXGI needs some time when mode switches occur, failing to do so causes
failure to start and exceptions internal to DXGI
*/
Sleep(400);
return Initialize(m_options);
}
enum FrameType GetFrameType();
size_t GetMaxFrameSize();
unsigned int Capture();
GrabStatus GetFrame (struct FrameInfo & frame );
bool GetCursor(CursorInfo & cursor);
void FreeCursor();
GrabStatus DiscardFrame();
private:
bool InitRawCapture();
bool InitYUV420Capture();
CursorInfo m_cursorRing[DXGI_CURSOR_RING_SIZE];
unsigned int m_cursorRPos, m_cursorWPos;
ID3D11Texture2DPtr m_ftexture;
GrabStatus ReleaseFrame();
GrabStatus GrabFrameRaw (struct FrameInfo & frame);
GrabStatus GrabFrameYUV420 (struct FrameInfo & frame);
CaptureOptions * m_options;
bool m_initialized;
bool m_started;
unsigned int m_width;
unsigned int m_height;
DXGI_FORMAT m_pixelFormat;
enum FrameType m_frameType;
IDXGIFactory1Ptr m_dxgiFactory;
ID3D11DevicePtr m_device;
D3D_FEATURE_LEVEL m_featureLevel;
ID3D11DeviceContextPtr m_deviceContext;
IDXGIOutputPtr m_output;
IDXGIOutputDuplicationPtr m_dup;
bool m_releaseFrame;
ID3D11Texture2DPtr m_texture[3];
TextureConverter * m_textureConverter;
MFT::H264 * m_h264;
int m_lastCursorX, m_lastCursorY;
BOOL m_lastMouseVis;
};
};

View File

@ -1,395 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if CONFIG_CAPTURE_NVFBC
#include "NvFBC.h"
using namespace Capture;
#include <string>
#include "common/debug.h"
#include "common/memcpySSE.h"
#include "Util.h"
#ifdef _WIN64
#define NVFBC_LIBRARY_NAME "NvFBC64.dll"
#else
#define NVFBC_LIBRARY_NAME "NvFBC.dll"
#endif
#define MOPT "privData"
NvFBC::NvFBC() :
m_options(NULL),
m_optNoCrop(false),
m_optNoWait(false),
m_initialized(false),
m_first(true),
m_hDLL(NULL),
m_nvFBC(NULL)
{
}
NvFBC::~NvFBC()
{
}
bool Capture::NvFBC::CanInitialize()
{
return true;
}
bool NvFBC::Initialize(CaptureOptions * options)
{
if (m_initialized)
DeInitialize();
m_first = true;
m_options = options;
m_optNoCrop = false;
uint8_t * privData = NULL;
NvU32 privDataSize = 0;
for (CaptureOptions::const_iterator it = options->cbegin(); it != options->cend(); ++it)
{
if (_strcmpi(*it, "nocrop") == 0) { m_optNoCrop = false; continue; }
if (_strcmpi(*it, "nowait") == 0) { m_optNoWait = true ; continue; }
if (_strnicmp(*it, MOPT " ", sizeof(MOPT)) == 0)
{
std::string value(*it);
value.erase(0, sizeof(MOPT));
if (value.empty() || value.length() & 1)
continue;
privDataSize = (NvU32)(value.length() / 2);
privData = new uint8_t[privDataSize];
uint8_t *p = privData;
for (int i = 0; i < value.length(); i += 2, ++p)
{
char hex[3];
#pragma warning(disable:4996)
value.copy(hex, 2, i);
#pragma warning(restore:4996)
hex[2] = 0;
*p = (uint8_t)strtoul(hex, NULL, 16);
}
}
}
std::string nvfbc = Util::GetSystemRoot() + "\\" + NVFBC_LIBRARY_NAME;
m_hDLL = LoadLibraryA(nvfbc.c_str());
if (!m_hDLL)
{
DEBUG_ERROR("Failed to load the NvFBC library: %d - %s", (int)GetLastError(), nvfbc.c_str());
return false;
}
m_fnCreateEx = (NvFBC_CreateFunctionExType )GetProcAddress(m_hDLL, "NvFBC_CreateEx" );
m_fnSetGlobalFlags = (NvFBC_SetGlobalFlagsType )GetProcAddress(m_hDLL, "NvFBC_SetGlobalFlags");
m_fnGetStatusEx = (NvFBC_GetStatusExFunctionType)GetProcAddress(m_hDLL, "NvFBC_GetStatusEx" );
m_fnEnable = (NvFBC_EnableFunctionType )GetProcAddress(m_hDLL, "NvFBC_Enable" );
if (!m_fnCreateEx || !m_fnSetGlobalFlags || !m_fnGetStatusEx || !m_fnEnable)
{
DEBUG_ERROR("Unable to locate required entry points in %s", nvfbc.c_str());
DeInitialize();
return false;
}
NvFBCStatusEx status;
ZeroMemory(&status, sizeof(NvFBCStatusEx));
status.dwVersion = NVFBC_STATUS_VER;
status.dwAdapterIdx = 0;
NVFBCRESULT ret = m_fnGetStatusEx(&status);
if (ret != NVFBC_SUCCESS)
{
DEBUG_ERROR("Failed to get NvFBC status");
DeInitialize();
return false;
}
if (!status.bIsCapturePossible)
{
DEBUG_INFO("Attempting to enable NvFBC");
switch(m_fnEnable(NVFBC_STATE_ENABLE))
{
case NVFBC_SUCCESS:
DEBUG_INFO("Success, attempting to get status again");
if (m_fnGetStatusEx(&status) != NVFBC_SUCCESS)
{
DEBUG_ERROR("Failed to get NvFBC status");
DeInitialize();
return false;
}
break;
case NVFBC_ERROR_INSUFFICIENT_PRIVILEGES:
DEBUG_ERROR("Please run once as administrator to enable the NvFBC API");
DeInitialize();
return false;
default:
DEBUG_ERROR("Unknown failure enabling NvFBC");
DeInitialize();
return false;
}
if (!status.bIsCapturePossible)
{
DEBUG_ERROR("Capture is not possible, unsupported device or driver");
DeInitialize();
return false;
}
}
if (!status.bCanCreateNow)
{
DEBUG_ERROR("Can not create an instance of NvFBC at this time");
DeInitialize();
return false;
}
NvFBCCreateParams params;
ZeroMemory(&params, sizeof(NvFBCCreateParams));
params.dwVersion = NVFBC_CREATE_PARAMS_VER;
params.dwInterfaceType = NVFBC_TO_SYS;
params.pDevice = NULL;
params.dwAdapterIdx = 0;
params.dwPrivateDataSize = privDataSize;
params.pPrivateData = privData;
if (m_fnCreateEx(&params) != NVFBC_SUCCESS)
{
if (privData)
delete [] privData;
DEBUG_ERROR("Failed to create an instance of NvFBC");
DeInitialize();
return false;
}
if (privData)
delete[] privData;
m_maxCaptureWidth = params.dwMaxDisplayWidth;
m_maxCaptureHeight = params.dwMaxDisplayHeight;
m_nvFBC = static_cast<NvFBCToSys *>(params.pNvFBC);
NVFBC_TOSYS_SETUP_PARAMS setupParams;
ZeroMemory(&setupParams, sizeof(NVFBC_TOSYS_SETUP_PARAMS));
setupParams.dwVersion = NVFBC_TOSYS_SETUP_PARAMS_VER;
setupParams.eMode = NVFBC_TOSYS_ARGB;
setupParams.bWithHWCursor = TRUE;
setupParams.bDiffMap = TRUE;
setupParams.eDiffMapBlockSize = NVFBC_TOSYS_DIFFMAP_BLOCKSIZE_128X128;
setupParams.ppBuffer = (void **)&m_frameBuffer;
setupParams.ppDiffMap = (void **)&m_diffMap;
if (m_nvFBC->NvFBCToSysSetUp(&setupParams) != NVFBC_SUCCESS)
{
DEBUG_ERROR("NvFBCToSysSetUp Failed");
DeInitialize();
return false;
}
// this is required according to NVidia sample code
Sleep(100);
HMONITOR monitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY);
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFO);
unsigned int screenWidth, screenHeight;
GetMonitorInfo(monitor, &monitorInfo);
screenWidth = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
screenHeight = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
ZeroMemory(&m_grabFrameParams, sizeof(NVFBC_TOSYS_GRAB_FRAME_PARAMS));
ZeroMemory(&m_grabInfo, sizeof(NvFBCFrameGrabInfo));
m_grabFrameParams.dwVersion = NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER;
m_grabFrameParams.dwFlags = m_optNoWait ? NVFBC_TOSYS_NOWAIT : NVFBC_TOSYS_WAIT_WITH_TIMEOUT;
m_grabFrameParams.dwWaitTime = 1000;
m_grabFrameParams.eGMode = NVFBC_TOSYS_SOURCEMODE_CROP;
m_grabFrameParams.dwStartX = 0;
m_grabFrameParams.dwStartY = 0;
m_grabFrameParams.dwTargetWidth = screenWidth;
m_grabFrameParams.dwTargetHeight = screenHeight;
m_grabFrameParams.pNvFBCFrameGrabInfo = &m_grabInfo;
m_initialized = true;
return true;
}
void NvFBC::DeInitialize()
{
m_frameBuffer = NULL;
if (m_nvFBC)
{
m_nvFBC->NvFBCToSysRelease();
m_nvFBC = NULL;
}
m_maxCaptureWidth = 0;
m_maxCaptureHeight = 0;
m_fnCreateEx = NULL;
m_fnSetGlobalFlags = NULL;
m_fnGetStatusEx = NULL;
m_fnEnable = NULL;
if (m_hDLL)
{
FreeLibrary(m_hDLL);
m_hDLL = NULL;
}
m_initialized = false;
}
FrameType NvFBC::GetFrameType()
{
if (!m_initialized)
return FRAME_TYPE_INVALID;
return FRAME_TYPE_BGRA;
}
size_t NvFBC::GetMaxFrameSize()
{
if (!m_initialized)
return false;
return m_maxCaptureWidth * m_maxCaptureHeight * 4;
}
unsigned int Capture::NvFBC::Capture()
{
if (!m_initialized)
return GRAB_STATUS_ERROR;
for (int i = 0; i < 2; ++i)
{
NVFBCRESULT status = m_nvFBC->NvFBCToSysGrabFrame(&m_grabFrameParams);
if (status == NVFBC_SUCCESS)
{
const int diffW = (m_grabInfo.dwWidth + 0x7F) >> 7;
const int diffH = (m_grabInfo.dwHeight + 0x7F) >> 7;
bool hasDiff = false;
for (int y = 0; y < diffH && !hasDiff; ++y)
for (int x = 0; x < diffW; ++x)
if (m_diffMap[y * diffW + x])
{
hasDiff = true;
break;
}
if (!hasDiff)
{
i = 0;
continue;
}
break;
}
else
{
if (status == NVFBC_ERROR_DYNAMIC_DISABLE)
{
DEBUG_ERROR("NvFBC was disabled by someone else");
return GRAB_STATUS_ERROR;
}
if (status == NVFBC_ERROR_INVALIDATED_SESSION)
{
DEBUG_WARN("Session was invalidated, attempting to restart");
return GRAB_STATUS_REINIT;
}
if (i == 1)
{
DEBUG_ERROR("NvFBCToSysGrabFrame failed");
return GRAB_STATUS_ERROR;
}
}
}
// if the capture size doesn't match the screen resolution then re-initialize to avoid
// copying black/blank areas of the screen
HMONITOR monitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY);
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFO);
unsigned int screenWidth, screenHeight;
GetMonitorInfo(monitor, &monitorInfo);
screenWidth = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
screenHeight = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
if (m_grabInfo.dwWidth != screenWidth || m_grabInfo.dwHeight != screenHeight)
{
DEBUG_INFO("Resolution change detected");
return GRAB_STATUS_REINIT;
}
// turn off the cursor on the first frame as NvFBC is drawing it
if (m_first)
return GRAB_STATUS_OK | GRAB_STATUS_FRAME | GRAB_STATUS_CURSOR;
else
return GRAB_STATUS_OK | GRAB_STATUS_FRAME;
}
bool Capture::NvFBC::GetCursor(CursorInfo & cursor)
{
cursor.hasShape = false;
cursor.hasPos = false;
cursor.visible = false;
if (m_first)
{
m_first = false;
return true;
}
return false;
}
void Capture::NvFBC::FreeCursor()
{
}
GrabStatus Capture::NvFBC::DiscardFrame()
{
return GrabStatus();
}
enum GrabStatus NvFBC::GetFrame(struct FrameInfo & frame)
{
if (!m_initialized)
return GRAB_STATUS_ERROR;
frame.width = m_grabInfo.dwWidth;
frame.height = m_grabInfo.dwHeight;
frame.stride = m_grabInfo.dwBufferWidth;
frame.pitch = m_grabInfo.dwBufferWidth * 4;
memcpySSE((uint8_t*)frame.buffer, (uint8_t *)m_frameBuffer, frame.pitch * frame.height);
return GRAB_STATUS_OK;
}
#endif// CONFIG_CAPTURE_NVFBC

View File

@ -1,79 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if CONFIG_CAPTURE_NVFBC
#pragma once
#include "ICapture.h"
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <NvFBC/nvFBC.h>
#include <NvFBC/nvFBCToSys.h>
namespace Capture
{
class NvFBC : public ICapture
{
public:
NvFBC();
~NvFBC();
const char * GetName() { return "NvFBC"; }
bool CanInitialize();
bool Initialize(CaptureOptions * options);
void DeInitialize();
bool ReInitialize()
{
DeInitialize();
return Initialize(m_options);
}
enum FrameType GetFrameType();
size_t GetMaxFrameSize();
unsigned int Capture();
enum GrabStatus GetFrame(struct FrameInfo & frame);
bool GetCursor(CursorInfo & cursor);
void FreeCursor() ;
enum GrabStatus DiscardFrame();
private:
CaptureOptions * m_options;
bool m_optNoCrop;
bool m_optNoWait;
bool m_initialized;
bool m_first;
HMODULE m_hDLL;
NvFBC_CreateFunctionExType m_fnCreateEx;
NvFBC_SetGlobalFlagsType m_fnSetGlobalFlags;
NvFBC_GetStatusExFunctionType m_fnGetStatusEx;
NvFBC_EnableFunctionType m_fnEnable;
DWORD m_maxCaptureWidth, m_maxCaptureHeight;
NvFBCToSys * m_nvFBC;
uint8_t * m_frameBuffer;
uint8_t * m_diffMap;
NvFBCFrameGrabInfo m_grabInfo;
NVFBC_TOSYS_GRAB_FRAME_PARAMS m_grabFrameParams;
};
};
#endif //CONFIG_CAPTURE_NVFBC

View File

@ -1,95 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <vector>
#include "common/debug.h"
#include "ICapture.h"
#if CONFIG_CAPTURE_NVFBC
#include "Capture/NvFBC.h"
#endif
#include "Capture/DXGI.h"
class CaptureFactory
{
public:
typedef std::vector<ICapture *> DeviceList;
static DeviceList & GetDevices()
{
static DeviceList devices;
if (!devices.empty())
return devices;
#if CONFIG_CAPTURE_NVFBC
devices.push_back(new Capture::NvFBC());
#endif
devices.push_back(new Capture::DXGI ());
return devices;
}
static ICapture * GetDevice(const char * name, CaptureOptions * options)
{
DeviceList devices = GetDevices();
for (DeviceList::const_iterator it = devices.begin(); it != devices.end(); ++it)
{
ICapture * device = *it;
if (_strcmpi(name, device->GetName()) != 0)
continue;
if (device->Initialize(options))
{
DEBUG_INFO("Using %s", device->GetName());
return device;
}
device->DeInitialize();
DEBUG_ERROR("Failed to initialize %s", device->GetName());
return NULL;
}
DEBUG_ERROR("No such device: %s", name);
return NULL;
}
static ICapture * DetectDevice(CaptureOptions * options)
{
DeviceList devices = GetDevices();
for (DeviceList::const_iterator it = devices.cbegin(); it != devices.cend(); ++it)
{
ICapture * device = *it;
DEBUG_INFO("Trying %s", device->GetName());
if (device->Initialize(options))
{
DEBUG_INFO("Using %s", device->GetName());
return device;
}
device->DeInitialize();
}
DEBUG_ERROR("Failed to initialize a capture device");
return NULL;
}
};

View File

@ -1,58 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <comdef.h>
#include <dxgi1_2.h>
#include <dxgi1_5.h>
#include <d3d11.h>
#include <mftransform.h>
_COM_SMARTPTR_TYPEDEF(IDXGIFactory1 , __uuidof(IDXGIFactory1 ));
_COM_SMARTPTR_TYPEDEF(ID3D11Device , __uuidof(ID3D11Device ));
_COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext , __uuidof(ID3D11DeviceContext ));
_COM_SMARTPTR_TYPEDEF(IDXGIDevice , __uuidof(IDXGIDevice ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutput1 , __uuidof(IDXGIOutput1 ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutput5 , __uuidof(IDXGIOutput5 ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutput , __uuidof(IDXGIOutput ));
_COM_SMARTPTR_TYPEDEF(IDXGIAdapter1 , __uuidof(IDXGIAdapter1 ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutputDuplication , __uuidof(IDXGIOutputDuplication ));
_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D , __uuidof(ID3D11Texture2D ));
_COM_SMARTPTR_TYPEDEF(IDXGIResource , __uuidof(IDXGIResource ));
_COM_SMARTPTR_TYPEDEF(ID3D10Multithread , __uuidof(ID3D10Multithread ));
_COM_SMARTPTR_TYPEDEF(IMFActivate , __uuidof(IMFActivate ));
_COM_SMARTPTR_TYPEDEF(IMFAttributes , __uuidof(IMFAttributes ));
_COM_SMARTPTR_TYPEDEF(IMFDXGIDeviceManager , __uuidof(IMFDXGIDeviceManager ));
_COM_SMARTPTR_TYPEDEF(IMFTransform , __uuidof(IMFTransform ));
_COM_SMARTPTR_TYPEDEF(IMFMediaEvent , __uuidof(IMFMediaEvent ));
_COM_SMARTPTR_TYPEDEF(IMFMediaEventGenerator , __uuidof(IMFMediaEventGenerator ));
_COM_SMARTPTR_TYPEDEF(IMFMediaType , __uuidof(IMFMediaType ));
_COM_SMARTPTR_TYPEDEF(IMFSample , __uuidof(IMFSample ));
_COM_SMARTPTR_TYPEDEF(IMFMediaBuffer , __uuidof(IMFMediaBuffer ));
_COM_SMARTPTR_TYPEDEF(IMF2DBuffer , __uuidof(IMF2DBuffer ));
_COM_SMARTPTR_TYPEDEF(ID3D11RenderTargetView , __uuidof(ID3D11RenderTargetView ));
_COM_SMARTPTR_TYPEDEF(ID3D11ShaderResourceView, __uuidof(ID3D11ShaderResourceView));
_COM_SMARTPTR_TYPEDEF(ID3D11DepthStencilView , __uuidof(ID3D11DepthStencilView ));
_COM_SMARTPTR_TYPEDEF(ID3D11InputLayout , __uuidof(ID3D11InputLayout ));
_COM_SMARTPTR_TYPEDEF(ID3D11VertexShader , __uuidof(ID3D11VertexShader ));
_COM_SMARTPTR_TYPEDEF(ID3D11PixelShader , __uuidof(ID3D11PixelShader ));
_COM_SMARTPTR_TYPEDEF(ID3D11SamplerState , __uuidof(ID3D11SamplerState ));
_COM_SMARTPTR_TYPEDEF(ID3D11Buffer , __uuidof(ID3D11Buffer ));

View File

@ -1,80 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CrashHandler.h"
typedef BOOL (WINAPI * PMiniDumpWriteDump)(
_In_ HANDLE hProcess,
_In_ DWORD ProcessId,
_In_ HANDLE hFile,
_In_ MINIDUMP_TYPE DumpType,
_In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
_In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
_In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
void CrashHandler::Initialize()
{
SetUnhandledExceptionFilter(CrashHandler::ExceptionFilter);
}
LONG WINAPI CrashHandler::ExceptionFilter(struct _EXCEPTION_POINTERS * apExceptionInfo)
{
HMODULE lib;
PMiniDumpWriteDump fn_MiniDumpWriteDump;
lib = LoadLibraryA("dbghelp.dll");
if (!lib)
return EXCEPTION_CONTINUE_SEARCH;
fn_MiniDumpWriteDump = (PMiniDumpWriteDump)GetProcAddress(lib, "MiniDumpWriteDump");
if (!fn_MiniDumpWriteDump)
return EXCEPTION_CONTINUE_SEARCH;
HANDLE hFile = CreateFileA(
"looking-glass-host.dump",
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
return EXCEPTION_CONTINUE_SEARCH;
_MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = GetCurrentThreadId();
info.ExceptionPointers = apExceptionInfo;
info.ClientPointers = FALSE;
fn_MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&info,
NULL,
NULL
);
CloseHandle(hFile);
return EXCEPTION_CONTINUE_SEARCH;
}

View File

@ -1,30 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <windows.h>
#include <dbghelp.h>
class CrashHandler
{
public:
static void Initialize();
private:
static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS * apExceptionInfo);
};

View File

@ -1,84 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include "common/KVMFR.h"
#include <vector>
#include <windows.h>
struct CursorBuffer
{
unsigned int bufferSize;
char * buffer;
unsigned int pointerSize;
};
struct CursorInfo
{
bool visible;
bool hasPos;
bool hasShape;
int x, y;
enum CursorType type;
unsigned int w, h;
unsigned int pitch;
CursorBuffer shape;
};
struct FrameInfo
{
unsigned int width;
unsigned int height;
unsigned int stride;
unsigned int pitch;
void * buffer;
size_t bufferSize;
};
enum GrabStatus
{
GRAB_STATUS_OK = 1,
GRAB_STATUS_TIMEOUT = 2,
GRAB_STATUS_REINIT = 4,
GRAB_STATUS_CURSOR = 8,
GRAB_STATUS_FRAME = 16,
GRAB_STATUS_ERROR = 32
};
typedef std::vector<const char *> CaptureOptions;
class ICapture
{
public:
virtual const char * GetName() = 0;
virtual bool CanInitialize() = 0;
virtual bool Initialize(CaptureOptions * options) = 0;
virtual void DeInitialize() = 0;
virtual bool ReInitialize() = 0;
virtual enum FrameType GetFrameType() = 0;
virtual size_t GetMaxFrameSize() = 0;
virtual unsigned int Capture() = 0;
virtual enum GrabStatus GetFrame(struct FrameInfo & frame) = 0;
virtual bool GetCursor(CursorInfo & cursor) = 0;
virtual void FreeCursor() = 0;
virtual enum GrabStatus DiscardFrame() = 0;
};

View File

@ -1,380 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "IVSHMEM.h"
#include <windows.h>
#include <setupapi.h>
#include "kvm-guest-drivers-windows/ivshmem/Public.h"
#include "common/debug.h"
IVSHMEM * IVSHMEM::m_instance = NULL;
void IVSHMEM::listDevices() {
HDEVINFO deviceInfoSet;
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
fprintf(stderr, "Found devices:\n");
DWORD i = 0;
while(SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, i, &deviceInterfaceData) != FALSE)
{
DWORD reqSize = 0;
SP_DEVINFO_DATA d;
d.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, &d);
if (!reqSize)
{
fprintf(stderr, "SetupDiGetDeviceInterfaceDetail");
break;
}
infData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(reqSize));
ZeroMemory(infData, reqSize);
infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
{
fprintf(stderr, "SetupDiGetDeviceInterfaceDetail");
break;
}
DWORD bus, addr, slot, func;
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, &d,SPDRP_BUSNUMBER,NULL,(PBYTE)&bus,sizeof(bus),NULL))
{
DEBUG_ERROR("SetupDiGetDeviceRegistryProperty - SPDRP_BUSNUMBER: %lu\n", GetLastError());
free(infData);
break;
}
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, &d,SPDRP_ADDRESS,NULL, (PBYTE)&addr,sizeof(addr),NULL))
{
DEBUG_ERROR("SetupDiGetDeviceRegistryProperty - SPDRP_ADDRESS: %lu\n", GetLastError());
free(infData);
break;
}
slot = (addr >> 16) & 0xFFFF;
func = addr & 0xFFFF;
fprintf(stderr, "[%lu] Found Device: %ls\n"
" Bus: 0x%lx\n"
" Slot: 0x%lx\n"
" Func: 0x%lx\n",
i, infData->DevicePath, bus, slot, func);
i++;
}
DWORD error = GetLastError();
if (error != ERROR_NO_MORE_ITEMS)
{
fprintf(stderr, "Unknown error on index %u: %lu\n", i, error);
}
fprintf(stderr, "%lu devices found\n\n", i);
}
IVSHMEM::IVSHMEM() :
m_initialized(false),
m_handle(INVALID_HANDLE_VALUE),
m_gotSize(false),
m_gotPeerID(false),
m_gotMemory(false)
{
}
IVSHMEM::~IVSHMEM()
{
DeInitialize();
}
bool IVSHMEM::Initialize(PCI_DEVICE dev)
{
if (m_initialized)
DeInitialize();
HDEVINFO deviceInfoSet;
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD devid = 0;
while (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, devid, &deviceInterfaceData) != FALSE)
{
DWORD reqSize = 0;
SP_DEVINFO_DATA d;
d.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, &d);
if (!reqSize)
{
DEBUG_ERROR("SetupDiGetDeviceInterfaceDetail");
break;
}
infData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(reqSize));
ZeroMemory(infData, reqSize);
infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
{
DEBUG_ERROR("SetupDiGetDeviceInterfaceDetail");
free(infData);
break;
}
DWORD bus, addr, slot, func;
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, &d,SPDRP_BUSNUMBER,NULL,(PBYTE)&bus,sizeof(bus),NULL))
{
DEBUG_ERROR("SetupDiGetDeviceRegistryProperty - SPDRP_BUSNUMBER");
free(infData);
break;
}
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, &d,SPDRP_ADDRESS,NULL, (PBYTE)&addr,sizeof(addr),NULL))
{
DEBUG_ERROR("SetupDiGetDeviceRegistryProperty - SPDRP_ADDRESS");
free(infData);
break;
}
slot = (addr >> 16) & 0xFFFF;
func = addr & 0xFFFF;
if (dev.bus != bus || dev.addr != slot || dev.func != func) //not the right device, keep searching
{
free(infData);
devid++;
continue;
}
fprintf(stderr, "Found Device at Index %lu: %ls\n"
" Bus: %lu\n"
" Addr: %lu\n"
" Func: %lu\n",
devid, infData->DevicePath, bus, slot, func);
m_handle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
if (m_handle == INVALID_HANDLE_VALUE)
{
DEBUG_ERROR("CreateFile returned INVALID_HANDLE_VALUE");
free(infData);
break;
}
m_initialized = true;
break;
}
DWORD error = GetLastError();
if (m_initialized == false)
{
if (error == ERROR_NO_MORE_ITEMS)
{
DEBUG_ERROR("Unable to enumerate the device, is it attached?");
}
else
{
DEBUG_ERROR("Unable to enumerate the device. Error: %lu\n", error);
}
}
SetupDiDestroyDeviceInfoList(deviceInfoSet);
return m_initialized;
}
void IVSHMEM::DeInitialize()
{
if (!m_initialized)
return;
if (m_gotMemory)
{
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL))
DEBUG_ERROR("DeviceIoControl failed: %d", (int)GetLastError());
m_memory = NULL;
}
if (m_handle != INVALID_HANDLE_VALUE)
CloseHandle(m_handle);
m_initialized = false;
m_handle = INVALID_HANDLE_VALUE;
m_gotSize = false;
m_gotPeerID = false;
m_gotVectors = false;
m_gotMemory = false;
}
bool IVSHMEM::IsInitialized()
{
return m_initialized;
}
UINT64 IVSHMEM::GetSize()
{
if (!m_initialized)
return 0;
if (m_gotSize)
return m_size;
IVSHMEM_SIZE size;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL))
{
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
return 0;
}
m_gotSize = true;
m_size = static_cast<UINT64>(size);
return m_size;
}
UINT16 IVSHMEM::GetPeerID()
{
if (!m_initialized)
return 0;
if (m_gotPeerID)
return m_peerID;
IVSHMEM_PEERID peerID;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &peerID, sizeof(IVSHMEM_PEERID), NULL, NULL))
{
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
return 0;
}
m_gotPeerID = true;
m_peerID = static_cast<UINT16>(peerID);
return m_peerID;
}
UINT16 IVSHMEM::GetVectors()
{
if (!m_initialized)
return 0;
if (!m_gotVectors)
return 0;
return m_vectors;
}
void * IVSHMEM::GetMemory()
{
if (!m_initialized)
return NULL;
if (m_gotMemory)
return m_memory;
// this if define can be removed later once everyone is un the latest version
// old versions of the IVSHMEM driver ignore the input argument, as such this
// is completely backwards compatible
#if defined(IVSHMEM_CACHE_WRITECOMBINED)
IVSHMEM_MMAP_CONFIG config;
config.cacheMode = IVSHMEM_CACHE_WRITECOMBINED;
#endif
IVSHMEM_MMAP map;
ZeroMemory(&map, sizeof(IVSHMEM_MMAP));
if (!DeviceIoControl(
m_handle,
IOCTL_IVSHMEM_REQUEST_MMAP,
#if defined(IVSHMEM_CACHE_WRITECOMBINED)
&config, sizeof(IVSHMEM_MMAP_CONFIG),
#else
NULL , 0,
#endif
&map , sizeof(IVSHMEM_MMAP ),
NULL, NULL))
{
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
return NULL;
}
m_gotSize = true;
m_gotPeerID = true;
m_gotMemory = true;
m_gotVectors = true;
m_size = static_cast<UINT64>(map.size );
m_peerID = static_cast<UINT16>(map.peerID );
m_vectors = static_cast<UINT16>(map.vectors);
m_memory = map.ptr;
return m_memory;
}
HANDLE IVSHMEM::CreateVectorEvent(UINT16 vector)
{
if (!m_initialized)
return INVALID_HANDLE_VALUE;
HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (event == INVALID_HANDLE_VALUE)
{
DEBUG_ERROR("CreateEvent Failed: %d", (int)GetLastError());
return INVALID_HANDLE_VALUE;
}
IVSHMEM_EVENT msg;
msg.event = event;
msg.singleShot = false;
msg.vector = vector;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REGISTER_EVENT, &msg, sizeof(IVSHMEM_EVENT), NULL, 0, NULL, NULL))
{
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
CloseHandle(event);
return INVALID_HANDLE_VALUE;
}
return event;
}
bool IVSHMEM::RingDoorbell(UINT16 peerID, UINT16 door)
{
if (!m_initialized)
return false;
IVSHMEM_RING msg;
msg.peerID = peerID;
msg.vector = door;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RING_DOORBELL, &msg, sizeof(IVSHMEM_RING), NULL, 0, NULL, NULL))
{
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
return false;
}
return true;
}

View File

@ -1,69 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <stdbool.h>
struct PCI_DEVICE {
BYTE bus, addr, func;
};
class IVSHMEM
{
public:
static IVSHMEM * Get()
{
if (!m_instance)
m_instance = new IVSHMEM();
return m_instance;
}
static void listDevices();
bool Initialize(PCI_DEVICE dev);
void DeInitialize();
bool IsInitialized();
UINT64 GetSize();
UINT16 GetPeerID();
UINT16 GetVectors();
void * GetMemory();
HANDLE CreateVectorEvent(UINT16 vector);
bool RingDoorbell(UINT16 peerID, UINT16 door);
protected:
private:
static IVSHMEM * m_instance;
IVSHMEM();
~IVSHMEM();
bool m_initialized;
HANDLE m_handle;
UINT64 m_size ; bool m_gotSize ;
UINT16 m_peerID ; bool m_gotPeerID;
void * m_memory ; bool m_gotMemory;
UINT16 m_vectors; bool m_gotVectors;
};

View File

@ -1,60 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "looking-glass-host", "looking-glass-host.vcxproj", "{D439DE3E-32FB-4599-8B5D-C92674D400D4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync-test", "sync-test\sync-test.vcxproj", "{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE5778A4-4447-410B-B8E8-D86087F62CFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - NvFBC|x64 = Debug - NvFBC|x64
Debug - NvFBC|x86 = Debug - NvFBC|x86
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release - NvFBC|x64 = Release - NvFBC|x64
Release - NvFBC|x86 = Release - NvFBC|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x64.ActiveCfg = Debug - NvFBC|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x64.Build.0 = Debug - NvFBC|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x86.ActiveCfg = Debug - NvFBC|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x86.Build.0 = Debug - NvFBC|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x64.ActiveCfg = Debug|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x64.Build.0 = Debug|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x86.ActiveCfg = Debug|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x86.Build.0 = Debug|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x64.ActiveCfg = Release - NvFBC|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x64.Build.0 = Release - NvFBC|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x86.ActiveCfg = Release - NvFBC|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x86.Build.0 = Release - NvFBC|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x64.ActiveCfg = Release|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x64.Build.0 = Release|x64
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x86.ActiveCfg = Release|Win32
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x86.Build.0 = Release|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x64.ActiveCfg = Debug - NvFBC|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x64.Build.0 = Debug - NvFBC|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x86.ActiveCfg = Debug - NvFBC|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x86.Build.0 = Debug - NvFBC|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x64.ActiveCfg = Debug|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x64.Build.0 = Debug|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x86.ActiveCfg = Debug|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x86.Build.0 = Debug|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x64.ActiveCfg = Release - NvFBC|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x64.Build.0 = Release - NvFBC|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x86.ActiveCfg = Release - NvFBC|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x86.Build.0 = Release - NvFBC|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x64.ActiveCfg = Release|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x64.Build.0 = Release|x64
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x86.ActiveCfg = Release|Win32
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,453 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "MFT/H264.h"
#include "WinDebug.h"
#include "common/memcpySSE.h"
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <wmcodecdsp.h>
#include <codecapi.h>
#include <mferror.h>
#include <evr.h>
using namespace MFT;
#if __MINGW32__
EXTERN_GUID(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0);
EXTERN_GUID(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, 0xf81da2c, 0xb537, 0x4672, 0xa8, 0xb2, 0xa6, 0x81, 0xb1, 0x73, 0x07, 0xa3);
EXTERN_GUID(MF_SA_D3D11_AWARE, 0x206b4fc8, 0xfcf9, 0x4c51, 0xaf, 0xe3, 0x97, 0x64, 0x36, 0x9e, 0x33, 0xa0);
#define METransformUnknown 600
#define METransformNeedInput 601
#define METransformHaveOutput 602
#define METransformDrainComplete 603
#define METransformMarker 604
#endif
MFT::H264::H264() :
m_cRef(1)
{
MFStartup(MF_VERSION);
}
MFT::H264::~H264()
{
DeInitialize();
}
bool MFT::H264::Initialize(ID3D11DevicePtr device, unsigned int width, unsigned int height)
{
DeInitialize();
HRESULT status;
MFT_REGISTER_TYPE_INFO typeInfo;
IMFActivate **activationPointers;
UINT32 activationPointerCount;
m_device = device;
m_width = width;
m_height = height;
m_encodeEvent = CreateEvent(NULL, TRUE , FALSE, NULL);
m_shutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection(&m_encodeCS);
ID3D10MultithreadPtr mt(m_device);
mt->SetMultithreadProtected(TRUE);
mt = NULL;
typeInfo.guidMajorType = MFMediaType_Video;
typeInfo.guidSubtype = MFVideoFormat_H264;
status = MFTEnumEx(
MFT_CATEGORY_VIDEO_ENCODER,
MFT_ENUM_FLAG_HARDWARE,
NULL,
&typeInfo,
&activationPointers,
&activationPointerCount
);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to enumerate encoder MFTs", status);
return false;
}
if (activationPointerCount == 0)
{
DEBUG_WINERROR("Hardware H264 MFT not available", status);
return false;
}
{
UINT32 nameLen = 0;
activationPointers[0]->GetStringLength(MFT_FRIENDLY_NAME_Attribute, &nameLen);
wchar_t * name = new wchar_t[nameLen + 1];
activationPointers[0]->GetString(MFT_FRIENDLY_NAME_Attribute, name, nameLen + 1, NULL);
DEBUG_INFO("Using Encoder: %S", name);
delete[] name;
}
m_mfActivation = activationPointers[0];
CoTaskMemFree(activationPointers);
status = m_mfActivation->ActivateObject(IID_PPV_ARGS(&m_mfTransform));
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create H264 encoder MFT", status);
return false;
}
IMFAttributesPtr attribs;
m_mfTransform->GetAttributes(&attribs);
attribs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
attribs->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE);
attribs->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE);
attribs->SetUINT32(MF_LOW_LATENCY, TRUE);
UINT32 d3d11Aware = 0;
UINT32 async = 0;
attribs->GetUINT32(MF_TRANSFORM_ASYNC, &async);
attribs->GetUINT32(MF_SA_D3D11_AWARE, &d3d11Aware);
if (async)
attribs->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
attribs = NULL;
status = m_mfTransform.QueryInterface(IID_PPV_ARGS(&m_mediaEventGen));
if (FAILED(status))
{
DEBUG_WINERROR("Failed to obtain the media event generator interface", status);
return false;
}
status = m_mediaEventGen->BeginGetEvent(this, NULL);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the begin get event", status);
return false;
}
if (d3d11Aware)
{
MFCreateDXGIDeviceManager(&m_resetToken, &m_mfDeviceManager);
status = m_mfDeviceManager->ResetDevice(m_device, m_resetToken);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to call reset device", status);
return false;
}
status = m_mfTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, ULONG_PTR(m_mfDeviceManager.GetInterfacePtr()));
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the D3D manager", status);
return false;
}
}
IMFMediaTypePtr outType;
MFCreateMediaType(&outType);
outType->SetGUID (MF_MT_MAJOR_TYPE , MFMediaType_Video );
outType->SetGUID (MF_MT_SUBTYPE , MFVideoFormat_H264 );
outType->SetUINT32(MF_MT_AVG_BITRATE , 384 * 1000 );
outType->SetUINT32(MF_MT_INTERLACE_MODE , MFVideoInterlace_Progressive);
outType->SetUINT32(MF_MT_MPEG2_PROFILE , eAVEncH264VProfile_High );
outType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
MFSetAttributeSize (outType, MF_MT_FRAME_SIZE , m_width, m_height);
MFSetAttributeRatio(outType, MF_MT_FRAME_RATE , 60 , 1 );
MFSetAttributeRatio(outType, MF_MT_PIXEL_ASPECT_RATIO, 1 , 1 );
status = m_mfTransform->SetOutputType(0, outType, 0);
outType = NULL;
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the output media type on the H264 encoder MFT", status);
return false;
}
IMFMediaTypePtr inType;
MFCreateMediaType(&inType);
inType->SetGUID (MF_MT_MAJOR_TYPE , MFMediaType_Video );
inType->SetGUID (MF_MT_SUBTYPE , MFVideoFormat_NV12 );
inType->SetUINT32(MF_MT_INTERLACE_MODE , MFVideoInterlace_Progressive);
inType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE );
MFSetAttributeSize (inType, MF_MT_FRAME_SIZE , m_width, m_height);
MFSetAttributeRatio(inType, MF_MT_FRAME_RATE , 60 , 1 );
MFSetAttributeRatio(inType, MF_MT_PIXEL_ASPECT_RATIO, 1 , 1 );
status = m_mfTransform->SetInputType(0, inType, 0);
inType = NULL;
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the input media type on the H264 encoder MFT", status);
return false;
}
m_mfTransform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
m_mfTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
m_mfTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
return true;
}
void MFT::H264::DeInitialize()
{
if (m_mediaEventGen)
{
m_mfTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
m_mfTransform->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
while (WaitForSingleObject(m_shutdownEvent, INFINITE) != WAIT_OBJECT_0) {}
m_mfTransform->DeleteInputStream(0);
}
m_mediaEventGen = NULL;
m_mfTransform = NULL;
m_mfDeviceManager = NULL;
if (m_encodeEvent)
{
CloseHandle(m_encodeEvent );
CloseHandle(m_shutdownEvent);
m_encodeEvent = NULL;
m_shutdownEvent = NULL;
DeleteCriticalSection(&m_encodeCS);
}
if (m_mfActivation)
{
m_mfActivation->ShutdownObject();
m_mfActivation = NULL;
}
}
unsigned int MFT::H264::Process()
{
while(true)
{
// only reset the event if there isn't work pending
EnterCriticalSection(&m_encodeCS);
if (!m_encodeHasData && !m_encodeNeedsData)
ResetEvent(m_encodeEvent);
LeaveCriticalSection(&m_encodeCS);
switch (WaitForSingleObject(m_encodeEvent, 1000))
{
case WAIT_FAILED:
DEBUG_WINERROR("Wait for encode event failed", GetLastError());
return H264_EVENT_ERROR;
case WAIT_ABANDONED:
DEBUG_ERROR("Wait abandoned");
return H264_EVENT_ERROR;
case WAIT_TIMEOUT:
continue;
case WAIT_OBJECT_0:
break;
}
unsigned int events = 0;
EnterCriticalSection(&m_encodeCS);
if (m_encodeNeedsData) events |= H264_EVENT_NEEDS_DATA;
if (m_encodeHasData ) events |= H264_EVENT_HAS_DATA;
LeaveCriticalSection(&m_encodeCS);
return events;
}
return H264_EVENT_ERROR;
}
bool MFT::H264::ProvideFrame(ID3D11Texture2DPtr texture)
{
EnterCriticalSection(&m_encodeCS);
if (!m_encodeNeedsData)
{
LeaveCriticalSection(&m_encodeCS);
return false;
}
m_encodeNeedsData = false;
LeaveCriticalSection(&m_encodeCS);
HRESULT status;
IMFMediaBufferPtr buffer;
status = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), texture, 0, FALSE, &buffer);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to create DXGI surface buffer from texture", status);
return false;
}
IMF2DBufferPtr imfBuffer(buffer);
DWORD length;
imfBuffer->GetContiguousLength(&length);
buffer->SetCurrentLength(length);
IMFSamplePtr sample;
MFCreateSample(&sample);
sample->AddBuffer(buffer);
status = m_mfTransform->ProcessInput(0, sample, 0);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to process the input", status);
return false;
}
return true;
}
bool MFT::H264::GetFrame(void * buffer, const size_t bufferSize, unsigned int & dataLen)
{
EnterCriticalSection(&m_encodeCS);
if (!m_encodeHasData)
{
LeaveCriticalSection(&m_encodeCS);
return false;
}
m_encodeHasData = false;
LeaveCriticalSection(&m_encodeCS);
HRESULT status;
MFT_OUTPUT_STREAM_INFO streamInfo;
status = m_mfTransform->GetOutputStreamInfo(0, &streamInfo);
if (FAILED(status))
{
DEBUG_WINERROR("GetOutputStreamInfo", status);
return false;
}
DWORD outStatus;
MFT_OUTPUT_DATA_BUFFER outDataBuffer = { 0 };
status = m_mfTransform->ProcessOutput(0, 1, &outDataBuffer, &outStatus);
if (FAILED(status))
{
DEBUG_WINERROR("ProcessOutput", status);
return false;
}
IMFMediaBufferPtr mb;
outDataBuffer.pSample->ConvertToContiguousBuffer(&mb);
BYTE *pixels;
DWORD curLen;
mb->Lock(&pixels, NULL, &curLen);
memcpy(buffer, pixels, curLen);
mb->Unlock();
if (outDataBuffer.pSample)
outDataBuffer.pSample->Release();
if (outDataBuffer.pEvents)
outDataBuffer.pEvents->Release();
dataLen = curLen;
return true;
}
STDMETHODIMP MFT::H264::Invoke(IMFAsyncResult * pAsyncResult)
{
HRESULT status, evtStatus;
MediaEventType meType = MEUnknown;
IMFMediaEventPtr pEvent = NULL;
status = m_mediaEventGen->EndGetEvent(pAsyncResult, &pEvent);
if (FAILED(status))
{
DEBUG_WINERROR("EndGetEvent", status);
return status;
}
status = pEvent->GetStatus(&evtStatus);
if (FAILED(status))
{
DEBUG_WINERROR("GetStatus", status);
return status;
}
if (FAILED(evtStatus))
{
DEBUG_WINERROR("evtStatus", evtStatus);
return evtStatus;
}
status = pEvent->GetType(&meType);
if (FAILED(status))
{
DEBUG_WINERROR("GetType", status);
return status;
}
switch (meType)
{
case METransformNeedInput:
EnterCriticalSection(&m_encodeCS);
m_encodeNeedsData = true;
SetEvent(m_encodeEvent);
LeaveCriticalSection(&m_encodeCS);
break;
case METransformHaveOutput:
EnterCriticalSection(&m_encodeCS);
m_encodeHasData = true;
SetEvent(m_encodeEvent);
LeaveCriticalSection(&m_encodeCS);
break;
case METransformDrainComplete:
{
status = m_mfTransform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
if (FAILED(status))
{
DEBUG_WINERROR("MFT_MESSAGE_COMMAND_FLUSH", status);
return status;
}
SetEvent(m_shutdownEvent);
return S_OK;
}
case MEError:
DEBUG_INFO("err");
break;
default:
DEBUG_INFO("unk");
break;
}
status = m_mediaEventGen->BeginGetEvent(this, NULL);
if (FAILED(status))
{
DEBUG_WINERROR("BeginGetEvent", status);
return status;
}
return status;
}

View File

@ -1,101 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>
#include "Com.h"
namespace MFT
{
enum H264_Event
{
H264_EVENT_ENCODE = 0x01,
H264_EVENT_NEEDS_DATA = 0x04,
H264_EVENT_HAS_DATA = 0x08,
H264_EVENT_ERROR = 0x10
};
class H264: public IMFAsyncCallback
{
public:
H264();
~H264();
bool Initialize(ID3D11DevicePtr device, unsigned int width, unsigned int height);
void DeInitialize();
unsigned int Process();
bool ProvideFrame(ID3D11Texture2DPtr texture);
bool GetFrame(void * buffer, const size_t bufferSize, unsigned int & dataLen);
ID3D11DevicePtr m_device;
unsigned int m_width;
unsigned int m_height;
HANDLE m_encodeEvent;
HANDLE m_shutdownEvent;
bool m_encodeNeedsData;
bool m_encodeHasData;
CRITICAL_SECTION m_encodeCS;
UINT m_resetToken;
IMFDXGIDeviceManagerPtr m_mfDeviceManager;
IMFActivatePtr m_mfActivation;
IMFTransformPtr m_mfTransform;
IMFMediaEventGeneratorPtr m_mediaEventGen;
/*
Junk needed for the horrid IMFAsyncCallback interface
*/
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
if (riid == __uuidof(IUnknown) || riid == __uuidof(IMFAsyncCallback)) {
*ppv = static_cast<IMFAsyncCallback*>(this);
AddRef();
return S_OK;
}
else {
*ppv = NULL;
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
long cRef = InterlockedDecrement(&m_cRef);
if (!cRef)
delete this;
return cRef;
}
STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue) { return E_NOTIMPL; }
STDMETHODIMP Invoke(IMFAsyncResult *pAsyncResult);
private:
long m_cRef;
};
};

View File

@ -1,59 +0,0 @@
BINARY = looking-glass-host.exe
CFLAGS = -g -O3 -march=native -Wall -Werror -I./ -I../common # -DDEBUG
LDFLAGS = -lshlwapi -ldxgi -ld3d11 -lsetupapi -luuid -lole32 -lmfplat -lmfuuid
CFLAGS += -ffast-math
CFLAGS += -fdata-sections -ffunction-sections
CFLAGS += -I../ -I.
LDFLAGS += -Wl,--gc-sections -mwindows
CFLAGS += -DWINVER=0x0602 -DUNICODE
PREFIX ?= x86_64-w64-mingw32-
STRIP = $(PREFIX)strip
CC = $(PREFIX)cc
CXX = $(PREFIX)c++
LD = $(CXX)
BUILD ?= .build
BIN ?= bin
CFLAGS += -DBUILD_VERSION='"$(shell git describe --always --long --dirty --abbrev=10 --tags)"'
OBJS = main.o \
CrashHandler.o \
MultiMemcpy.o \
IVSHMEM.o \
Service.o \
Capture/DXGI.o
ifeq ($(ENABLE_TRACING),1)
CFLAGS += -DENABLE_TRACING
OBJS += TraceUtil.o
endif
ifeq ($(CONFIG_CAPTURE_NVFBC),1)
CFLAGS += -DCONFIG_CAPTURE_NVFBC=1 -I../vendor
OBJS += Capture/NvFBC.o
endif
BUILD_OBJS = $(foreach obj,$(OBJS),$(BUILD)/$(obj))
all: $(BIN)/$(BINARY)
$(BUILD)/%.o: %.c
@mkdir -p $(dir $@)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILD)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) -c $(CFLAGS) -o $@ $<
$(BIN)/$(BINARY): $(BUILD_OBJS)
@mkdir -p $(dir $@)
$(LD) -o $@ $^ $(LDFLAGS)
$(STRIP) -s $@
clean:
rm -rf $(BUILD) $(BIN)
.PHONY: clean

View File

@ -1,391 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Service.h"
#include "IVSHMEM.h"
#include "TraceUtil.h"
#include "common/debug.h"
#include "common/KVMFR.h"
#include "Util.h"
#include "CaptureFactory.h"
PCI_DEVICE Service::s_dev = {0x13, 0x01, 0x00};
Service::Service() :
m_initialized(false),
m_memory(NULL),
m_timer(NULL),
m_capture(NULL),
m_shmHeader(NULL),
m_frameIndex(0),
m_cursorDataSize(0),
m_cursorData(NULL)
{
m_consoleSessionID = WTSGetActiveConsoleSessionId();
m_ivshmem = IVSHMEM::Get();
if (!m_ivshmem->Initialize(s_dev))
throw "IVSHMEM failed to initalize";
if (m_ivshmem->GetSize() < sizeof(KVMFRHeader))
throw "Shared memory is not large enough for the KVMFRHeader";
m_memory = static_cast<uint8_t*>(m_ivshmem->GetMemory());
if (!m_memory)
throw "Failed to get IVSHMEM memory";
if (!InitPointers())
throw "Failed to initialize the shared memory pointers";
}
Service::~Service()
{
DeInitialize();
}
LRESULT Service::LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION && wParam == WM_MOUSEMOVE)
{
MSLLHOOKSTRUCT *msg = (MSLLHOOKSTRUCT *)lParam;
volatile KVMFRCursor * cursor = &(m_shmHeader->cursor);
volatile char * flags = (volatile char *)&(cursor->flags);
cursor->x = (int16_t)msg->pt.x;
cursor->y = (int16_t)msg->pt.y;
INTERLOCKED_OR8(flags, KVMFR_CURSOR_FLAG_POS);
}
return CallNextHookEx(m_mouseHook, nCode, wParam, lParam);
}
bool Service::Initialize(ICapture * captureDevice)
{
if (m_initialized)
DeInitialize();
m_tryTarget = 0;
m_capture = captureDevice;
if (m_capture->GetMaxFrameSize() > m_frameSize)
{
DEBUG_ERROR("Maximum frame size of %zu bytes excceds maximum space available", m_capture->GetMaxFrameSize());
DeInitialize();
return false;
}
// Create the cursor thread
m_cursorThread = CreateThread(NULL, 0, _CursorThread, NULL, 0, NULL);
m_cursorEvent = CreateEvent (NULL, FALSE, FALSE, L"CursorEvent");
InitializeCriticalSection(&m_cursorCS);
// update everything except for the hostID
memcpy(m_shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
m_shmHeader->version = KVMFR_HEADER_VERSION;
// zero and tell the client we have restarted
ZeroMemory(&(m_shmHeader->frame ), sizeof(KVMFRFrame ));
ZeroMemory(&(m_shmHeader->cursor), sizeof(KVMFRCursor));
m_shmHeader->flags &= ~KVMFR_HEADER_FLAG_RESTART;
m_haveFrame = false;
m_initialized = true;
m_running = true;
return true;
}
#define ALIGN_DN(x) ((uintptr_t)(x) & ~0x7F)
#define ALIGN_UP(x) ALIGN_DN(x + 0x7F)
bool Service::InitPointers()
{
m_shmHeader = reinterpret_cast<KVMFRHeader *>(m_memory);
m_cursorData = (uint8_t *)ALIGN_UP(m_memory + sizeof(KVMFRHeader));
m_cursorDataSize = 1048576; // 1MB fixed for cursor size, should be more then enough
m_cursorOffset = m_cursorData - m_memory;
uint8_t * m_frames = (uint8_t *)ALIGN_UP(m_cursorData + m_cursorDataSize);
m_frameSize = ALIGN_DN((m_ivshmem->GetSize() - (m_frames - m_memory)) / MAX_FRAMES);
DEBUG_INFO("Total Available : %3u MB", (unsigned int)(m_ivshmem->GetSize() / 1024 / 1024));
DEBUG_INFO("Max Cursor Size : %3u MB", (unsigned int)(m_cursorDataSize / 1024 / 1024));
DEBUG_INFO("Max Frame Size : %3u MB", (unsigned int)(m_frameSize / 1024 / 1024));
DEBUG_INFO("Cursor : %p (0x%08x)", m_cursorData, (int)m_cursorOffset);
for (int i = 0; i < MAX_FRAMES; ++i)
{
m_frame[i] = m_frames + i * m_frameSize;
m_dataOffset[i] = m_frame[i] - m_memory;
DEBUG_INFO("Frame %d : %p (0x%08x)", i, m_frame[i], (int)m_dataOffset[i]);
}
return true;
}
void Service::DeInitialize()
{
m_running = false;
WaitForSingleObject(m_cursorThread, INFINITE);
CloseHandle(m_cursorThread);
CloseHandle(m_cursorEvent);
m_shmHeader = NULL;
m_cursorData = NULL;
m_cursorDataSize = 0;
m_cursorOffset = 0;
m_haveFrame = false;
for(int i = 0; i < MAX_FRAMES; ++i)
{
m_frame [i] = NULL;
m_dataOffset[i] = 0;
}
m_frameSize = 0;
m_ivshmem->DeInitialize();
if (m_capture)
{
m_capture->DeInitialize();
m_capture = NULL;
}
m_memory = NULL;
m_initialized = false;
}
bool Service::ReInit(volatile char * flags)
{
DEBUG_INFO("ReInitialize Requested");
INTERLOCKED_OR8(flags, KVMFR_HEADER_FLAG_PAUSED);
if (WTSGetActiveConsoleSessionId() != m_consoleSessionID)
{
DEBUG_INFO("User switch detected, waiting to regain control");
while (WTSGetActiveConsoleSessionId() != m_consoleSessionID)
Sleep(100);
}
while (!m_capture->CanInitialize())
Sleep(100);
if (!m_capture->ReInitialize())
{
DEBUG_ERROR("ReInitialize Failed");
return false;
}
if (m_capture->GetMaxFrameSize() > m_frameSize)
{
DEBUG_ERROR("Maximum frame size of %zd bytes excceds maximum space available", m_capture->GetMaxFrameSize());
return false;
}
INTERLOCKED_AND8(flags, ~KVMFR_HEADER_FLAG_PAUSED);
return true;
}
ProcessStatus Service::Process()
{
if (!m_initialized)
return PROCESS_STATUS_ERROR;
volatile char * flags = (volatile char *)&(m_shmHeader->flags);
// check if the client has flagged a restart
if (*flags & KVMFR_HEADER_FLAG_RESTART)
{
DEBUG_INFO("Restart Requested");
if (!m_capture->ReInitialize())
{
DEBUG_ERROR("ReInitialize Failed");
return PROCESS_STATUS_ERROR;
}
if (m_capture->GetMaxFrameSize() > m_frameSize)
{
DEBUG_ERROR("Maximum frame size of %zd bytes exceeds maximum space available", m_capture->GetMaxFrameSize());
return PROCESS_STATUS_ERROR;
}
INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART));
}
unsigned int status;
bool notify = false;
status = m_capture->Capture();
if (status & GRAB_STATUS_ERROR)
{
DEBUG_WARN("Capture error, retrying");
return PROCESS_STATUS_RETRY;
}
if (status & GRAB_STATUS_TIMEOUT)
{
// timeouts should not count towards a failure to capture
if (!m_haveFrame)
return PROCESS_STATUS_OK;
notify = true;
}
if (status & GRAB_STATUS_REINIT)
{
if (!ReInit(flags))
return PROCESS_STATUS_ERROR;
// re-init request should not count towards a failure to capture
return PROCESS_STATUS_OK;
}
if ((status & (GRAB_STATUS_OK | GRAB_STATUS_TIMEOUT)) == 0)
{
DEBUG_ERROR("Capture interface returned an unexpected result");
return PROCESS_STATUS_ERROR;
}
if (status & GRAB_STATUS_CURSOR)
SetEvent(m_cursorEvent);
volatile KVMFRFrame * fi = &(m_shmHeader->frame);
if (status & GRAB_STATUS_FRAME)
{
FrameInfo frame = { 0 };
frame.buffer = m_frame[m_frameIndex];
frame.bufferSize = m_frameSize;
GrabStatus result = m_capture->GetFrame(frame);
if (result != GRAB_STATUS_OK)
{
if (result == GRAB_STATUS_REINIT)
{
if (!ReInit(flags))
return PROCESS_STATUS_ERROR;
// re-init request should not count towards a failure to capture
return PROCESS_STATUS_OK;
}
DEBUG_INFO("GetFrame failed");
return PROCESS_STATUS_ERROR;
}
/* don't touch the frame information until the client is done with it */
while (fi->flags & KVMFR_FRAME_FLAG_UPDATE)
{
/* this generally never occurs */
Sleep(1);
if (*flags & KVMFR_HEADER_FLAG_RESTART)
break;
}
fi->type = m_capture->GetFrameType();
fi->width = frame.width;
fi->height = frame.height;
fi->stride = frame.stride;
fi->pitch = frame.pitch;
fi->dataPos = m_dataOffset[m_frameIndex];
if (++m_frameIndex == MAX_FRAMES)
m_frameIndex = 0;
// remember that we have a valid frame
m_haveFrame = true;
notify = true;
}
if (notify)
{
/* don't touch the frame inforamtion until the client is done with it */
while (fi->flags & KVMFR_FRAME_FLAG_UPDATE)
{
if (*flags & KVMFR_HEADER_FLAG_RESTART)
break;
}
// signal a frame update
fi->flags |= KVMFR_FRAME_FLAG_UPDATE;
}
// update the flags
INTERLOCKED_AND8(flags, KVMFR_HEADER_FLAG_RESTART);
return PROCESS_STATUS_OK;
}
DWORD Service::CursorThread()
{
while(m_running)
{
if (WaitForSingleObject(m_cursorEvent, 1000) != WAIT_OBJECT_0)
continue;
CursorInfo ci;
while (m_capture->GetCursor(ci))
{
volatile KVMFRCursor * cursor = &(m_shmHeader->cursor);
// wait until the client is ready
while ((cursor->flags & ~KVMFR_CURSOR_FLAG_POS) != 0)
{
Sleep(1);
if (!m_capture)
return 0;
}
uint8_t flags = cursor->flags;
if (ci.hasPos)
{
cursor->x = ci.x;
cursor->y = ci.y;
flags |= KVMFR_CURSOR_FLAG_POS;
}
if (ci.hasShape)
{
if (ci.shape.pointerSize > m_cursorDataSize)
DEBUG_ERROR("Cursor size exceeds allocated space");
else
{
// give the client the new cursor shape
flags |= KVMFR_CURSOR_FLAG_SHAPE;
++cursor->version;
cursor->type = ci.type;
cursor->width = ci.w;
cursor->height = ci.h;
cursor->pitch = ci.pitch;
cursor->dataPos = m_cursorOffset;
memcpy(m_cursorData, ci.shape.buffer, ci.shape.bufferSize);
}
}
if (ci.visible)
flags |= KVMFR_CURSOR_FLAG_VISIBLE;
flags |= KVMFR_CURSOR_FLAG_UPDATE;
cursor->flags = flags;
m_capture->FreeCursor();
}
}
return 0;
}

View File

@ -1,114 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#define W32_LEAN_AND_MEAN
#include <windows.h>
#include <stdbool.h>
#include "IVSHMEM.h"
#include "ICapture.h"
#include "common/debug.h"
#define MAX_FRAMES 2
enum ProcessStatus
{
PROCESS_STATUS_OK,
PROCESS_STATUS_RETRY,
PROCESS_STATUS_ERROR
};
class Service
{
public:
static Service & Instance()
{
static Service service;
return service;
}
static void InstallHook()
{
if (Instance().m_mouseHook)
RemoveHook();
Instance().m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, _LowLevelMouseProc, NULL, 0);
}
static void RemoveHook()
{
if (Instance().m_mouseHook)
{
UnhookWindowsHookEx(Instance().m_mouseHook);
Instance().m_mouseHook = NULL;
}
}
static void SetDevice(PCI_DEVICE dev)
{
s_dev = dev;
}
bool Initialize(ICapture * captureDevice);
void DeInitialize();
ProcessStatus Process();
private:
bool InitPointers();
int m_tryTarget;
int m_lastTryCount;
Service();
~Service();
HHOOK m_mouseHook;
LRESULT LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
static LRESULT WINAPI _LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { return Service::Instance().LowLevelMouseProc(nCode, wParam, lParam); }
bool ReInit(volatile char * flags);
bool m_initialized;
bool m_running;
DWORD m_consoleSessionID;
uint8_t * m_memory;
IVSHMEM * m_ivshmem;
HANDLE m_timer;
ICapture * m_capture;
KVMFRHeader * m_shmHeader;
bool m_haveFrame;
uint8_t * m_frame[MAX_FRAMES];
size_t m_frameSize;
uint64_t m_dataOffset[MAX_FRAMES];
int m_frameIndex;
static PCI_DEVICE s_dev;
static DWORD WINAPI _CursorThread(LPVOID lpParameter) { return Service::Instance().CursorThread(); }
DWORD CursorThread();
HANDLE m_cursorThread;
HANDLE m_cursorEvent;
CRITICAL_SECTION m_cursorCS;
size_t m_cursorDataSize;
uint8_t * m_cursorData;
uint64_t m_cursorOffset;
};

View File

@ -1,13 +0,0 @@
Texture2D texTexture;
SamplerState texSampler;
struct VS
{
float4 pos : SV_Position;
float2 tex : TEXCOORD;
};
float4 main(VS input): SV_Target
{
return texTexture.Sample(texSampler, input.tex);
}

View File

@ -1,31 +0,0 @@
Texture2D texTexture;
SamplerState texSampler;
struct VS
{
float4 pos : SV_Position;
float2 tex : TEXCOORD;
};
struct OUT
{
float4 y: SV_TARGET0;
float4 u: SV_TARGET1;
float4 v: SV_TARGET2;
};
OUT main(VS input)
{
OUT o;
const float4 rgba = texTexture.Sample(texSampler, input.tex);
o.y.gba = 1.0f;
o.u.gba = 1.0f;
o.v.gba = 1.0f;
o.y.r = rgba.r * 0.2126 + 0.7152 * rgba.g + 0.0722 * rgba.b;
o.u.r = ((rgba.b - o.y.r) / 1.8556) + 0.5;
o.v.r = ((rgba.r - o.y.r) / 1.5748) + 0.5;
return o;
}

View File

@ -1,16 +0,0 @@
struct VS
{
float4 pos : POSITION;
float2 tex : TEXCOORD;
};
struct PS
{
float4 pos : SV_Position;
float2 tex : TEXCOORD;
};
PS main(VS input)
{
return input;
}

View File

@ -1,418 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "TextureConverter.h"
#include "common\debug.h"
#include "Shaders\Vertex.h"
#include "Shaders\Pixel.h"
#include "Shaders\RGBtoYUV.h"
TextureConverter::TextureConverter()
{
}
TextureConverter::~TextureConverter()
{
DeInitialize();
}
bool TextureConverter::Initialize(
ID3D11DeviceContextPtr deviceContext,
ID3D11DevicePtr device,
const unsigned int width,
const unsigned int height,
FrameType format
)
{
HRESULT result;
D3D11_TEXTURE2D_DESC texDesc;
D3D11_RENDER_TARGET_VIEW_DESC targetDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc;
D3D11_SAMPLER_DESC samplerDesc;
m_deviceContext = deviceContext;
m_device = device;
m_width = width;
m_height = height;
m_format = format;
result = device->CreatePixelShader(g_Pixel, sizeof(g_Pixel), NULL, &m_psCopy);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the copy pixel shader");
return false;
}
switch (format)
{
case FRAME_TYPE_YUV420:
result = device->CreatePixelShader(g_RGBtoYUV, sizeof(g_RGBtoYUV), NULL, &m_psConversion);
m_texFormats[0] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[0] = 1;
m_texFormats[1] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[1] = 2;
m_texFormats[2] = DXGI_FORMAT_R8_UNORM; m_scaleFormats[2] = 2;
break;
default:
DEBUG_ERROR("Unsupported format");
return false;
}
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the pixel shader");
return false;
}
const D3D11_INPUT_ELEMENT_DESC inputDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT , 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
result = device->CreateInputLayout(inputDesc, _countof(inputDesc), g_Vertex, sizeof(g_Vertex), &m_layout);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the input layout");
return false;
}
result = device->CreateVertexShader(g_Vertex, sizeof(g_Vertex), NULL, &m_vertexShader);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the vertex shader");
return false;
}
ZeroMemory(&texDesc , sizeof(texDesc ));
ZeroMemory(&targetDesc , sizeof(targetDesc ));
ZeroMemory(&shaderDesc , sizeof(shaderDesc ));
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
texDesc.Width = width;
texDesc.Height = height;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = 0;
texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
targetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderDesc.Texture2D.MipLevels = 1;
for(int i = 0; i < _countof(m_targetTexture); ++i)
{
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
continue;
texDesc .Format = m_texFormats[i];
targetDesc.Format = m_texFormats[i];
shaderDesc.Format = m_texFormats[i];
result = device->CreateTexture2D(&texDesc, NULL, &m_targetTexture[i]);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the render texture");
return false;
}
result = device->CreateRenderTargetView(m_targetTexture[i], &targetDesc, &m_renderView[i]);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the render view");
return false;
}
result = device->CreateShaderResourceView(m_targetTexture[i], &shaderDesc, &m_shaderView[i]);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create the resource view");
return false;
}
}
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerDesc.BorderColor[0] = 1.0f;
samplerDesc.BorderColor[1] = 1.0f;
samplerDesc.BorderColor[2] = 1.0f;
samplerDesc.MinLOD = -FLT_MAX;
samplerDesc.MaxLOD = FLT_MAX;
result = device->CreateSamplerState(&samplerDesc, &m_samplerState);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create sampler state");
return false;
}
return IntializeBuffers();
}
bool TextureConverter::IntializeBuffers()
{
struct VS_INPUT * verticies;
unsigned long * indicies;
HRESULT result;
D3D11_BUFFER_DESC vertexDesc, indexDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
m_vertexCount = 4;
m_indexCount = 4;
verticies = new struct VS_INPUT[m_vertexCount];
if (!verticies)
{
DeInitialize();
DEBUG_ERROR("new failure");
return false;
}
indicies = new unsigned long[m_indexCount];
if (!indicies)
{
DeInitialize();
DEBUG_ERROR("new failure");
return false;
}
verticies[0].pos = DirectX::XMFLOAT3(-1.0f, -1.0f, 0.5f); //BL
verticies[1].pos = DirectX::XMFLOAT3(-1.0f, 1.0f, 0.5f); //TL
verticies[2].pos = DirectX::XMFLOAT3( 1.0f, -1.0f, 0.5f); //BR
verticies[3].pos = DirectX::XMFLOAT3( 1.0f, 1.0f, 0.5f); //TR
verticies[0].tex = DirectX::XMFLOAT2(0.0f, 1.0f);
verticies[1].tex = DirectX::XMFLOAT2(0.0f, 0.0f);
verticies[2].tex = DirectX::XMFLOAT2(1.0f, 1.0f);
verticies[3].tex = DirectX::XMFLOAT2(1.0f, 0.0f);
indicies[0] = 0;
indicies[1] = 1;
indicies[2] = 2;
indicies[3] = 3;
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.ByteWidth = sizeof(struct VS_INPUT) * m_vertexCount;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.CPUAccessFlags = 0;
vertexDesc.MiscFlags = 0;
vertexDesc.StructureByteStride = 0;
vertexData.pSysMem = verticies;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
result = m_device->CreateBuffer(&vertexDesc, &vertexData, &m_vertexBuffer);
if (FAILED(result))
{
delete[] indicies;
delete[] verticies;
DeInitialize();
DEBUG_ERROR("Failed to create vertex buffer");
return false;
}
indexDesc.Usage = D3D11_USAGE_DEFAULT;
indexDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexDesc.CPUAccessFlags = 0;
indexDesc.MiscFlags = 0;
indexDesc.StructureByteStride = 0;
indexData.pSysMem = indicies;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
result = m_device->CreateBuffer(&indexDesc, &indexData, &m_indexBuffer);
if (FAILED(result))
{
delete[] indicies;
delete[] verticies;
DeInitialize();
DEBUG_ERROR("Failed to create index buffer");
return false;
}
delete[] indicies;
delete[] verticies;
return true;
}
void TextureConverter::DeInitialize()
{
m_samplerState = NULL;
m_indexBuffer = NULL;
m_indexBuffer = NULL;
for(int i = 0; i < _countof(m_targetTexture); ++i)
{
m_shaderView [i] = NULL;
m_renderView [i] = NULL;
m_targetTexture[i] = NULL;
}
m_vertexShader = NULL;
m_psConversion = NULL;
m_layout = NULL;
m_psCopy = NULL;
}
bool TextureConverter::Convert(ID3D11Texture2DPtr texture, TextureList & output)
{
unsigned int stride;
unsigned int offset;
float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
HRESULT result;
D3D11_TEXTURE2D_DESC texDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
ID3D11ShaderResourceViewPtr textureView;
texture->GetDesc(&texDesc);
viewDesc.Format = texDesc.Format;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MostDetailedMip = 0;
viewDesc.Texture2D.MipLevels = 1;
result = m_device->CreateShaderResourceView(texture, &viewDesc, &textureView);
if (FAILED(result))
{
DeInitialize();
DEBUG_ERROR("Failed to create shader resource view");
return false;
}
ID3D11Buffer *buffers [] = { m_vertexBuffer.GetInterfacePtr() };
ID3D11SamplerState *samplerStates[] = { m_samplerState.GetInterfacePtr() };
ID3D11ShaderResourceView *shaderViews [] = { textureView .GetInterfacePtr() };
D3D11_VIEWPORT viewPorts [] = { {
0.0f , 0.0f,
(float)m_width, (float)m_height,
0.0f , 1.0f
} };
int targetCount = 0;
ID3D11RenderTargetView **renderViews = new ID3D11RenderTargetView*[_countof(m_renderView)];
for(int i = 0; i < _countof(m_renderView); ++i)
{
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
continue;
m_deviceContext->ClearRenderTargetView(m_renderView[i], color);
renderViews[i] = m_renderView[i].GetInterfacePtr();
++targetCount;
}
m_deviceContext->PSSetShaderResources(0, _countof(shaderViews), shaderViews);
m_deviceContext->OMSetRenderTargets(targetCount, renderViews, NULL);
delete [] renderViews;
stride = sizeof(VS_INPUT);
offset = 0;
m_deviceContext->RSSetViewports (_countof(viewPorts), viewPorts);
m_deviceContext->IASetInputLayout (m_layout);
m_deviceContext->IASetVertexBuffers (0, _countof(buffers), buffers, &stride, &offset);
m_deviceContext->IASetIndexBuffer (m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_deviceContext->VSSetShader (m_vertexShader, NULL, 0);
m_deviceContext->PSSetSamplers (0, _countof(samplerStates), samplerStates);
m_deviceContext->PSSetShader (m_psConversion, NULL, 0);
m_deviceContext->DrawIndexed(m_indexCount, 0, 0);
textureView = NULL;
D3D11_RENDER_TARGET_VIEW_DESC targetDesc;
ZeroMemory(&targetDesc, sizeof(targetDesc));
targetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
m_deviceContext->PSSetShader(m_psCopy, NULL, 0);
renderViews = new ID3D11RenderTargetView*[1];
for (int i = 0; i < _countof(m_renderView); ++i)
{
if (m_texFormats[i] == DXGI_FORMAT_UNKNOWN)
continue;
ID3D11Texture2DPtr src = m_targetTexture[i];
ID3D11Texture2DPtr dest;
ID3D11RenderTargetViewPtr view;
D3D11_TEXTURE2D_DESC srcDesc;
// if there is no scaling
if (m_scaleFormats[i] == 1)
{
output.push_back(src);
continue;
}
src->GetDesc(&srcDesc);
viewPorts[0].Width = srcDesc.Width / m_scaleFormats[i];
viewPorts[0].Height = srcDesc.Height / m_scaleFormats[i];
srcDesc.Width = (UINT)viewPorts[0].Width;
srcDesc.Height = (UINT)viewPorts[0].Height;
result = m_device->CreateTexture2D(&srcDesc, NULL, &dest);
if (FAILED(result))
{
delete[] renderViews;
DeInitialize();
DEBUG_ERROR("Failed to create the target texture");
return false;
}
targetDesc.Format = srcDesc.Format;
result = m_device->CreateRenderTargetView(dest, &targetDesc, &view);
if (FAILED(result))
{
delete[] renderViews;
DeInitialize();
DEBUG_ERROR("Failed to create the target view");
return false;
}
renderViews[0] = view.GetInterfacePtr();
shaderViews[0] = m_shaderView[i].GetInterfacePtr();
m_deviceContext->OMSetRenderTargets(1, renderViews, NULL);
m_deviceContext->RSSetViewports(_countof(viewPorts), viewPorts);
m_deviceContext->PSSetShaderResources(0, 1, shaderViews);
m_deviceContext->DrawIndexed(m_indexCount, 0, 0);
output.push_back(dest);
view = NULL;
}
delete[] renderViews;
return true;
}

View File

@ -1,80 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include "Com.h"
#include "common\KVMFR.h"
#include <DirectXMath.h>
#include <vector>
typedef std::vector<ID3D11Texture2DPtr> TextureList;
class TextureConverter
{
public:
TextureConverter();
~TextureConverter();
bool Initialize(
ID3D11DeviceContextPtr deviceContext,
ID3D11DevicePtr device,
const unsigned int width,
const unsigned int height,
FrameType format
);
void DeInitialize();
bool Convert(ID3D11Texture2DPtr texture, TextureList & output);
private:
struct VS_INPUT
{
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT2 tex;
};
bool IntializeBuffers();
ID3D11DeviceContextPtr m_deviceContext;
ID3D11DevicePtr m_device;
unsigned int m_width, m_height;
FrameType m_format;
DXGI_FORMAT m_texFormats [3];
unsigned int m_scaleFormats [3];
ID3D11Texture2DPtr m_targetTexture[3];
ID3D11RenderTargetViewPtr m_renderView [3];
ID3D11ShaderResourceViewPtr m_shaderView [3];
ID3D11InputLayoutPtr m_layout;
ID3D11VertexShaderPtr m_vertexShader;
ID3D11PixelShaderPtr m_psCopy;
ID3D11PixelShaderPtr m_psConversion;
ID3D11SamplerStatePtr m_samplerState;
ID3D11BufferPtr m_vertexBuffer;
unsigned int m_vertexCount;
ID3D11BufferPtr m_indexBuffer;
unsigned int m_indexCount;
};

View File

@ -1,25 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "TraceUtil.h"
double TraceUtil::m_freq;
LARGE_INTEGER TraceUtil::m_last;
LARGE_INTEGER TraceUtil::m_start;
const char * TraceUtil::m_traceName;

View File

@ -1,79 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <windows.h>
#include <stdint.h>
#include "common/debug.h"
#ifdef ENABLE_TRACING
#define TRACE TraceUtil::Trace(__FUNCTION__, __LINE__)
#define TRACE_START(x) TraceUtil::TraceStart(x)
#define TRACE_END TraceUtil::TraceEnd()
#else
#define TRACE
#define TRACE_START(x)
#define TRACE_END
#endif
class TraceUtil
{
private:
static double m_freq;
static LARGE_INTEGER m_last;
static LARGE_INTEGER m_start;
static const char * m_traceName;
public:
static void Initialize()
{
#ifdef ENABLE_TRACING
LARGE_INTEGER now;
QueryPerformanceFrequency(&now);
m_freq = (double)now.QuadPart / 1000.0;
QueryPerformanceCounter(&m_last);
#endif
}
static inline void Trace(const char * function, const unsigned int line)
{
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
const double diff = (now.QuadPart - m_last.QuadPart) / m_freq;
m_last = now;
DEBUG_INFO("Trace [%8.4f] %s:%u", diff, function, line);
}
static inline void TraceStart(const char * traceName)
{
QueryPerformanceCounter(&m_start);
m_traceName = traceName;
}
static inline void TraceEnd()
{
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
const double diff = (now.QuadPart - m_start.QuadPart) / m_freq;
DEBUG_INFO("Trace [%8.4f] %s", diff, m_traceName);
}
};

View File

@ -1,154 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <string>
#include <assert.h>
#include <inttypes.h>
#include <tmmintrin.h>
#include "common/debug.h"
#if !defined(min)
#define LG_MIN(a, b) ((a) < (b) ? (a) : (b))
#else
#define LG_MIN min
#endif
#if __MINGW32__
#define INTERLOCKED_AND8 __sync_and_and_fetch
#define INTERLOCKED_OR8 __sync_or_and_fetch
#else
#define INTERLOCKED_OR8 InterlockedOr8
#define INTERLOCKED_AND8 InterlockedAnd8
#endif
class Util
{
public:
static void DebugWinError(const char * file, const unsigned int line, const char * function, const char * desc, HRESULT status)
{
char *buffer;
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
status,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(char*)&buffer,
1024,
NULL
);
for(size_t i = strlen(buffer) - 1; i > 0; --i)
if (buffer[i] == '\n' || buffer[i] == '\r')
buffer[i] = 0;
fprintf(stderr, "[E] %20s:%-4u | %-30s | %s: 0x%08x (%s)\n", file, line, function, desc, (int)status, buffer);
LocalFree(buffer);
}
static std::string GetSystemRoot()
{
std::string defaultPath;
#if __MINGW32__
const char * libPath = getenv("SystemRoot");
const size_t libPathLen = strlen(libPath);
#else
char * libPath;
size_t libPathLen;
_dupenv_s(&libPath, &libPathLen, "SystemRoot");
#endif
if (!libPath)
{
DEBUG_ERROR("Unable to get the SystemRoot environment variable");
return defaultPath;
}
if (!libPathLen)
{
DEBUG_ERROR("The SystemRoot environment variable is not set");
#ifndef __MINGW32__
free(libPath);
#endif
return defaultPath;
}
#ifdef _WIN64
defaultPath = std::string(libPath) + "\\System32";
#else
if (IsWow64())
{
defaultPath = std::string(libPath) + "\\Syswow64";
}
else
{
defaultPath = std::string(libPath) + "\\System32";
}
#endif
#ifndef __MINGW32__
free(libPath);
#endif
return defaultPath;
}
static inline void BGRAtoRGB(uint8_t * orig, size_t imagesize, uint8_t * dest)
{
assert((uintptr_t)orig % 16 == 0);
assert((uintptr_t)dest % 16 == 0);
assert(imagesize % 16 == 0);
__m128i mask_right = _mm_set_epi8
(
12, 13, 14, 8,
9, 10, 4, 5,
6, 0, 1, 2,
-128, -128, -128, -128
);
__m128i mask_left = _mm_set_epi8
(
-128, -128, -128, -128,
12, 13, 14, 8,
9, 10, 4, 5,
6, 0, 1, 2
);
uint8_t *end = orig + imagesize * 4;
for (; orig != end; orig += 64, dest += 48)
{
_mm_prefetch((char *)(orig + 128), _MM_HINT_NTA);
_mm_prefetch((char *)(orig + 192), _MM_HINT_NTA);
__m128i v0 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)&orig[0 ]), mask_right);
__m128i v1 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)&orig[16]), mask_left );
__m128i v2 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)&orig[32]), mask_left );
__m128i v3 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)&orig[48]), mask_left );
v0 = _mm_alignr_epi8(v1, v0, 4);
v1 = _mm_alignr_epi8(v2, _mm_slli_si128(v1, 4), 8);
v2 = _mm_alignr_epi8(v3, _mm_slli_si128(v2, 4), 12);
_mm_stream_si128((__m128i *)&dest[0 ], v0);
_mm_stream_si128((__m128i *)&dest[16], v1);
_mm_stream_si128((__m128i *)&dest[32], v2);
}
}
};

View File

@ -1,24 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include "Util.h"
#define DEBUG_WINERROR(x, y) Util::DebugWinError(STRIPPATH(__FILE__), __LINE__, __FUNCTION__, x, y)

View File

@ -1,418 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - NvFBC|Win32">
<Configuration>Debug - NvFBC</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug - NvFBC|x64">
<Configuration>Debug - NvFBC</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - NvFBC|Win32">
<Configuration>Release - NvFBC</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - NvFBC|x64">
<Configuration>Release - NvFBC</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D439DE3E-32FB-4599-8B5D-C92674D400D4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>kvmivshmemhost</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>looking-glass-host</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
<ExecutablePath>C:\Program Files (x86)\Windows Kits\10\bin\$(TargetPlatformVersion)\$(PreferredToolArchitecture);$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ENABLE_TRACING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ENABLE_TRACING;CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ENABLE_TRACING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ENABLE_TRACING;CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\vendor;..\common\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;avrt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\vendor\getopt\getopt.c" />
<ClCompile Include="Capture\DXGI.cpp" />
<ClCompile Include="Capture\NvFBC.cpp" />
<ClCompile Include="CrashHandler.cpp" />
<ClCompile Include="ivshmem.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MFT\H264.cpp" />
<ClCompile Include="TextureConverter.cpp" />
<ClCompile Include="Service.cpp" />
<ClCompile Include="TraceUtil.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CaptureFactory.h" />
<ClInclude Include="Capture\DXGI.h" />
<ClInclude Include="Capture\NvFBC.h" />
<ClInclude Include="Com.h" />
<ClInclude Include="CrashHandler.h" />
<ClInclude Include="ICapture.h" />
<ClInclude Include="ivshmem.h" />
<ClInclude Include="MFT\H264.h" />
<ClInclude Include="TextureConverter.h" />
<ClInclude Include="Service.h" />
<ClInclude Include="TraceUtil.h" />
<ClInclude Include="Util.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="..\common\src\memcpySSE.asm" />
</ItemGroup>
<ItemGroup>
<FxCompile Include="Shaders\Pixel.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_Pixel</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\Pixel.h</HeaderFileOutput>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">4.0_level_9_1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">g_Pixel</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Shaders\Pixel.h</HeaderFileOutput>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">g_Pixel</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Shaders\Pixel.h</HeaderFileOutput>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">g_Pixel</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shaders\Pixel.h</HeaderFileOutput>
</FxCompile>
<FxCompile Include="Shaders\RGBtoYUV.hlsl">
<FileType>HLSL</FileType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_RGBtoYUV</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\RGBtoYUV.h</HeaderFileOutput>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">4.0_level_9_1</ShaderModel>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">g_RGBtoYUV</VariableName>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">g_RGBtoYUV</VariableName>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">g_RGBtoYUV</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Shaders\RGBtoYUV.h</HeaderFileOutput>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Shaders\RGBtoYUV.h</HeaderFileOutput>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shaders\RGBtoYUV.h</HeaderFileOutput>
</FxCompile>
<FxCompile Include="Shaders\Vertex.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">g_Vertex</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shaders\Vertex.h</HeaderFileOutput>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">g_Vertex</VariableName>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">g_Vertex</VariableName>
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">g_Vertex</VariableName>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Shaders\Vertex.h</HeaderFileOutput>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Shaders\Vertex.h</HeaderFileOutput>
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shaders\Vertex.h</HeaderFileOutput>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">Vertex</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">4.0_level_9_1</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
</FxCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Capture">
<UniqueIdentifier>{3a65593b-37a9-448d-acf0-6339dea46ed1}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Capture">
<UniqueIdentifier>{0a865d22-907e-44ea-a230-ad7ede7edeb0}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\MFT">
<UniqueIdentifier>{bd9c6e76-f398-49eb-acfb-3f50cd99724c}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\MFT">
<UniqueIdentifier>{fead4000-1954-4480-8ee7-b817d7042761}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Shaders">
<UniqueIdentifier>{afb06b60-4959-4447-92ec-75cc07995a8f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ivshmem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Service.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Capture\NvFBC.cpp">
<Filter>Source Files\Capture</Filter>
</ClCompile>
<ClCompile Include="Capture\DXGI.cpp">
<Filter>Source Files\Capture</Filter>
</ClCompile>
<ClCompile Include="..\vendor\getopt\getopt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CrashHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TraceUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MFT\H264.cpp">
<Filter>Source Files\MFT</Filter>
</ClCompile>
<ClCompile Include="TextureConverter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ivshmem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ICapture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Service.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CaptureFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Capture\NvFBC.h">
<Filter>Header Files\Capture</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Capture\DXGI.h">
<Filter>Header Files\Capture</Filter>
</ClInclude>
<ClInclude Include="CrashHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TraceUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MFT\H264.h">
<Filter>Header Files\MFT</Filter>
</ClInclude>
<ClInclude Include="Com.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TextureConverter.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<FxCompile Include="Shaders\Vertex.hlsl">
<Filter>Source Files\Shaders</Filter>
</FxCompile>
<FxCompile Include="Shaders\RGBtoYUV.hlsl">
<Filter>Source Files\Shaders</Filter>
</FxCompile>
<FxCompile Include="Shaders\Pixel.hlsl">
<Filter>Source Files\Shaders</Filter>
</FxCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="..\common\src\memcpySSE.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>

View File

@ -1,373 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include <shlwapi.h>
#include <avrt.h>
#include "common/debug.h"
#include "getopt/getopt.h"
#include "CrashHandler.h"
#include "TraceUtil.h"
#include "CaptureFactory.h"
#include "Service.h"
#include <io.h>
#include <fcntl.h>
#include <iostream>
int parseArgs(struct StartupArgs & args);
static DWORD WINAPI CaptureThread(LPVOID lpParameter);
int run();
void doHelp();
void doLicense();
bool running = true;
bool consoleActive = false;
void setupConsole();
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
struct StartupArgs
{
bool foreground;
const char * captureDevice;
CaptureOptions captureOptions;
};
struct StartupArgs args;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
{
CrashHandler::Initialize();
TraceUtil::Initialize();
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
args.foreground = false;
args.captureDevice = NULL;
int ret = parseArgs(args);
if (ret != 0)
fprintf(stderr, "Failed to parse command line arguments\n");
else
{
if (args.foreground)
setupConsole();
Service::InstallHook();
HANDLE captureThread = CreateThread(NULL, 0, CaptureThread, NULL, 0, NULL);
while (running)
{
MSG msg;
BOOL bRet = GetMessage(&msg, NULL, 0, 0);
if (bRet == -1 || bRet == 0)
{
ret = msg.wParam;
break;
}
DispatchMessage(&msg);
}
Service::RemoveHook();
running = false;
ret = WaitForSingleObject(captureThread, INFINITE);
CloseHandle(captureThread);
}
if (ret != 0)
{
if (!args.foreground)
{
setupConsole();
fprintf(stderr, "An error occurred, re-run in forground mode (-f) for more information\n");
}
}
if (consoleActive)
{
fprintf(stderr, "\nPress enter to terminate...");
fflush(stderr);
getc(stdin);
}
return ret;
}
static DWORD WINAPI CaptureThread(LPVOID lpParameter)
{
int ret = 0;
while (running)
{
ret = run();
if (ret != 0)
break;
}
running = false;
return ret;
}
int run()
{
/* increase the system timer resolution */
ULONG currentRes;
NtSetTimerResolution(0, TRUE, &currentRes);
/* boost our thread priority class as high as possible */
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
/* use MMCSS to boost our priority for capture */
DWORD taskIndex = 0;
HANDLE task = AvSetMmThreadCharacteristics(L"Capture", &taskIndex);
if (!task || (AvSetMmThreadPriority(task, AVRT_PRIORITY_CRITICAL) == FALSE))
DEBUG_WARN("Failed to boosted priority using MMCSS");
ICapture * captureDevice;
if (args.captureDevice == NULL)
captureDevice = CaptureFactory::DetectDevice(&args.captureOptions);
else
{
captureDevice = CaptureFactory::GetDevice(args.captureDevice, &args.captureOptions);
if (!captureDevice)
{
setupConsole();
fprintf(stderr, "Failed to configure requested capture device\n");
return -1;
}
}
if (!captureDevice)
{
setupConsole();
fprintf(stderr, "Unable to configure a capture device\n");
return -1;
}
Service &svc = Service::Instance();
if (!svc.Initialize(captureDevice))
return -1;
int retry = 0;
bool running = true;
while (running)
{
switch (svc.Process())
{
case PROCESS_STATUS_OK:
retry = 0;
break;
case PROCESS_STATUS_RETRY:
if (retry++ == 3)
{
fprintf(stderr, "Too many consecutive retries, aborting");
running = false;
}
break;
case PROCESS_STATUS_ERROR:
fprintf(stderr, "Capture process returned error");
running = false;
}
}
svc.DeInitialize();
if (task)
AvRevertMmThreadCharacteristics(task);
return 0;
}
int parseArgs(struct StartupArgs & args)
{
int c;
while((c = getopt(__argc, __argv, "hc:o:fld:")) != -1)
{
switch (c)
{
case '?':
case 'h':
doHelp();
return -1;
case 'c':
{
const CaptureFactory::DeviceList deviceList = CaptureFactory::GetDevices();
bool found = false;
if (strcmp(optarg, "?") != 0)
{
for (CaptureFactory::DeviceList::const_iterator it = deviceList.begin(); it != deviceList.end(); ++it)
{
if (_strcmpi(optarg, (*it)->GetName()) == 0)
{
args.captureDevice = (*it)->GetName();
found = true;
break;
}
}
if (!found)
{
setupConsole();
fprintf(stderr, "Invalid capture device: %s\n\n", optarg);
}
}
if (!found)
{
setupConsole();
fprintf(stderr, "Available Capture Devices:\n\n");
for (CaptureFactory::DeviceList::const_iterator it = deviceList.begin(); it != deviceList.end(); ++it)
fprintf(stderr, " %s\n", (*it)->GetName());
return -1;
}
break;
}
case 'o':
{
args.captureOptions.push_back(optarg);
break;
}
case 'f':
args.foreground = true;
break;
case 'l':
doLicense();
return -1;
case 'd':
if (optarg == NULL || strlen(optarg) == 0)
{
setupConsole();
fprintf(stderr, "Device ID missing\n");
return -1;
}
else if (*optarg == '?')
{
setupConsole();
IVSHMEM::listDevices();
return -1;
}
else
{
PCI_DEVICE dev;
int cnt = sscanf_s(optarg, "%hhu,%hhu,%hhu", &dev.bus, &dev.addr, &dev.func);
if (cnt == 3)
{
Service::SetDevice(dev);
}
else
{
setupConsole();
fprintf(stderr, "Invalid Parameter\n");
return -1;
}
}
break;
}
}
return 0;
}
void doHelp()
{
setupConsole();
const char *app = PathFindFileNameA(__argv[0]);
fprintf(stderr,
"Usage: %s [OPTION]...\n"
"Example: %s -c ?\n"
"\n"
" -h Print out this help\n"
" -c Specify the capture device to use or ? to list availble (device is probed if not specified)\n"
" -o Option to pass to the capture device, may be specified multiple times for extra options\n"
" -f Foreground mode\n"
" -l License information\n"
" -d Specify the IVSHMEM device with \"<bus>,<slot>,<function>\" or ? to list available\n",
app,
app
);
}
void doLicense()
{
setupConsole();
fprintf(stderr,
"Looking Glass - KVM FrameRelay (KVMFR) Client\n"
"Copyright(C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>\n"
"\n"
"This program is free software; you can redistribute it and / or modify it under\n"
"the terms of the GNU General Public License as published by the Free Software\n"
"Foundation; either version 2 of the License, or (at your option) any later\n"
"version.\n"
"\n"
"This program is distributed in the hope that it will be useful, but WITHOUT ANY\n"
"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n"
"PARTICULAR PURPOSE.See the GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License along with\n"
"this program; if not, write to the Free Software Foundation, Inc., 59 Temple\n"
"Place, Suite 330, Boston, MA 02111 - 1307 USA\n"
);
}
void setupConsole()
{
if (consoleActive)
return;
HANDLE _handle;
int _conout;
FILE * fp;
AllocConsole();
CONSOLE_SCREEN_BUFFER_INFO conInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conInfo);
conInfo.dwSize.Y = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), conInfo.dwSize);
_handle = GetStdHandle(STD_INPUT_HANDLE);
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
fp = _fdopen(_conout, "r");
freopen_s(&fp, "CONIN$", "r", stdin);
_handle = GetStdHandle(STD_OUTPUT_HANDLE);
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
fp = _fdopen(_conout, "w");
freopen_s(&fp, "CONOUT$", "w", stdout);
_handle = GetStdHandle(STD_ERROR_HANDLE);
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
fp = _fdopen(_conout, "w");
freopen_s(&fp, "CONOUT$", "w", stderr);
std::ios::sync_with_stdio();
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
consoleActive = true;
}

View File

@ -1,109 +0,0 @@
#include <stdbool.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
SDL_Window * window;
SDL_Renderer * renderer;
TTF_Init();
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("sync-test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1000, 1040, SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Event event;
bool running = true;
unsigned int frameCount = 0;
Uint32 fpsFrame = 0;
Uint32 fpsStart = SDL_GetTicks();
float fps = 0.0f;
TTF_Font * fpsFont = NULL;
SDL_Rect fpsTextRect = {5, 5};
SDL_Texture * fpsText = NULL;
int width = 1000;
int boxX = 100;
int boxY = 100;
fpsFont = TTF_OpenFont("C:\\Windows\\Fonts\\cour.ttf", 24);
while (running)
{
while (SDL_PollEvent(&event))
switch(event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYUP:
switch(event.key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
running = false;
break;
case SDL_SCANCODE_F11:
SDL_SetWindowFullscreen(window, (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
break;
}
case SDL_WINDOWEVENT:
switch (event.window.event)
{
case SDL_WINDOWEVENT_RESIZED:
width = event.window.data1;
boxX = event.window.data1 / 10;
boxY = (event.window.data2 - 40) / 10;
break;
}
}
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, SDL_ALPHA_OPAQUE);
for (int y = 0; y < 10; ++y)
for (int x = 0; x < 10; ++x)
{
const SDL_Rect rect = { x * boxX, y * boxY + 40, boxX, boxY};
if (y * 10 + x == frameCount % 100)
SDL_RenderFillRect(renderer, &rect);
else
SDL_RenderDrawRect(renderer, &rect);
}
if (SDL_GetTicks() - fpsStart > 1000)
{
const float delta = (float)(SDL_GetTicks() - fpsStart) / 1000.0f;
const unsigned int frames = frameCount - fpsFrame;
fps = (float)frames / delta;
fpsStart = SDL_GetTicks();
fpsFrame = frameCount;
}
const SDL_Color c = {0x00, 0xff, 0x00, 0xff};
char text[128];
snprintf(text, sizeof(text), "FPS: %7.4f, Frame: %05u \"F11\" to toggle Full Screen", fps, frameCount);
SDL_Surface * fpsSurf = TTF_RenderText_Solid(fpsFont, text, c);
if (fpsText)
SDL_DestroyTexture(fpsText);
fpsText = SDL_CreateTextureFromSurface(renderer, fpsSurf);
fpsTextRect.x = width / 2 - fpsSurf->w / 2;
fpsTextRect.y = 20 - fpsSurf->h / 2;
fpsTextRect.w = fpsSurf->w;
fpsTextRect.h = fpsSurf->h;
SDL_FreeSurface(fpsSurf);
SDL_RenderCopy(renderer, fpsText, NULL, &fpsTextRect);
SDL_RenderPresent(renderer);
++frameCount;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
return 0;
}

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="freetype.redist" version="2.6.2.1" targetFramework="native" />
<package id="sdl2.v140" version="2.0.4" targetFramework="native" />
<package id="sdl2.v140.redist" version="2.0.4" targetFramework="native" />
<package id="sdl2_ttf.v140" version="2.0.14" targetFramework="native" />
<package id="sdl2_ttf.v140.redist" version="2.0.14" targetFramework="native" />
</packages>

View File

@ -1,302 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - NvFBC|Win32">
<Configuration>Debug - NvFBC</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug - NvFBC|x64">
<Configuration>Debug - NvFBC</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - NvFBC|Win32">
<Configuration>Release - NvFBC</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - NvFBC|x64">
<Configuration>Release - NvFBC</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>synctest</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.c" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\freetype.redist.2.6.2.1\build\native\freetype.redist.targets" Condition="Exists('..\packages\freetype.redist.2.6.2.1\build\native\freetype.redist.targets')" />
<Import Project="..\packages\sdl2.v140.redist.2.0.4\build\native\sdl2.v140.redist.targets" Condition="Exists('..\packages\sdl2.v140.redist.2.0.4\build\native\sdl2.v140.redist.targets')" />
<Import Project="..\packages\sdl2_ttf.v140.redist.2.0.14\build\native\sdl2_ttf.v140.redist.targets" Condition="Exists('..\packages\sdl2_ttf.v140.redist.2.0.14\build\native\sdl2_ttf.v140.redist.targets')" />
<Import Project="..\packages\sdl2_ttf.v140.2.0.14\build\native\sdl2_ttf.v140.targets" Condition="Exists('..\packages\sdl2_ttf.v140.2.0.14\build\native\sdl2_ttf.v140.targets')" />
<Import Project="..\packages\sdl2.v140.2.0.4\build\native\sdl2.v140.targets" Condition="Exists('..\packages\sdl2.v140.2.0.4\build\native\sdl2.v140.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\freetype.redist.2.6.2.1\build\native\freetype.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\freetype.redist.2.6.2.1\build\native\freetype.redist.targets'))" />
<Error Condition="!Exists('..\packages\sdl2.v140.redist.2.0.4\build\native\sdl2.v140.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\sdl2.v140.redist.2.0.4\build\native\sdl2.v140.redist.targets'))" />
<Error Condition="!Exists('..\packages\sdl2_ttf.v140.redist.2.0.14\build\native\sdl2_ttf.v140.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\sdl2_ttf.v140.redist.2.0.14\build\native\sdl2_ttf.v140.redist.targets'))" />
<Error Condition="!Exists('..\packages\sdl2_ttf.v140.2.0.14\build\native\sdl2_ttf.v140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\sdl2_ttf.v140.2.0.14\build\native\sdl2_ttf.v140.targets'))" />
<Error Condition="!Exists('..\packages\sdl2.v140.2.0.4\build\native\sdl2.v140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\sdl2.v140.2.0.4\build\native\sdl2.v140.targets'))" />
</Target>
</Project>

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>