Output DeviceName from various windows ScreenCapturer related implementations

Both DXGI_OUTPUT_DESC and DISPLAY_DEVICE contain the DeviceName, which may be
able to map a DirectX screen id with the GDI screen id.
So this change exports the field from both DirectX and GDI implementations.

BUG=webrtc:7950

Review-Url: https://codereview.webrtc.org/2971393002
Cr-Commit-Position: refs/heads/master@{#19010}
This commit is contained in:
zijiehe 2017-07-13 16:05:24 -07:00 committed by Commit Bot
parent 8110beda7f
commit 4ff4208c21
10 changed files with 97 additions and 4 deletions

View File

@ -88,6 +88,7 @@ if (rtc_include_tests) {
"win/cursor_unittest.cc",
"win/cursor_unittest_resources.h",
"win/cursor_unittest_resources.rc",
"win/screen_capture_utils_unittest.cc",
]
deps = [
":desktop_capture",

View File

@ -146,6 +146,11 @@ DesktopRect DxgiAdapterDuplicator::ScreenRect(int id) const {
return duplicators_[id].desktop_rect();
}
const std::string& DxgiAdapterDuplicator::GetDeviceName(int id) const {
RTC_DCHECK(id >= 0 && id < static_cast<int>(duplicators_.size()));
return duplicators_[id].device_name();
}
int DxgiAdapterDuplicator::screen_count() const {
return static_cast<int>(duplicators_.size());
}

View File

@ -59,6 +59,10 @@ class DxgiAdapterDuplicator {
// should be between [0, screen_count()).
DesktopRect ScreenRect(int id) const;
// Returns the device name of one screen owned by this DxgiAdapterDuplicator
// in utf8 encoding. |id| should be between [0, screen_count()).
const std::string& GetDeviceName(int id) const;
// Returns the count of screens owned by this DxgiAdapterDuplicator. These
// screens can be retrieved by an interger in the range of
// [0, screen_count()).

View File

@ -114,6 +114,16 @@ int DxgiDuplicatorController::ScreenCount() {
return 0;
}
bool DxgiDuplicatorController::GetDeviceNames(
std::vector<std::string>* output) {
rtc::CritScope lock(&lock_);
if (Initialize()) {
GetDeviceNamesUnlocked(output);
return true;
}
return false;
}
DxgiDuplicatorController::Result
DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) {
RTC_DCHECK(frame);
@ -370,6 +380,16 @@ int DxgiDuplicatorController::ScreenCountUnlocked() const {
return result;
}
void DxgiDuplicatorController::GetDeviceNamesUnlocked(
std::vector<std::string>* output) const {
RTC_DCHECK(output);
for (auto& duplicator : duplicators_) {
for (int i = 0; i < duplicator.screen_count(); i++) {
output->push_back(duplicator.GetDeviceName(i));
}
}
}
DesktopSize DxgiDuplicatorController::SelectedDesktopSize(
int monitor_id) const {
if (monitor_id < 0) {

View File

@ -14,6 +14,7 @@
#include <D3DCommon.h>
#include <atomic>
#include <string>
#include <vector>
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
@ -101,6 +102,12 @@ class DxgiDuplicatorController {
// support DXGI based capturer, this function returns 0.
int ScreenCount();
// Returns the device names of all screens on the system in utf8 encoding.
// These screens can be retrieved by an integer in the range of
// [0, output->size()). If system does not support DXGI based capturer, this
// function returns false.
bool GetDeviceNames(std::vector<std::string>* output);
private:
// DxgiFrameContext calls private Unregister(Context*) function in Reset().
friend void DxgiFrameContext::Reset();
@ -182,6 +189,8 @@ class DxgiDuplicatorController {
int ScreenCountUnlocked() const;
void GetDeviceNamesUnlocked(std::vector<std::string>* output) const;
// Returns the desktop size of the selected screen |monitor_id|. Setting
// |monitor_id| < 0 to return the entire screen size.
DesktopSize SelectedDesktopSize(int monitor_id) const;

View File

@ -23,6 +23,7 @@
#include "webrtc/modules/desktop_capture/win/dxgi_texture_staging.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/win32.h"
namespace webrtc {
@ -64,6 +65,7 @@ DxgiOutputDuplicator::DxgiOutputDuplicator(const D3dDevice& device,
const DXGI_OUTPUT_DESC& desc)
: device_(device),
output_(output),
device_name_(rtc::ToUtf8(desc.DeviceName)),
desktop_rect_(RECTToDesktopRect(desc.DesktopCoordinates)) {
RTC_DCHECK(output_);
RTC_DCHECK(!desktop_rect_.is_empty());

View File

@ -17,6 +17,7 @@
#include <DXGI1_2.h>
#include <memory>
#include <string>
#include <vector>
#include "webrtc/modules/desktop_capture/desktop_frame_rotation.h"
@ -68,6 +69,9 @@ class DxgiOutputDuplicator {
// Returns the desktop rect covered by this DxgiOutputDuplicator.
DesktopRect desktop_rect() const { return desktop_rect_; }
// Returns the device name from DXGI_OUTPUT_DESC in utf8 encoding.
const std::string& device_name() const { return device_name_; }
void Setup(Context* context);
void Unregister(const Context* const context);
@ -112,6 +116,7 @@ class DxgiOutputDuplicator {
const D3dDevice device_;
const Microsoft::WRL::ComPtr<IDXGIOutput1> output_;
const std::string device_name_;
DesktopRect desktop_rect_;
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> duplication_;
DXGI_OUTDUPL_DESC desc_;

View File

@ -13,11 +13,16 @@
#include <windows.h>
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/win32.h"
namespace webrtc {
bool GetScreenList(DesktopCapturer::SourceList* screens) {
RTC_DCHECK(screens->size() == 0);
bool GetScreenList(DesktopCapturer::SourceList* screens,
std::vector<std::string>* device_names /* = nullptr */) {
RTC_DCHECK_EQ(screens->size(), 0U);
if (device_names) {
RTC_DCHECK_EQ(device_names->size(), 0U);
}
BOOL enum_result = TRUE;
for (int device_index = 0;; ++device_index) {
@ -34,6 +39,9 @@ bool GetScreenList(DesktopCapturer::SourceList* screens) {
continue;
screens->push_back({device_index, std::string()});
if (device_names) {
device_names->push_back(rtc::ToUtf8(device.DeviceName));
}
}
return true;
}

View File

@ -11,13 +11,20 @@
#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURE_UTILS_H_
#define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURE_UTILS_H_
#include <vector>
#include <string>
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
namespace webrtc {
// Output the list of active screens into |screens|. Returns true if succeeded,
// or false if it fails to enumerate the display devices.
bool GetScreenList(DesktopCapturer::SourceList* screens);
// 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
// |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);
// Returns true if |screen| is a valid screen. The screen device key is
// returned through |device_key| if the screen is valid. The device key can be

View File

@ -0,0 +1,32 @@
/*
* 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_capture_utils.h"
#include <vector>
#include <string>
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
TEST(ScreenCaptureUtilsTest, GetScreenList) {
DesktopCapturer::SourceList screens;
std::vector<std::string> device_names;
GetScreenList(&screens);
screens.clear();
GetScreenList(&screens, &device_names);
ASSERT_EQ(screens.size(), device_names.size());
}
} // namespace webrtc