[host] general performance improvements

This commit is contained in:
Geoffrey McRae 2018-10-04 00:07:34 +10:00
parent 471303a179
commit 8f0a6cd810
7 changed files with 200 additions and 158 deletions

View File

@ -29,9 +29,10 @@ DXGI::DXGI() :
m_dxgiFactory(), m_dxgiFactory(),
m_device(), m_device(),
m_deviceContext(), m_deviceContext(),
m_dup(), m_dup()
m_pointer(NULL)
{ {
InitializeCriticalSection(&m_cursorCS );
InitializeCriticalSection(&m_cursorDataCS);
} }
DXGI::~DXGI() DXGI::~DXGI()
@ -91,9 +92,9 @@ bool DXGI::Initialize(CaptureOptions * options)
DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description); DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description);
DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId); DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId);
DEBUG_INFO("Device Device ID : 0x%x" , adapterDesc.DeviceId); DEBUG_INFO("Device Device ID : 0x%x" , adapterDesc.DeviceId);
DEBUG_INFO("Device Video Mem : %5u MB", adapterDesc.DedicatedVideoMemory / 1048576); DEBUG_INFO("Device Video Mem : %lld MB", adapterDesc.DedicatedVideoMemory / 1048576);
DEBUG_INFO("Device Sys Mem : %5u MB", adapterDesc.DedicatedSystemMemory / 1048576); DEBUG_INFO("Device Sys Mem : %lld MB", adapterDesc.DedicatedSystemMemory / 1048576);
DEBUG_INFO("Shared Sys Mem : %5u MB", adapterDesc.SharedSystemMemory / 1048576); DEBUG_INFO("Shared Sys Mem : %lld MB", adapterDesc.SharedSystemMemory / 1048576);
m_width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left; m_width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left;
m_height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top; m_height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top;
@ -314,11 +315,12 @@ void DXGI::DeInitialize()
ReleaseFrame(); ReleaseFrame();
if (m_pointer) while(m_cursorData.size())
{ {
delete[] m_pointer; CursorBuffer * buf = m_cursorData.front();
m_pointer = NULL; delete[] buf->buffer;
m_pointerBufSize = 0; delete buf;
m_cursorData.pop_front();
} }
for(int i = 0; i < _countof(m_texture); ++i) for(int i = 0; i < _countof(m_texture); ++i)
@ -353,10 +355,8 @@ GrabStatus Capture::DXGI::Capture()
if (!m_initialized) if (!m_initialized)
return GRAB_STATUS_ERROR; return GRAB_STATUS_ERROR;
m_cursor.updated = false; CursorInfo cursor = { 0 };
m_cursor.hasPos = false; bool cursorUpdated = false;
m_cursor.hasShape = false;
DXGI_OUTDUPL_FRAME_INFO frameInfo; DXGI_OUTDUPL_FRAME_INFO frameInfo;
IDXGIResourcePtr res; IDXGIResourcePtr res;
@ -382,40 +382,59 @@ GrabStatus Capture::DXGI::Capture()
if (frameInfo.LastMouseUpdateTime.QuadPart) if (frameInfo.LastMouseUpdateTime.QuadPart)
{ {
if ( if (
m_lastMousePos.x != frameInfo.PointerPosition.Position.x || m_lastCursorX != frameInfo.PointerPosition.Position.x ||
m_lastMousePos.y != frameInfo.PointerPosition.Position.y m_lastCursorY != frameInfo.PointerPosition.Position.y
) { ) {
m_cursor.updated = true; cursorUpdated = true;
m_cursor.hasPos = true; cursor.hasPos = true;
m_cursor.x = frameInfo.PointerPosition.Position.x; cursor.x = m_lastCursorX = frameInfo.PointerPosition.Position.x;
m_cursor.y = frameInfo.PointerPosition.Position.y; cursor.y = m_lastCursorY = frameInfo.PointerPosition.Position.y;
m_lastMousePos.x = frameInfo.PointerPosition.Position.x;
m_lastMousePos.y = frameInfo.PointerPosition.Position.y;
} }
if (m_lastMouseVis != frameInfo.PointerPosition.Visible) if (m_lastMouseVis != frameInfo.PointerPosition.Visible)
{ {
m_cursor.updated = true; cursorUpdated = true;
m_lastMouseVis = frameInfo.PointerPosition.Visible; m_lastMouseVis = frameInfo.PointerPosition.Visible;
} }
m_cursor.visible = m_lastMouseVis == TRUE; cursor.visible = m_lastMouseVis == TRUE;
} }
// if the pointer shape has changed // if the pointer shape has changed
if (frameInfo.PointerShapeBufferSize > 0) if (frameInfo.PointerShapeBufferSize > 0)
{ {
m_cursor.updated = true; CursorBuffer * buf;
if (m_pointerBufSize < frameInfo.PointerShapeBufferSize)
if (m_cursorData.size() == 0)
{ {
if (m_pointer) // create a new buffer
delete[] m_pointer; buf = new CursorBuffer;
m_pointer = new BYTE[frameInfo.PointerShapeBufferSize]; buf->buffer = new char[frameInfo.PointerShapeBufferSize];
m_pointerBufSize = frameInfo.PointerShapeBufferSize; buf->bufferSize = frameInfo.PointerShapeBufferSize;
}
else
{
// get an existing buffer from the pool
EnterCriticalSection(&m_cursorDataCS);
buf = m_cursorData.front();
m_cursorData.pop_front();
LeaveCriticalSection(&m_cursorDataCS);
// resize the buffer if required
if (buf->bufferSize < frameInfo.PointerShapeBufferSize)
{
delete[] buf->buffer;
buf->buffer = new char[frameInfo.PointerShapeBufferSize];
buf->bufferSize = frameInfo.PointerShapeBufferSize;
}
} }
buf->pointerSize = 0;
cursor.shape = buf;
cursorUpdated = true;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo; DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
status = m_dup->GetFramePointerShape(m_pointerBufSize, m_pointer, &m_pointerSize, &shapeInfo); status = m_dup->GetFramePointerShape(buf->bufferSize, buf->buffer, &buf->pointerSize, &shapeInfo);
if (FAILED(status)) if (FAILED(status))
{ {
DEBUG_WINERROR("Failed to get the new pointer shape", status); DEBUG_WINERROR("Failed to get the new pointer shape", status);
@ -424,20 +443,25 @@ GrabStatus Capture::DXGI::Capture()
switch (shapeInfo.Type) switch (shapeInfo.Type)
{ {
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR : m_cursor.type = CURSOR_TYPE_COLOR; break; case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR : cursor.type = CURSOR_TYPE_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR: m_cursor.type = CURSOR_TYPE_MASKED_COLOR; break; case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR: cursor.type = CURSOR_TYPE_MASKED_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME : m_cursor.type = CURSOR_TYPE_MONOCHROME; break; case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME : cursor.type = CURSOR_TYPE_MONOCHROME; break;
default: default:
DEBUG_ERROR("Invalid cursor type"); DEBUG_ERROR("Invalid cursor type");
return GRAB_STATUS_ERROR; return GRAB_STATUS_ERROR;
} }
m_cursor.hasShape = true; cursor.w = shapeInfo.Width;
m_cursor.shape = m_pointer; cursor.h = shapeInfo.Height;
m_cursor.w = shapeInfo.Width; cursor.pitch = shapeInfo.Pitch;
m_cursor.h = shapeInfo.Height; }
m_cursor.pitch = shapeInfo.Pitch;
m_cursor.dataSize = m_pointerSize; if (cursorUpdated)
{
// push the cursor update into the queue
EnterCriticalSection(&m_cursorCS);
m_cursorUpdates.push_back(cursor);
LeaveCriticalSection(&m_cursorCS);
} }
// if we also have frame data, break out to process it // if we also have frame data, break out to process it
@ -447,7 +471,7 @@ GrabStatus Capture::DXGI::Capture()
res = NULL; res = NULL;
// if the cursor has been updated // if the cursor has been updated
if (m_cursor.updated) if (cursorUpdated)
return GRAB_STATUS_CURSOR; return GRAB_STATUS_CURSOR;
// otherwise just try again // otherwise just try again
@ -481,7 +505,6 @@ GrabStatus Capture::DXGI::Capture()
if (!m_ftexture) if (!m_ftexture)
{ {
ReleaseFrame();
DEBUG_ERROR("Failed to get src ID3D11Texture2D"); DEBUG_ERROR("Failed to get src ID3D11Texture2D");
return GRAB_STATUS_ERROR; return GRAB_STATUS_ERROR;
} }
@ -682,7 +705,25 @@ GrabStatus DXGI::GetFrame(struct FrameInfo & frame)
return GrabFrameRaw(frame); return GrabFrameRaw(frame);
} }
const CursorInfo & DXGI::GetCursor() bool DXGI::GetCursor(CursorInfo & cursor)
{ {
return m_cursor; if (!m_cursorUpdates.size())
return false;
EnterCriticalSection(&m_cursorCS);
cursor = m_cursorUpdates.front();
m_cursorUpdates.pop_front();
LeaveCriticalSection(&m_cursorCS);
return true;
}
void DXGI::FreeCursor(CursorInfo & cursor)
{
/* put the buffer back into the pool */
if (cursor.shape)
{
EnterCriticalSection(&m_cursorDataCS);
m_cursorData.push_front(cursor.shape);
LeaveCriticalSection(&m_cursorDataCS);
}
} }

View File

@ -24,6 +24,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "TextureConverter.h" #include "TextureConverter.h"
#include "MFT/H264.h" #include "MFT/H264.h"
#include <list>
#define W32_LEAN_AND_MEAN #define W32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <shlwapi.h> #include <shlwapi.h>
@ -58,15 +60,23 @@ namespace Capture
size_t GetMaxFrameSize(); size_t GetMaxFrameSize();
GrabStatus Capture(); GrabStatus Capture();
GrabStatus GetFrame (struct FrameInfo & frame ); GrabStatus GetFrame (struct FrameInfo & frame );
const CursorInfo & GetCursor(); bool GetCursor(CursorInfo & cursor);
void FreeCursor(CursorInfo & cursor);
GrabStatus DiscardFrame(); GrabStatus DiscardFrame();
private: private:
typedef std::list<CursorInfo > CursorList;
typedef std::list<CursorBuffer *> CursorBufferPool;
bool InitRawCapture(); bool InitRawCapture();
bool InitYUV420Capture(); bool InitYUV420Capture();
bool InitH264Capture(); bool InitH264Capture();
struct CursorInfo m_cursor; CursorList m_cursorUpdates;
CursorBufferPool m_cursorData;
CRITICAL_SECTION m_cursorCS;
CRITICAL_SECTION m_cursorDataCS;
ID3D11Texture2DPtr m_ftexture; ID3D11Texture2DPtr m_ftexture;
GrabStatus ReleaseFrame(); GrabStatus ReleaseFrame();
@ -92,10 +102,7 @@ namespace Capture
TextureConverter * m_textureConverter; TextureConverter * m_textureConverter;
MFT::H264 * m_h264; MFT::H264 * m_h264;
BYTE * m_pointer; int m_lastCursorX, m_lastCursorY;
UINT m_pointerBufSize;
UINT m_pointerSize;
BOOL m_lastMouseVis; BOOL m_lastMouseVis;
POINT m_lastMousePos;
}; };
}; };

View File

@ -23,20 +23,23 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <vector> #include <vector>
#include <windows.h> #include <windows.h>
struct CursorBuffer
{
unsigned int bufferSize;
char * buffer;
unsigned int pointerSize;
};
struct CursorInfo struct CursorInfo
{ {
bool updated;
bool visible; bool visible;
bool hasShape;
bool hasPos; bool hasPos;
int x, y; int x, y;
enum CursorType type; enum CursorType type;
unsigned int w, h; unsigned int w, h;
unsigned int pitch; unsigned int pitch;
void * shape; CursorBuffer * shape;
unsigned int dataSize;
}; };
struct FrameInfo struct FrameInfo
@ -73,6 +76,7 @@ public:
virtual size_t GetMaxFrameSize() = 0; virtual size_t GetMaxFrameSize() = 0;
virtual enum GrabStatus Capture() = 0; virtual enum GrabStatus Capture() = 0;
virtual enum GrabStatus GetFrame(struct FrameInfo & frame) = 0; virtual enum GrabStatus GetFrame(struct FrameInfo & frame) = 0;
virtual const CursorInfo & GetCursor() = 0; virtual bool GetCursor(CursorInfo & cursor) = 0;
virtual void FreeCursor(CursorInfo & cursor) = 0;
virtual enum GrabStatus DiscardFrame() = 0; virtual enum GrabStatus DiscardFrame() = 0;
}; };

View File

@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "Service.h" #include "Service.h"
#include "IVSHMEM.h" #include "IVSHMEM.h"
#include "TraceUtil.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/KVMFR.h" #include "common/KVMFR.h"
@ -171,7 +172,7 @@ bool Service::Process()
if (!m_initialized) if (!m_initialized)
return false; return false;
volatile uint8_t *flags = &(m_shmHeader->flags); volatile char * flags = (volatile char *)&(m_shmHeader->flags);
// check if the client has flagged a restart // check if the client has flagged a restart
if (*flags & KVMFR_HEADER_FLAG_RESTART) if (*flags & KVMFR_HEADER_FLAG_RESTART)
@ -189,7 +190,7 @@ bool Service::Process()
return false; return false;
} }
INTERLOCKED_AND8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_RESTART)); INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART));
} }
GrabStatus result; GrabStatus result;
@ -211,8 +212,6 @@ bool Service::Process()
{ {
ok = true; ok = true;
repeat = true; repeat = true;
if (--m_frameIndex < 0)
m_frameIndex = MAX_FRAMES - 1;
break; break;
} }
@ -232,7 +231,7 @@ bool Service::Process()
case GRAB_STATUS_REINIT: case GRAB_STATUS_REINIT:
DEBUG_INFO("ReInitialize Requested"); DEBUG_INFO("ReInitialize Requested");
*flags |= KVMFR_HEADER_FLAG_PAUSED; INTERLOCKED_OR8(flags, KVMFR_HEADER_FLAG_PAUSED);
if(WTSGetActiveConsoleSessionId() != m_consoleSessionID) if(WTSGetActiveConsoleSessionId() != m_consoleSessionID)
{ {
DEBUG_INFO("User switch detected, waiting to regain control"); DEBUG_INFO("User switch detected, waiting to regain control");
@ -255,7 +254,7 @@ bool Service::Process()
return false; return false;
} }
*flags &= ~KVMFR_HEADER_FLAG_PAUSED; INTERLOCKED_AND8(flags, ~KVMFR_HEADER_FLAG_PAUSED);
// re-init request should not count towards a failure to capture // re-init request should not count towards a failure to capture
--i; --i;
@ -272,33 +271,7 @@ bool Service::Process()
return false; return false;
} }
const CursorInfo & cursor = m_capture->GetCursor();
if (cursor.updated)
{
EnterCriticalSection(&m_cursorCS);
if (cursor.hasPos)
{
m_cursorInfo.hasPos = true;
m_cursorInfo.x = cursor.x;
m_cursorInfo.y = cursor.y;
}
if (cursor.hasShape)
{
m_cursorInfo.hasShape = true;
m_cursorInfo.dataSize = cursor.dataSize;
m_cursorInfo.type = cursor.type;
m_cursorInfo.w = cursor.w;
m_cursorInfo.h = cursor.h;
m_cursorInfo.pitch = cursor.pitch;
m_cursorInfo.shape = cursor.shape;
}
m_cursorInfo.visible = cursor.visible;
LeaveCriticalSection(&m_cursorCS);
SetEvent(m_cursorEvent); SetEvent(m_cursorEvent);
}
if (!cursorOnly) if (!cursorOnly)
{ {
@ -313,11 +286,16 @@ bool Service::Process()
result = m_capture->GetFrame(frame); result = m_capture->GetFrame(frame);
if (result != GRAB_STATUS_OK) if (result != GRAB_STATUS_OK)
return result; {
DEBUG_INFO("GetFrame failed");
return false;
}
/* don't touch the frame inforamtion until the client is done with it */ /* don't touch the frame information until the client is done with it */
while (fi->flags & KVMFR_FRAME_FLAG_UPDATE) while (fi->flags & KVMFR_FRAME_FLAG_UPDATE)
{ {
/* this generally never occurs */
Sleep(1);
if (*flags & KVMFR_HEADER_FLAG_RESTART) if (*flags & KVMFR_HEADER_FLAG_RESTART)
break; break;
} }
@ -350,7 +328,7 @@ bool Service::Process()
} }
// update the flags // update the flags
INTERLOCKED_AND8((volatile char *)flags, KVMFR_HEADER_FLAG_RESTART); INTERLOCKED_AND8(flags, KVMFR_HEADER_FLAG_RESTART);
return true; return true;
} }
@ -361,54 +339,55 @@ DWORD Service::CursorThread()
if (WaitForSingleObject(m_cursorEvent, 1000) != WAIT_OBJECT_0) if (WaitForSingleObject(m_cursorEvent, 1000) != WAIT_OBJECT_0)
continue; continue;
CursorInfo ci;
while (m_capture->GetCursor(ci))
{
volatile KVMFRCursor * cursor = &(m_shmHeader->cursor); volatile KVMFRCursor * cursor = &(m_shmHeader->cursor);
// wait until the client is ready // wait until the client is ready
while (cursor->flags != 0) while (cursor->flags != 0)
{ {
Sleep(2); Sleep(1);
if (!m_capture) if (!m_capture)
return 0; return 0;
} }
EnterCriticalSection(&m_cursorCS); uint8_t flags = 0;
if (m_cursorInfo.hasPos)
if (ci.hasPos)
{ {
m_cursorInfo.hasPos = false;
// tell the client where the cursor is // tell the client where the cursor is
cursor->flags |= KVMFR_CURSOR_FLAG_POS; flags |= KVMFR_CURSOR_FLAG_POS;
cursor->x = m_cursorInfo.x; cursor->x = ci.x;
cursor->y = m_cursorInfo.y; cursor->y = ci.y;
if (m_cursorInfo.visible) if (ci.visible)
cursor->flags |= KVMFR_CURSOR_FLAG_VISIBLE; flags |= KVMFR_CURSOR_FLAG_VISIBLE;
else
cursor->flags &= ~KVMFR_CURSOR_FLAG_VISIBLE;
} }
if (m_cursorInfo.hasShape) if (ci.shape)
{ {
m_cursorInfo.hasShape = false; if (ci.shape->pointerSize > m_cursorDataSize)
if (m_cursorInfo.dataSize > m_cursorDataSize)
DEBUG_ERROR("Cursor size exceeds allocated space"); DEBUG_ERROR("Cursor size exceeds allocated space");
else else
{ {
// give the client the new cursor shape // give the client the new cursor shape
cursor->flags |= KVMFR_CURSOR_FLAG_SHAPE; flags |= KVMFR_CURSOR_FLAG_SHAPE;
++cursor->version; ++cursor->version;
cursor->type = m_cursorInfo.type; cursor->type = ci.type;
cursor->width = m_cursorInfo.w; cursor->width = ci.w;
cursor->height = m_cursorInfo.h; cursor->height = ci.h;
cursor->pitch = m_cursorInfo.pitch; cursor->pitch = ci.pitch;
cursor->dataPos = m_cursorOffset; cursor->dataPos = m_cursorOffset;
memcpy(m_cursorData, m_cursorInfo.shape, m_cursorInfo.dataSize); memcpy(m_cursorData, ci.shape->buffer, ci.shape->bufferSize);
} }
} }
flags |= KVMFR_CURSOR_FLAG_UPDATE;
LeaveCriticalSection(&m_cursorCS); cursor->flags = flags;
cursor->flags |= KVMFR_CURSOR_FLAG_UPDATE; m_capture->FreeCursor(ci);
}
} }
return 0; return 0;

View File

@ -72,7 +72,6 @@ private:
HANDLE m_cursorThread; HANDLE m_cursorThread;
HANDLE m_cursorEvent; HANDLE m_cursorEvent;
CursorInfo m_cursorInfo;
CRITICAL_SECTION m_cursorCS; CRITICAL_SECTION m_cursorCS;
size_t m_cursorDataSize; size_t m_cursorDataSize;
uint8_t * m_cursorData; uint8_t * m_cursorData;

View File

@ -165,8 +165,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>
@ -185,8 +184,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>
@ -205,8 +203,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>
@ -225,8 +222,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>
@ -249,9 +245,9 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
<Manifest> <Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness> <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
@ -273,8 +269,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>
@ -297,9 +292,9 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
<Manifest> <Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness> <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
@ -321,8 +316,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <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>
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;wmcodecdspuuid.lib;mfplat.lib;mfuuid.lib;evr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
<Manifest> <Manifest>

View File

@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <windows.h> #include <windows.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <avrt.h>
#include "common/debug.h" #include "common/debug.h"
#include "vendor/getopt/getopt.h" #include "vendor/getopt/getopt.h"
@ -41,6 +42,8 @@ void doLicense();
bool consoleActive = false; bool consoleActive = false;
void setupConsole(); void setupConsole();
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
struct StartupArgs struct StartupArgs
{ {
bool foreground; bool foreground;
@ -54,8 +57,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam
TraceUtil::Initialize(); TraceUtil::Initialize();
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
struct StartupArgs args; struct StartupArgs args;
args.foreground = false; args.foreground = false;
args.captureDevice = NULL; args.captureDevice = NULL;
@ -89,6 +90,19 @@ int run(struct StartupArgs & args)
if (args.foreground) if (args.foreground)
setupConsole(); setupConsole();
/* 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; ICapture * captureDevice;
if (args.captureDevice == NULL) if (args.captureDevice == NULL)
captureDevice = CaptureFactory::DetectDevice(&args.captureOptions); captureDevice = CaptureFactory::DetectDevice(&args.captureOptions);
@ -121,6 +135,10 @@ int run(struct StartupArgs & args)
} }
svc->DeInitialize(); svc->DeInitialize();
if (task)
AvRevertMmThreadCharacteristics(task);
return 0; return 0;
} }