Index: webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc |
diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc |
index c17bd1481c7fffa9e09939e3fbcb75f70deaee87..75c3ed11b6e83032648d7db7c0a66e28a1a0cc85 100644 |
--- a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc |
+++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc |
@@ -16,7 +16,9 @@ |
#include <string> |
#include "webrtc/base/checks.h" |
+#include "webrtc/base/logging.h" |
#include "webrtc/base/timeutils.h" |
+#include "webrtc/base/win32.h" |
#include "webrtc/modules/desktop_capture/desktop_capture_types.h" |
#include "webrtc/modules/desktop_capture/win/dxgi_frame.h" |
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" |
@@ -24,6 +26,19 @@ |
namespace webrtc { |
+namespace { |
+ |
+bool IsRunningInSession0() { |
+ DWORD session_id = 0; |
+ if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) { |
+ LOG(LS_WARNING) << "Failed to retrieve current session Id, no priviledge?"; |
+ return true; |
+ } |
+ return session_id == 0; |
+} |
+ |
+} // namespace |
+ |
// static |
DxgiDuplicatorController* DxgiDuplicatorController::Instance() { |
// The static instance won't be deleted to ensure it can be used by other |
@@ -40,17 +55,48 @@ DxgiDuplicatorController::~DxgiDuplicatorController() { |
} |
bool DxgiDuplicatorController::IsSupported() { |
- rtc::CritScope lock(&lock_); |
- return Initialize(); |
+ bool result = false; |
+ { |
+ rtc::CritScope lock(&lock_); |
+ result = Initialize(); |
+ } |
+ |
+ if (result) { |
+ return true; |
+ } |
+ |
+ if (IsRunningInSession0()) { |
+ LOG(LS_WARNING) << "Current binary is running in session 0. DXGI " |
+ "components cannot be initialized. Fallback to use " |
+ "Windows version to decide the support of DirectX " |
+ "capturer. It may be inaccurate."; |
+ return rtc::IsWindows8OrLater(); |
Sergey Ulanov
2017/06/26 23:41:41
In this case DX capturer is effectively unsupporte
Hzj_jie
2017/06/27 04:37:33
A very good point, I have moved this logic into ht
|
+ } |
+ |
+ return false; |
} |
bool DxgiDuplicatorController::RetrieveD3dInfo(D3dInfo* info) { |
- rtc::CritScope lock(&lock_); |
- if (!Initialize()) { |
- return false; |
+ bool result = false; |
+ { |
+ rtc::CritScope lock(&lock_); |
+ result = Initialize(); |
} |
- *info = d3d_info_; |
- return true; |
+ |
+ if (result) { |
+ *info = d3d_info_; |
+ return true; |
+ } |
+ |
+ if (IsRunningInSession0()) { |
+ LOG(LS_WARNING) << "Current binary is running in session 0. Initialization " |
+ "of DXGI components are expected to fail. But " |
+ "retrieving feature level is still supported."; |
+ *info = d3d_info_; |
+ return true; |
+ } |
+ |
+ return false; |
} |
DxgiDuplicatorController::Result |
@@ -104,6 +150,12 @@ DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) { |
} |
if (!Initialize()) { |
+ if (succeeded_duplications_ == 0 && IsRunningInSession0()) { |
+ LOG(LS_WARNING) << "Current binary is running in session 0. DXGI " |
+ "components cannot be initialized."; |
+ return Result::UNSUPPORTED_SESSION; |
+ } |
+ |
// Cannot initialize COM components now, display mode may be changing. |
return Result::INITIALIZATION_FAILED; |
} |
@@ -115,6 +167,7 @@ DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) { |
frame->frame()->mutable_updated_region()->Clear(); |
if (DoDuplicateUnlocked(frame->context(), monitor_id, frame->frame())) { |
+ succeeded_duplications_++; |
return Result::SUCCEEDED; |
} |
if (monitor_id >= ScreenCountUnlocked()) { |
@@ -162,15 +215,11 @@ bool DxgiDuplicatorController::DoInitialize() { |
std::vector<D3dDevice> devices = D3dDevice::EnumDevices(); |
if (devices.empty()) { |
+ LOG(LS_WARNING) << "No D3dDevice found."; |
return false; |
} |
for (size_t i = 0; i < devices.size(); i++) { |
- duplicators_.emplace_back(devices[i]); |
- if (!duplicators_.back().Initialize()) { |
- return false; |
- } |
- |
D3D_FEATURE_LEVEL feature_level = |
devices[i].d3d_device()->GetFeatureLevel(); |
if (d3d_info_.max_feature_level == 0 || |
@@ -182,6 +231,16 @@ bool DxgiDuplicatorController::DoInitialize() { |
d3d_info_.min_feature_level = feature_level; |
} |
+ DxgiAdapterDuplicator duplicator(devices[i]); |
+ if (!duplicator.Initialize()) { |
+ LOG(LS_WARNING) << "Failed to initialize DxgiAdapterDuplicator on " |
+ "adapter " |
+ << i; |
+ continue; |
Sergey Ulanov
2017/06/26 23:41:41
Why do we need to keep trying initialization after
Hzj_jie
2017/06/27 04:37:33
This issue happens when a virtual adapter is insta
|
+ } |
+ RTC_DCHECK(!duplicator.desktop_rect().is_empty()); |
+ duplicators_.push_back(std::move(duplicator)); |
+ |
desktop_rect_.UnionWith(duplicators_.back().desktop_rect()); |
} |
TranslateRect(); |
@@ -194,7 +253,12 @@ bool DxgiDuplicatorController::DoInitialize() { |
} |
identity_++; |
- return true; |
+ |
+ if (duplicators_.empty()) { |
+ LOG(LS_WARNING) << "Cannot initialize any DxgiAdapterDuplicator instance."; |
+ } |
+ |
+ return !duplicators_.empty(); |
} |
void DxgiDuplicatorController::Deinitialize() { |