Skip to content

Commit 260da3f

Browse files
committed
Release 1.1.1 - bug fixes and code clean-up
1 parent 2209bdc commit 260da3f

20 files changed

+163
-1875
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Advanced Interactive Streaming SDK is a C++ library that provides building block
44
Virtual and Augmented Reality, etc. using AMD Radeon graphics. It allows you to build a complete streaming solution including video and audio capture, video and audio encoder/decoder/pre-post-processing pipelines, a robust and secure network stack, or use some of its components, while implementing the rest yourself.
55

66
## Changelog:
7+
- v1.1.1 - bug fixes:
8+
- Allowing the server to start without audio when no audio output device is available on the server
9+
- Code clean-up
710
- v1.1.0 - added support for Linux:
811
- Server supported on AMD graphics with the Pro driver (X.org required)
912
- Client supported on AMD graphics with the Pro and RADV drivers, NVidia graphics (proprietary driver recommended), Intel graphics (X.org recommended, Wayland supported with some limitations)

samples/RemoteDesktopServer/RemoteDesktopServer.cpp

Lines changed: 26 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ static constexpr const wchar_t* PARAM_NAME_ENCRYPTION = L"encrypted";
7676
static constexpr const wchar_t* PARAM_NAME_PASSPHRASE = L"pass";
7777

7878
const wchar_t* PARAM_NAME_MONITOR_ID = L"MonitorID";
79-
static constexpr const wchar_t* PARAM_NAME_CAPTURE_MODE = L"CaptureMode";
8079
static constexpr const wchar_t* PARAM_NAME_CAPTURE_RATE = L"FrameRate";
8180
static constexpr const wchar_t* PARAM_NAME_VIDEO_CODEC = L"VideoCodec";
8281
static constexpr const wchar_t* PARAM_NAME_RESOLUTION = L"Resolution";
@@ -167,7 +166,6 @@ RemoteDesktopServer::RemoteDesktopServer()
167166
SetParamDescription(PARAM_NAME_PASSPHRASE, ParamCommon, L"Specify a passphrase for AES encryption", nullptr);
168167

169168
SetParamDescription(PARAM_NAME_MONITOR_ID, ParamCommon, L"Specify a 0-based index of the monitor to capture video from, default = 0", ParamConverterInt64);
170-
SetParamDescription(PARAM_NAME_CAPTURE_MODE, ParamCommon, L"Specify capture mode: [framerate, present, asap], default = framerate", nullptr);
171169
SetParamDescription(PARAM_NAME_CAPTURE_RATE, ParamCommon, L"Specify capture frame rate for the \"framerate\" capture mode, default = 60", ParamConverterInt64);
172170
SetParamDescription(CAPTURE_FORCE_COPY, ParamCommon, L"Force display capture to make a copy of the captured surface (true, false), default = false", ParamConverterBoolean);
173171

@@ -260,8 +258,9 @@ RemoteDesktopServer::EStatus RemoteDesktopServer::Init(int argc/* = 0*/, const c
260258
else if (InitAudioCapture() != true)
261259
{
262260
AMFTraceError(AMF_FACILITY, L"Failed to create/initialize audio capture - no default audio output?");
263-
}
264-
else if (InitAudioCodec() != true)
261+
} // This is a special case - audio capture may fail if there is no default audio output device, but we can continue without audio
262+
263+
if (InitAudioCodec() != true)
265264
{
266265
AMFTraceError(AMF_FACILITY, L"Failed to create audio codec");
267266
}
@@ -445,116 +444,39 @@ bool RemoteDesktopServer::InitVideoCapture()
445444
AMF_RESULT amfResult = AMF_OK;
446445
static constexpr const int64_t DEFAULT_FRAMERATE = 60;
447446

448-
if (m_VideoCapture == nullptr) // Check for nullptr since capture can be created by the platform-specific derived class, e.g. MS Desktop Duplication
449-
{
450-
amfResult = g_AMFFactory.GetFactory()->CreateComponent(m_Context, AMFDisplayCapture, &m_VideoCapture);
451-
}
447+
int64_t monitorID = 0;
448+
GetParam(PARAM_NAME_MONITOR_ID, monitorID);
449+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MONITOR_INDEX, monitorID);
450+
m_VideoStreamDescriptor.SetSourceID(static_cast<int32_t>(monitorID));
451+
452+
bool forceCopy = false;
453+
GetParam(CAPTURE_FORCE_COPY, forceCopy);
452454

453-
if (amfResult != AMF_OK)
455+
if ((amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_DUPLICATEOUTPUT, forceCopy)) == AMF_OK)
454456
{
455-
AMFTraceError(AMF_FACILITY, L"Failed to create the display capture component, result=%s", amf::AMFGetResultText(amfResult));
457+
AMFTraceInfo(AMF_FACILITY, L"Captured surface will be %s", forceCopy ? L"duplicated" : L"used directly");
456458
}
457459
else
458460
{
459-
int64_t monitorID = 0;
460-
GetParam(PARAM_NAME_MONITOR_ID, monitorID);
461-
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MONITOR_INDEX, monitorID);
462-
m_VideoStreamDescriptor.SetSourceID(static_cast<int32_t>(monitorID));
463-
464-
bool forceCopy = false;
465-
GetParam(CAPTURE_FORCE_COPY, forceCopy);
466-
467-
std::wstring captureMode = CAPTURE_MODE_FRAMERATE;
468-
if (GetParamWString(PARAM_NAME_CAPTURE_MODE, captureMode) == AMF_OK)
469-
{
470-
captureMode = ::toUpper(captureMode);
471-
}
472-
if (captureMode == CAPTURE_MODE_FRAMERATE)
473-
{
474-
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE));
475-
switch (amfResult)
476-
{
477-
case AMF_OK:
478-
{
479-
int64_t frameRate = DEFAULT_FRAMERATE;
480-
GetParam(PARAM_NAME_CAPTURE_RATE, frameRate);
481-
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_FRAMERATE, AMFConstructRate(int32_t(frameRate), 1));
482-
switch (amfResult)
483-
{
484-
case AMF_OK:
485-
AMFTraceInfo(AMF_FACILITY, L"Capture mode is set to \"%s\" at %d fps", CAPTURE_MODE_FRAMERATE, int32_t(frameRate));
486-
m_VideoStreamDescriptor.SetFramerate(static_cast<float>(frameRate));
487-
result = true;
488-
break;
489-
case AMF_NOT_FOUND:
490-
case AMF_ACCESS_DENIED:
491-
AMFTraceWarning(AMF_FACILITY, L"Failed to set video capture frame rate to %d fps", int32_t(frameRate));
492-
result = true;
493-
break;
494-
default:
495-
break;
496-
}
497-
}
498-
break;
499-
case AMF_NOT_FOUND:
500-
case AMF_ACCESS_DENIED:
501-
AMFTraceWarning(AMF_FACILITY, L"Selected video capture method does not support capture at a fixed frame rate, -%s %s ignored", PARAM_NAME_CAPTURE_MODE, CAPTURE_MODE_FRAMERATE);
502-
result = true;
503-
break;
504-
default:
505-
AMFTraceError(AMF_FACILITY, L"Error setting the AMF_DISPLAYCAPTURE_MODE property on the display capture component, result=%s", amf::AMFGetResultText(amfResult));
506-
break;
507-
}
508-
}
509-
else if (captureMode == CAPTURE_MODE_PRESENT)
510-
{
511-
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_WAIT_FOR_PRESENT));
512-
m_VideoStreamDescriptor.SetFramerate(float(DEFAULT_FRAMERATE)); // Set the initial frame rate to 60fps, it will be adjusted automatically in a few seconds to the actual frame rate determined by capture
513-
}
514-
else if (captureMode == CAPTURE_MODE_ASAP)
515-
{
516-
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_GET_CURRENT_SURFACE));
517-
m_VideoStreamDescriptor.SetFramerate(float(DEFAULT_FRAMERATE)); // Set the initial frame rate to 60fps, it will be adjusted automatically in a few seconds to the actual frame rate determined by capture
518-
}
519-
if (result != true)
520-
{
521-
if (amfResult == AMF_OK)
522-
{
523-
AMFTraceInfo(AMF_FACILITY, L"Capture mode is set to %s", captureMode.c_str());
524-
}
525-
else
526-
{
527-
AMFTraceError(AMF_FACILITY, L"Failed to set video capture mode to %s, result=%s", captureMode.c_str(), amf::AMFGetResultText(amfResult));
528-
}
529-
}
461+
AMFTraceWarning(AMF_FACILITY, L"Capture component does not support surface duplication, ignored, result=%s", amf::AMFGetResultText(amfResult));
462+
}
530463

531-
if ((amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_DUPLICATEOUTPUT, forceCopy)) == AMF_OK)
464+
if ((amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_CURRENT_TIME_INTERFACE, m_CurrentTime)) != AMF_OK)
465+
{
466+
AMFTraceError(AMF_FACILITY, L"Failed to set the current time interface on the video capture component, result=%s", amf::AMFGetResultText(amfResult));
467+
}
468+
else
469+
{ // All properties are configured
470+
if ((amfResult = m_VideoCapture->Init(amf::AMF_SURFACE_UNKNOWN, 0, 0)) != AMF_OK)
532471
{
533-
AMFTraceInfo(AMF_FACILITY, L"Captured surface will be %s", forceCopy ? L"duplicated" : L"used directly");
472+
AMFTraceError(AMF_FACILITY, L"Failed to initialize display capture, result=%s", amf::AMFGetResultText(amfResult));
473+
result = false;
534474
}
535475
else
536476
{
537-
AMFTraceWarning(AMF_FACILITY, L"Capture component does not support surface duplication, ignored, result=%s", amf::AMFGetResultText(amfResult));
538-
}
539-
540-
if ((amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_CURRENT_TIME_INTERFACE, m_CurrentTime)) != AMF_OK)
541-
{
542-
AMFTraceError(AMF_FACILITY, L"Failed to set the current time interface on the video capture component, result=%s", amf::AMFGetResultText(amfResult));
543-
}
544-
else
545-
{ // All properties are configured
546-
if ((amfResult = m_VideoCapture->Init(amf::AMF_SURFACE_UNKNOWN, 0, 0)) != AMF_OK)
547-
{
548-
AMFTraceError(AMF_FACILITY, L"Failed to initialize display capture, result=%s", amf::AMFGetResultText(amfResult));
549-
result = false;
550-
}
551-
else
552-
{
553-
AMFTraceInfo(AMF_FACILITY, L"Video capture successfully initialized");
554-
result = true;
555-
}
477+
AMFTraceInfo(AMF_FACILITY, L"Video capture successfully initialized");
478+
result = true;
556479
}
557-
558480
}
559481

560482
return result;
@@ -978,14 +900,8 @@ bool RemoteDesktopServer::InitStreamer()
978900
qosInitParams.maxEncoderQueueDepth = QOS_DEFAULT_MAX_ENCODER_QUEUE_DEPTH;
979901
qosInitParams.maxDecoderQueueDepth = QOS_DEFAULT_MAX_DECODER_QUEUE_DEPTH;
980902

981-
std::wstring captureMode = CAPTURE_MODE_FRAMERATE;
982-
if (GetParamWString(PARAM_NAME_CAPTURE_MODE, captureMode) == AMF_OK)
983-
{
984-
captureMode = ::toUpper(captureMode);
985-
}
986-
987903
qosInitParams.strategy = ssdk::util::QoS::QoSStrategy::ADJUST_NONE;
988-
if (captureMode == CAPTURE_MODE_FRAMERATE)
904+
if (m_CaptureMode == CaptureMode::FRAMERATE)
989905
{
990906
if (enableQoSBitrate == true && enableQoSFramerate == true)
991907
{

samples/RemoteDesktopServer/RemoteDesktopServer.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class RemoteDesktopServer :
7272
SKIP
7373
};
7474

75+
enum class CaptureMode
76+
{
77+
FRAMERATE,
78+
PRESENT,
79+
ASAP
80+
};
81+
7582
protected:
7683
RemoteDesktopServer();
7784
public:
@@ -148,7 +155,7 @@ class RemoteDesktopServer :
148155
ssdk::video::TransmitterAdapter::Ptr m_VideoTransmitterAdapter;
149156
ssdk::video::MonoscopicVideoOutput::Ptr m_VideoOutput;
150157
ssdk::transport_common::VideoStreamDescriptor m_VideoStreamDescriptor;
151-
158+
CaptureMode m_CaptureMode = CaptureMode::FRAMERATE;
152159

153160
amf::AMFComponentPtr m_AudioCapture;
154161
ssdk::audio::AudioEncodeEngine::Ptr m_AudioEncoder;

samples/RemoteDesktopServer/RemoteDesktopServerLinux.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
static constexpr const wchar_t* const AMF_FACILITY = L"RemoteDesktopServerLinux";
5353

5454
static constexpr const wchar_t* PARAM_NAME_INTERACTIVE = L"interactive";
55+
static constexpr const wchar_t* PARAM_NAME_CAPTURE_RATE = L"FrameRate";
56+
57+
static constexpr const wchar_t* CAPTURE_MODE_FRAMERATE = L"FRAMERATE";
58+
5559

5660
// Game controllers max count
5761
static constexpr const int8_t GAME_USER_MAX_COUNT = 1;
@@ -189,7 +193,35 @@ void RemoteDesktopServerLinux::TerminateVulkan()
189193

190194
bool RemoteDesktopServerLinux::InitVideoCapture()
191195
{
192-
return RemoteDesktopServer::InitVideoCapture();
196+
bool result = false;
197+
AMF_RESULT amfResult = AMF_OK;
198+
static constexpr const int64_t DEFAULT_FRAMERATE = 60;
199+
200+
if ((amfResult = g_AMFFactory.GetFactory()->CreateComponent(m_Context, AMFDisplayCapture, &m_VideoCapture)) == AMF_OK)
201+
{
202+
m_CaptureMode = CaptureMode::FRAMERATE;
203+
int64_t frameRate = DEFAULT_FRAMERATE;
204+
GetParam(PARAM_NAME_CAPTURE_RATE, frameRate);
205+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_FRAMERATE, AMFConstructRate(int32_t(frameRate), 1));
206+
switch (amfResult)
207+
{
208+
case AMF_OK:
209+
AMFTraceInfo(AMF_FACILITY, L"Capture mode is set to \"%s\" at %d fps", CAPTURE_MODE_FRAMERATE, int32_t(frameRate));
210+
m_VideoStreamDescriptor.SetFramerate(static_cast<float>(frameRate));
211+
result = RemoteDesktopServer::InitVideoCapture();
212+
break;
213+
case AMF_NOT_FOUND:
214+
case AMF_ACCESS_DENIED:
215+
AMFTraceWarning(AMF_FACILITY, L"Failed to set video capture frame rate to %d fps", int32_t(frameRate));
216+
result = false;
217+
break;
218+
default:
219+
result = false;
220+
break;
221+
}
222+
}
223+
224+
return result;
193225
}
194226

195227
bool RemoteDesktopServerLinux::InitCursorCapture()

samples/RemoteDesktopServer/RemoteDesktopServerLinux.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ class RemoteDesktopServerLinux : public RemoteDesktopServer
5656
void TerminateVulkan();
5757

5858
virtual bool InitVideoCapture() override;
59+
5960
virtual bool InitCursorCapture() override;
61+
6062
virtual bool InitDirectories() override;
63+
6164
virtual bool InitControllers() override;
6265

6366
AMF_RESULT InitCrtcInfo();

samples/RemoteDesktopServer/RemoteDesktopServerWin.cpp

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ static constexpr const wchar_t* const AMF_FACILITY = L"RemoteDesktopServerWin";
5555
static constexpr const wchar_t* PARAM_NAME_INTERACTIVE = L"interactive";
5656
static constexpr const wchar_t* PARAM_NAME_VIDEO_API = L"videoapi";
5757
static constexpr const wchar_t* PARAM_NAME_VIDEO_CAPTURE_TYPE = L"capture";
58+
static constexpr const wchar_t* PARAM_NAME_CAPTURE_MODE = L"CaptureMode";
59+
static constexpr const wchar_t* PARAM_NAME_CAPTURE_RATE = L"FrameRate";
60+
61+
62+
// Values for PARAM_NAME_CAPTURE_MODE
63+
static constexpr const wchar_t* CAPTURE_MODE_FRAMERATE = L"FRAMERATE";
64+
static constexpr const wchar_t* CAPTURE_MODE_PRESENT = L"PRESENT";
65+
static constexpr const wchar_t* CAPTURE_MODE_ASAP = L"ASAP";
66+
5867

5968
// Game controllers max count
6069
static constexpr const int8_t GAME_USER_MAX_COUNT = 4;
@@ -98,6 +107,7 @@ RemoteDesktopServerWin::RemoteDesktopServerWin()
98107
SetParamDescription(PARAM_NAME_INTERACTIVE, ParamCommon, L"Enable interactive mode (true, false), default=true", ParamConverterBoolean);
99108
SetParamDescription(PARAM_NAME_VIDEO_API, ParamCommon, L"Select video API (DX11, DX12), default=DX12", nullptr);
100109
SetParamDescription(PARAM_NAME_VIDEO_CAPTURE_TYPE, ParamCommon, L"Select video capture type (AMD, DD), default=AMD", nullptr);
110+
SetParamDescription(PARAM_NAME_CAPTURE_MODE, ParamCommon, L"Specify capture mode: [framerate, present, asap], default = framerate", nullptr);
101111
}
102112

103113
RemoteDesktopServerWin::~RemoteDesktopServerWin()
@@ -219,6 +229,7 @@ bool RemoteDesktopServerWin::InitVideoCapture()
219229
{
220230
bool result = false;
221231
AMF_RESULT amfResult = AMF_OK;
232+
static constexpr const int64_t DEFAULT_FRAMERATE = 60;
222233

223234
std::wstring captureType = L"AMD";
224235
if (GetParamWString(PARAM_NAME_VIDEO_CAPTURE_TYPE, captureType) == AMF_OK)
@@ -231,12 +242,89 @@ bool RemoteDesktopServerWin::InitVideoCapture()
231242
if ((amfResult = AMFCreateComponentDisplayCapture(m_Context, nullptr, &m_VideoCapture)) != AMF_OK)
232243
{
233244
AMFTraceError(AMF_FACILITY, L"Failed to create Microsoft Desktop Duplication video capture component, result=%s", amf::AMFGetResultText(amfResult));
234-
amfResult = AMF_FAIL;
245+
}
246+
}
247+
else
248+
{
249+
if ((amfResult = g_AMFFactory.GetFactory()->CreateComponent(m_Context, AMFDisplayCapture, &m_VideoCapture)) != AMF_OK)
250+
{
251+
AMFTraceError(AMF_FACILITY, L"Failed to create AMD video capture component, result=%s", amf::AMFGetResultText(amfResult));
235252
}
236253
}
237254
if (amfResult == AMF_OK)
238255
{
239-
result = RemoteDesktopServer::InitVideoCapture();
256+
std::wstring captureMode = CAPTURE_MODE_FRAMERATE;
257+
if (GetParamWString(PARAM_NAME_CAPTURE_MODE, captureMode) == AMF_OK)
258+
{
259+
captureMode = ::toUpper(captureMode);
260+
}
261+
if (captureMode == CAPTURE_MODE_FRAMERATE)
262+
{
263+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE));
264+
switch (amfResult)
265+
{
266+
case AMF_OK:
267+
{
268+
int64_t frameRate = DEFAULT_FRAMERATE;
269+
GetParam(PARAM_NAME_CAPTURE_RATE, frameRate);
270+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_FRAMERATE, AMFConstructRate(int32_t(frameRate), 1));
271+
switch (amfResult)
272+
{
273+
case AMF_OK:
274+
AMFTraceInfo(AMF_FACILITY, L"Capture mode is set to \"%s\" at %d fps", CAPTURE_MODE_FRAMERATE, int32_t(frameRate));
275+
m_VideoStreamDescriptor.SetFramerate(static_cast<float>(frameRate));
276+
result = true;
277+
break;
278+
case AMF_NOT_FOUND:
279+
case AMF_ACCESS_DENIED:
280+
AMFTraceWarning(AMF_FACILITY, L"Failed to set video capture frame rate to %d fps", int32_t(frameRate));
281+
result = true;
282+
break;
283+
default:
284+
break;
285+
}
286+
}
287+
break;
288+
case AMF_NOT_FOUND:
289+
case AMF_ACCESS_DENIED:
290+
AMFTraceWarning(AMF_FACILITY, L"Selected video capture method does not support capture at a fixed frame rate, -%s %s ignored", PARAM_NAME_CAPTURE_MODE, CAPTURE_MODE_FRAMERATE);
291+
result = true;
292+
break;
293+
default:
294+
AMFTraceError(AMF_FACILITY, L"Error setting the AMF_DISPLAYCAPTURE_MODE property on the display capture component, result=%s", amf::AMFGetResultText(amfResult));
295+
break;
296+
}
297+
m_CaptureMode = CaptureMode::FRAMERATE;
298+
}
299+
else if (captureMode == CAPTURE_MODE_PRESENT)
300+
{
301+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_WAIT_FOR_PRESENT));
302+
m_VideoStreamDescriptor.SetFramerate(float(DEFAULT_FRAMERATE)); // Set the initial frame rate to 60fps, it will be adjusted automatically in a few seconds to the actual frame rate determined by capture
303+
m_CaptureMode = CaptureMode::PRESENT;
304+
result = true;
305+
}
306+
else if (captureMode == CAPTURE_MODE_ASAP)
307+
{
308+
amfResult = m_VideoCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM::AMF_DISPLAYCAPTURE_MODE_GET_CURRENT_SURFACE));
309+
m_VideoStreamDescriptor.SetFramerate(float(DEFAULT_FRAMERATE)); // Set the initial frame rate to 60fps, it will be adjusted automatically in a few seconds to the actual frame rate determined by capture
310+
m_CaptureMode = CaptureMode::ASAP;
311+
result = true;
312+
}
313+
if (result != true)
314+
{
315+
if (amfResult == AMF_OK)
316+
{
317+
AMFTraceInfo(AMF_FACILITY, L"Capture mode is set to %s", captureMode.c_str());
318+
}
319+
else
320+
{
321+
AMFTraceError(AMF_FACILITY, L"Failed to set video capture mode to %s, result=%s", captureMode.c_str(), amf::AMFGetResultText(amfResult));
322+
}
323+
}
324+
else
325+
{
326+
result = RemoteDesktopServer::InitVideoCapture();
327+
}
240328
}
241329
return result;
242330
}

0 commit comments

Comments
 (0)