mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 14:03:40 +00:00
[host] general performance improvements
This commit is contained in:
parent
471303a179
commit
8f0a6cd810
@ -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()
|
||||||
@ -88,12 +89,12 @@ bool DXGI::Initialize(CaptureOptions * options)
|
|||||||
|
|
||||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||||
adapter->GetDesc1(&adapterDesc);
|
adapter->GetDesc1(&adapterDesc);
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
@ -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;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -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;
|
||||||
};
|
};
|
||||||
|
141
host/Service.cpp
141
host/Service.cpp
@ -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;
|
||||||
@ -209,10 +210,8 @@ bool Service::Process()
|
|||||||
case GRAB_STATUS_TIMEOUT:
|
case GRAB_STATUS_TIMEOUT:
|
||||||
if (m_haveFrame)
|
if (m_haveFrame)
|
||||||
{
|
{
|
||||||
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();
|
SetEvent(m_cursorEvent);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
volatile KVMFRCursor * cursor = &(m_shmHeader->cursor);
|
CursorInfo ci;
|
||||||
// wait until the client is ready
|
while (m_capture->GetCursor(ci))
|
||||||
while (cursor->flags != 0)
|
|
||||||
{
|
{
|
||||||
Sleep(2);
|
volatile KVMFRCursor * cursor = &(m_shmHeader->cursor);
|
||||||
if (!m_capture)
|
// wait until the client is ready
|
||||||
return 0;
|
while (cursor->flags != 0)
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&m_cursorCS);
|
|
||||||
if (m_cursorInfo.hasPos)
|
|
||||||
{
|
|
||||||
m_cursorInfo.hasPos = false;
|
|
||||||
|
|
||||||
// tell the client where the cursor is
|
|
||||||
cursor->flags |= KVMFR_CURSOR_FLAG_POS;
|
|
||||||
cursor->x = m_cursorInfo.x;
|
|
||||||
cursor->y = m_cursorInfo.y;
|
|
||||||
|
|
||||||
if (m_cursorInfo.visible)
|
|
||||||
cursor->flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
|
||||||
else
|
|
||||||
cursor->flags &= ~KVMFR_CURSOR_FLAG_VISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_cursorInfo.hasShape)
|
|
||||||
{
|
|
||||||
m_cursorInfo.hasShape = false;
|
|
||||||
if (m_cursorInfo.dataSize > m_cursorDataSize)
|
|
||||||
DEBUG_ERROR("Cursor size exceeds allocated space");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// give the client the new cursor shape
|
Sleep(1);
|
||||||
cursor->flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
if (!m_capture)
|
||||||
++cursor->version;
|
return 0;
|
||||||
|
|
||||||
cursor->type = m_cursorInfo.type;
|
|
||||||
cursor->width = m_cursorInfo.w;
|
|
||||||
cursor->height = m_cursorInfo.h;
|
|
||||||
cursor->pitch = m_cursorInfo.pitch;
|
|
||||||
cursor->dataPos = m_cursorOffset;
|
|
||||||
|
|
||||||
memcpy(m_cursorData, m_cursorInfo.shape, m_cursorInfo.dataSize);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&m_cursorCS);
|
uint8_t flags = 0;
|
||||||
cursor->flags |= KVMFR_CURSOR_FLAG_UPDATE;
|
|
||||||
|
if (ci.hasPos)
|
||||||
|
{
|
||||||
|
// tell the client where the cursor is
|
||||||
|
flags |= KVMFR_CURSOR_FLAG_POS;
|
||||||
|
cursor->x = ci.x;
|
||||||
|
cursor->y = ci.y;
|
||||||
|
|
||||||
|
if (ci.visible)
|
||||||
|
flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ci.shape)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags |= KVMFR_CURSOR_FLAG_UPDATE;
|
||||||
|
|
||||||
|
cursor->flags = flags;
|
||||||
|
m_capture->FreeCursor(ci);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -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, ¤tRes);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user