Mapping screen id from DirectX capturer to GDI capturer
This change ensures DirectX capturer to return the same ScreenId as GDI capturer for each monitor. So MouseCursoeMonitor can work correctly with the DirectX capturer. This is a temporary fix of webrtc:7950. Bug: webrtc:7950 Change-Id: Icd3f40556701811c21c773a39260a74db43979f3 Reviewed-on: https://chromium-review.googlesource.com/571101 Commit-Queue: Zijie He <zijiehe@chromium.org> Reviewed-by: Sergey Ulanov <sergeyu@chromium.org> Cr-Commit-Position: refs/heads/master@{#19079}
This commit is contained in:
parent
8d2c235b75
commit
3e45cb577e
@ -89,6 +89,7 @@ if (rtc_include_tests) {
|
||||
"win/cursor_unittest_resources.h",
|
||||
"win/cursor_unittest_resources.rc",
|
||||
"win/screen_capture_utils_unittest.cc",
|
||||
"win/screen_capturer_win_directx_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
":desktop_capture",
|
||||
|
||||
@ -12,6 +12,10 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
#include "webrtc/rtc_base/checks.h"
|
||||
#include "webrtc/rtc_base/win32.h"
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ namespace webrtc {
|
||||
// Output the list of active screens into |screens|. Returns true if succeeded,
|
||||
// or false if it fails to enumerate the display devices. If the |device_names|
|
||||
// is provided, it will be filled with the DISPLAY_DEVICE.DeviceName in UTF-8
|
||||
// encoding. Once this function returns true, consumers can always assume that
|
||||
// encoding. If this function returns true, consumers can always assume that
|
||||
// |screens|[i] and |device_names|[i] indicate the same monitor on the system.
|
||||
bool GetScreenList(DesktopCapturer::SourceList* screens,
|
||||
std::vector<std::string>* device_names = nullptr);
|
||||
|
||||
@ -22,9 +22,9 @@ TEST(ScreenCaptureUtilsTest, GetScreenList) {
|
||||
DesktopCapturer::SourceList screens;
|
||||
std::vector<std::string> device_names;
|
||||
|
||||
GetScreenList(&screens);
|
||||
ASSERT_TRUE(GetScreenList(&screens));
|
||||
screens.clear();
|
||||
GetScreenList(&screens, &device_names);
|
||||
ASSERT_TRUE(GetScreenList(&screens, &device_names));
|
||||
|
||||
ASSERT_EQ(screens.size(), device_names.size());
|
||||
}
|
||||
|
||||
@ -10,10 +10,13 @@
|
||||
|
||||
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
|
||||
#include "webrtc/rtc_base/checks.h"
|
||||
#include "webrtc/rtc_base/logging.h"
|
||||
#include "webrtc/rtc_base/ptr_util.h"
|
||||
@ -41,6 +44,60 @@ bool ScreenCapturerWinDirectx::IsCurrentSessionSupported() {
|
||||
return DxgiDuplicatorController::IsCurrentSessionSupported();
|
||||
}
|
||||
|
||||
// static
|
||||
bool ScreenCapturerWinDirectx::GetScreenListFromDeviceNames(
|
||||
const std::vector<std::string>& device_names,
|
||||
DesktopCapturer::SourceList* screens) {
|
||||
RTC_DCHECK(screens->empty());
|
||||
|
||||
DesktopCapturer::SourceList gdi_screens;
|
||||
std::vector<std::string> gdi_names;
|
||||
if (!GetScreenList(&gdi_screens, &gdi_names)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RTC_DCHECK_EQ(gdi_screens.size(), gdi_names.size());
|
||||
|
||||
ScreenId max_screen_id = -1;
|
||||
for (const DesktopCapturer::Source& screen : gdi_screens) {
|
||||
max_screen_id = std::max(max_screen_id, screen.id);
|
||||
}
|
||||
|
||||
for (const auto& device_name : device_names) {
|
||||
const auto it = std::find(
|
||||
gdi_names.begin(), gdi_names.end(), device_name);
|
||||
if (it == gdi_names.end()) {
|
||||
// devices_names[i] has not been found in gdi_names, so use max_screen_id.
|
||||
max_screen_id++;
|
||||
screens->push_back({ max_screen_id });
|
||||
} else {
|
||||
screens->push_back({ gdi_screens[it - gdi_names.begin()] });
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
int ScreenCapturerWinDirectx::GetIndexFromScreenId(
|
||||
ScreenId id,
|
||||
const std::vector<std::string>& device_names) {
|
||||
DesktopCapturer::SourceList screens;
|
||||
if (!GetScreenListFromDeviceNames(device_names, &screens)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
RTC_DCHECK_EQ(device_names.size(), screens.size());
|
||||
|
||||
for (size_t i = 0; i < screens.size(); i++) {
|
||||
if (screens[i].id == id) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScreenCapturerWinDirectx::ScreenCapturerWinDirectx()
|
||||
: controller_(DxgiDuplicatorController::Instance()) {}
|
||||
|
||||
@ -115,29 +172,33 @@ void ScreenCapturerWinDirectx::CaptureFrame() {
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinDirectx::GetSourceList(SourceList* sources) {
|
||||
int screen_count = controller_->ScreenCount();
|
||||
for (int i = 0; i < screen_count; i++) {
|
||||
sources->push_back({i});
|
||||
std::vector<std::string> device_names;
|
||||
if (!controller_->GetDeviceNames(&device_names)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return GetScreenListFromDeviceNames(device_names, sources);
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinDirectx::SelectSource(SourceId id) {
|
||||
if (id == current_screen_id_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == kFullDesktopScreenId) {
|
||||
current_screen_id_ = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
int screen_count = controller_->ScreenCount();
|
||||
if (id >= 0 && id < screen_count) {
|
||||
current_screen_id_ = id;
|
||||
return true;
|
||||
std::vector<std::string> device_names;
|
||||
if (!controller_->GetDeviceNames(&device_names)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
int index;
|
||||
index = GetIndexFromScreenId(id, device_names);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
current_screen_id_ = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -51,6 +51,23 @@ class ScreenCapturerWinDirectx : public DesktopCapturer {
|
||||
// always try IsSupported() function.
|
||||
static bool IsCurrentSessionSupported();
|
||||
|
||||
// Maps |device_names| with the result from GetScreenList() and creates a new
|
||||
// SourceList to include only the ones in |device_names|. If this function
|
||||
// returns true, consumers can always assume |device_names|.size() equals to
|
||||
// |screens|->size(), meanwhile |device_names|[i] and |screens|[i] indicate
|
||||
// the same monitor on the system.
|
||||
// Public for test only.
|
||||
static bool GetScreenListFromDeviceNames(
|
||||
const std::vector<std::string>& device_names,
|
||||
DesktopCapturer::SourceList* screens);
|
||||
|
||||
// Maps |id| with the result from GetScreenListFromDeviceNames() and returns
|
||||
// the index of the entity in |device_names|. This function returns -1 if |id|
|
||||
// cannot be found.
|
||||
// Public for test only.
|
||||
static int GetIndexFromScreenId(ScreenId id,
|
||||
const std::vector<std::string>& device_names);
|
||||
|
||||
explicit ScreenCapturerWinDirectx();
|
||||
|
||||
~ScreenCapturerWinDirectx() override;
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
#include "webrtc/test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// This test cannot ensure GetScreenListFromDeviceNames() won't reorder the
|
||||
// devices in its output, since the device name is missing.
|
||||
TEST(ScreenCaptureUtilsTest, GetScreenListFromDeviceNamesAndGetIndex) {
|
||||
const std::vector<std::string> device_names = {
|
||||
"\\\\.\\DISPLAY0",
|
||||
"\\\\.\\DISPLAY1",
|
||||
"\\\\.\\DISPLAY2",
|
||||
};
|
||||
DesktopCapturer::SourceList screens;
|
||||
ASSERT_TRUE(ScreenCapturerWinDirectx::GetScreenListFromDeviceNames(
|
||||
device_names, &screens));
|
||||
ASSERT_EQ(device_names.size(), screens.size());
|
||||
|
||||
for (size_t i = 0; i < screens.size(); i++) {
|
||||
ASSERT_EQ(ScreenCapturerWinDirectx::GetIndexFromScreenId(
|
||||
screens[i].id, device_names),
|
||||
static_cast<int>(i));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user