Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions dll/ApiHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ bool WINAPI MsRdpEx_CaptureBlt(
bool outputMirrorEnabled = false;
bool videoRecordingEnabled = false;
uint32_t videoRecordingQuality = 5;
uint32_t videoRecordingFrameRate = 0;
bool dumpBitmapUpdates = false;
IMsRdpExInstance* instance = NULL;
MsRdpEx_OutputMirror* outputMirror = NULL;
Expand All @@ -457,6 +458,7 @@ bool WINAPI MsRdpEx_CaptureBlt(
outputMirrorEnabled = pExtendedSettings->GetOutputMirrorEnabled();
videoRecordingEnabled = pExtendedSettings->GetVideoRecordingEnabled();
videoRecordingQuality = pExtendedSettings->GetVideoRecordingQuality();
videoRecordingFrameRate = pExtendedSettings->GetVideoRecordingFrameRate();
dumpBitmapUpdates = pExtendedSettings->GetDumpBitmapUpdates();

if (!outputMirrorEnabled)
Expand All @@ -476,6 +478,7 @@ bool WINAPI MsRdpEx_CaptureBlt(
MsRdpEx_OutputMirror_SetDumpBitmapUpdates(outputMirror, dumpBitmapUpdates);
MsRdpEx_OutputMirror_SetVideoRecordingEnabled(outputMirror, videoRecordingEnabled);
MsRdpEx_OutputMirror_SetVideoQualityLevel(outputMirror, videoRecordingQuality);
MsRdpEx_OutputMirror_SetVideoFrameRate(outputMirror, videoRecordingFrameRate);

char* recordingPath = pExtendedSettings->GetRecordingPath();
if (recordingPath) {
Expand Down
13 changes: 12 additions & 1 deletion dll/OutputMirror.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct _MsRdpEx_OutputMirror
MsRdpEx_RecordingManifest* manifest;
FILE* frameMetadataFile;

uint32_t videoFrameRate;

CRITICAL_SECTION lock;
};

Expand Down Expand Up @@ -83,9 +85,9 @@ bool MsRdpEx_OutputMirror_DumpFrame(MsRdpEx_OutputMirror* ctx)
captureTime = GetTickCount64() - ctx->captureBaseTime;

if (ctx->videoRecordingEnabled && ctx->videoRecorder) {
// Submit every paint; cadeau caps the encode rate. A per-paint Timeout would force-encode and bypass that cap.
MsRdpEx_VideoRecorder_UpdateFrame(ctx->videoRecorder, ctx->bitmapData,
0, 0, ctx->bitmapWidth, ctx->bitmapHeight, ctx->bitmapStep);
MsRdpEx_VideoRecorder_Timeout(ctx->videoRecorder);
}
Comment thread
irvingoujAtDevolution marked this conversation as resolved.

if (ctx->dumpBitmapUpdates) {
Expand Down Expand Up @@ -121,6 +123,11 @@ void MsRdpEx_OutputMirror_SetVideoQualityLevel(MsRdpEx_OutputMirror* ctx, uint32
ctx->videoQualityLevel = videoQualityLevel;
}

void MsRdpEx_OutputMirror_SetVideoFrameRate(MsRdpEx_OutputMirror* ctx, uint32_t videoFrameRate)
{
ctx->videoFrameRate = videoFrameRate;
}

void MsRdpEx_OutputMirror_SetRecordingPath(MsRdpEx_OutputMirror* ctx, const char* recordingPath)
{
strcpy_s(ctx->recordingPath, MSRDPEX_MAX_PATH, recordingPath);
Expand Down Expand Up @@ -214,6 +221,10 @@ bool MsRdpEx_OutputMirror_Init(MsRdpEx_OutputMirror* ctx)
MsRdpEx_VideoRecorder_SetFileName(ctx->videoRecorder, filename);
MsRdpEx_VideoRecorder_SetVideoQuality(ctx->videoRecorder, ctx->videoQualityLevel);

if (ctx->videoFrameRate > 0) {
MsRdpEx_VideoRecorder_SetFrameRate(ctx->videoRecorder, ctx->videoFrameRate);
}

if (!MsRdpEx_StringIsNullOrEmpty(ctx->recordingPipeName)) {
MsRdpEx_VideoRecorder_SetPipeName(ctx->videoRecorder, ctx->recordingPipeName);
}
Expand Down
30 changes: 30 additions & 0 deletions dll/RdpSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extern "C" const GUID IID_ITSPropertySet;
extern MsRdpEx_mstscax g_mstscax;
extern MsRdpEx_rdclientax g_rdclientax;

#define MSRDPEX_VIDEO_RECORDING_MAX_FRAME_RATE 60

static bool g_TSPropertySet_Hooked = false;

static ITSPropertySet_SetBoolProperty Real_ITSPropertySet_SetBoolProperty = NULL;
Expand Down Expand Up @@ -826,6 +828,18 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_Property(BSTR bstrPropertyName, VA

hr = S_OK;
}
else if (MsRdpEx_StringEquals(propName, "VideoRecordingFrameRate"))
{
if ((pValue->vt != VT_UI4) && (pValue->vt != VT_I4))
goto end;

m_VideoRecordingFrameRate = (uint32_t)pValue->uintVal;

if (m_VideoRecordingFrameRate > MSRDPEX_VIDEO_RECORDING_MAX_FRAME_RATE)
m_VideoRecordingFrameRate = MSRDPEX_VIDEO_RECORDING_MAX_FRAME_RATE;

Comment thread
irvingoujAtDevolution marked this conversation as resolved.
hr = S_OK;
}
else if (MsRdpEx_StringEquals(propName, "RecordingPath"))
{
if (pValue->vt != VT_BSTR)
Expand Down Expand Up @@ -971,6 +985,11 @@ HRESULT __stdcall CMsRdpExtendedSettings::get_Property(BSTR bstrPropertyName, VA
pValue->intVal = (INT)m_VideoRecordingQuality;
hr = S_OK;
}
else if (MsRdpEx_StringEquals(propName, "VideoRecordingFrameRate")) {
pValue->vt = VT_I4;
pValue->intVal = (INT)m_VideoRecordingFrameRate;
hr = S_OK;
}
else if (MsRdpEx_StringEquals(propName, "RecordingPath")) {
pValue->vt = VT_BSTR;
const char* recordingPath = m_RecordingPath ? m_RecordingPath : "";
Expand Down Expand Up @@ -1384,6 +1403,12 @@ HRESULT CMsRdpExtendedSettings::ApplyRdpFile(void* rdpFilePtr)
pMsRdpExtendedSettings->put_Property(propName, &value);
}
}
else if (MsRdpEx_RdpFileEntry_IsMatch(entry, 'i', "VideoRecordingFrameRate")) {
if (MsRdpEx_RdpFileEntry_GetIntValue(entry, &value)) {
bstr_t propName = _com_util::ConvertStringToBSTR(entry->name);
pMsRdpExtendedSettings->put_Property(propName, &value);
}
}
else if (MsRdpEx_RdpFileEntry_IsMatch(entry, 's', "RecordingPath")) {
bstr_t propName = _com_util::ConvertStringToBSTR(entry->name);
bstr_t propValue = _com_util::ConvertStringToBSTR(entry->value);
Expand Down Expand Up @@ -1635,6 +1660,11 @@ uint32_t CMsRdpExtendedSettings::GetVideoRecordingQuality()
return m_VideoRecordingQuality;
}

uint32_t CMsRdpExtendedSettings::GetVideoRecordingFrameRate()
{
return m_VideoRecordingFrameRate;
}

char* CMsRdpExtendedSettings::GetRecordingPath()
{
if (m_RecordingPath)
Expand Down
1 change: 1 addition & 0 deletions include/MsRdpEx/OutputMirror.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ bool MsRdpEx_OutputMirror_DumpFrame(MsRdpEx_OutputMirror* ctx);
void MsRdpEx_OutputMirror_SetDumpBitmapUpdates(MsRdpEx_OutputMirror* ctx, bool dumpBitmapUpdates);
void MsRdpEx_OutputMirror_SetVideoRecordingEnabled(MsRdpEx_OutputMirror* ctx, bool videoRecordingEnabled);
void MsRdpEx_OutputMirror_SetVideoQualityLevel(MsRdpEx_OutputMirror* ctx, uint32_t videoQualityLevel);
void MsRdpEx_OutputMirror_SetVideoFrameRate(MsRdpEx_OutputMirror* ctx, uint32_t videoFrameRate);
void MsRdpEx_OutputMirror_SetRecordingPath(MsRdpEx_OutputMirror* ctx, const char* recordingPath);
void MsRdpEx_OutputMirror_SetRecordingPipeName(MsRdpEx_OutputMirror* ctx, const char* recordingPipeName);
void MsRdpEx_OutputMirror_SetSessionId(MsRdpEx_OutputMirror* ctx, const char* sessionId);
Expand Down
2 changes: 2 additions & 0 deletions include/MsRdpEx/RdpSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class CMsRdpExtendedSettings : public IMsRdpExtendedSettings
bool GetOutputMirrorEnabled();
bool GetVideoRecordingEnabled();
uint32_t GetVideoRecordingQuality();
uint32_t GetVideoRecordingFrameRate();
char* GetRecordingPath();
char* GetRecordingSessionId();
char* GetRecordingPipeName();
Expand All @@ -88,6 +89,7 @@ class CMsRdpExtendedSettings : public IMsRdpExtendedSettings
bool m_OutputMirrorEnabled = false;
bool m_VideoRecordingEnabled = false;
uint32_t m_VideoRecordingQuality = 5;
uint32_t m_VideoRecordingFrameRate = 0;
char* m_RecordingPath = NULL;
char* m_RecordingSessionId = NULL;
char* m_RecordingPipeName = NULL;
Expand Down