diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn index 6e7e9bcf39..0c427993d4 100644 --- a/webrtc/modules/desktop_capture/BUILD.gn +++ b/webrtc/modules/desktop_capture/BUILD.gn @@ -200,6 +200,8 @@ rtc_static_library("desktop_capture") { "mouse_cursor_monitor.h", "mouse_cursor_monitor_mac.mm", "mouse_cursor_monitor_win.cc", + "resolution_change_detector.cc", + "resolution_change_detector.h", "screen_capture_frame_queue.h", "screen_capturer_helper.cc", "screen_capturer_helper.h", diff --git a/webrtc/modules/desktop_capture/resolution_change_detector.cc b/webrtc/modules/desktop_capture/resolution_change_detector.cc new file mode 100644 index 0000000000..f61a5352fb --- /dev/null +++ b/webrtc/modules/desktop_capture/resolution_change_detector.cc @@ -0,0 +1,29 @@ +/* + * 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/resolution_change_detector.h" + +namespace webrtc { + +bool ResolutionChangeDetector::IsChanged(DesktopSize size) { + if (!initialized_) { + initialized_ = true; + last_size_ = size; + return false; + } + + return !last_size_.equals(size); +} + +void ResolutionChangeDetector::Reset() { + initialized_ = false; +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/resolution_change_detector.h b/webrtc/modules/desktop_capture/resolution_change_detector.h new file mode 100644 index 0000000000..6ccf8a7a17 --- /dev/null +++ b/webrtc/modules/desktop_capture/resolution_change_detector.h @@ -0,0 +1,30 @@ +/* + * 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. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_RESOLUTION_CHANGE_DETECTOR_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_RESOLUTION_CHANGE_DETECTOR_H_ + +#include "webrtc/modules/desktop_capture/desktop_geometry.h" + +namespace webrtc { + +class ResolutionChangeDetector { + public: + bool IsChanged(DesktopSize size); + void Reset(); + + private: + DesktopSize last_size_; + bool initialized_ = false; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_RESOLUTION_CHANGE_DETECTOR_H_ diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc index 975d7e4770..065a6148c0 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc +++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc @@ -13,17 +13,24 @@ #include #include +#include #include "webrtc/base/checks.h" +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" +#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" namespace webrtc { -DxgiDuplicatorController::Context::Context() {} +DxgiDuplicatorController::Context::Context() = default; DxgiDuplicatorController::Context::~Context() { DxgiDuplicatorController::Instance()->Unregister(this); } +void DxgiDuplicatorController::Context::Reset() { + identity_ = 0; +} + // static DxgiDuplicatorController* DxgiDuplicatorController::Instance() { // The static instance won't be deleted to ensure it can be used by other @@ -44,6 +51,11 @@ bool DxgiDuplicatorController::IsSupported() { return Initialize(); } +void DxgiDuplicatorController::Reset() { + rtc::CritScope lock(&lock_); + Deinitialize(); +} + bool DxgiDuplicatorController::RetrieveD3dInfo(D3dInfo* info) { rtc::CritScope lock(&lock_); if (!Initialize()) { @@ -182,6 +194,7 @@ bool DxgiDuplicatorController::DoInitialize() { void DxgiDuplicatorController::Deinitialize() { desktop_rect_ = DesktopRect(); duplicators_.clear(); + resolution_change_detector_.Reset(); } bool DxgiDuplicatorController::ContextExpired( @@ -219,17 +232,34 @@ bool DxgiDuplicatorController::DoDuplicate(Context* context, RTC_DCHECK(target); target->mutable_updated_region()->Clear(); rtc::CritScope lock(&lock_); + if (DoDuplicateUnlocked(context, monitor_id, target)) { + return true; + } + Deinitialize(); + return false; +} + +bool DxgiDuplicatorController::DoDuplicateUnlocked(Context* context, + int monitor_id, + SharedDesktopFrame* target) { if (!Initialize()) { // Cannot initialize COM components now, display mode may be changing. return false; } + if (resolution_change_detector_.IsChanged( + GetScreenRect(kFullDesktopScreenId, std::wstring()).size())) { + // Resolution of entire screen has been changed, which usually means a new + // monitor has been attached or one has been removed. The simplest way is to + // Deinitialize() and returns false to indicate downstream components. + return false; + } + Setup(context); if (monitor_id < 0) { // Capture entire screen. for (size_t i = 0; i < duplicators_.size(); i++) { if (!duplicators_[i].Duplicate(&context->contexts_[i], target)) { - Deinitialize(); return false; } } @@ -248,7 +278,6 @@ bool DxgiDuplicatorController::DoDuplicate(Context* context, target->set_dpi(dpi()); return true; } - Deinitialize(); return false; } } diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h index d13961d0da..7470db9eeb 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h +++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h @@ -19,6 +19,7 @@ #include "webrtc/base/criticalsection.h" #include "webrtc/modules/desktop_capture/desktop_geometry.h" #include "webrtc/modules/desktop_capture/desktop_region.h" +#include "webrtc/modules/desktop_capture/resolution_change_detector.h" #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" #include "webrtc/modules/desktop_capture/win/d3d_device.h" #include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h" @@ -47,6 +48,9 @@ class DxgiDuplicatorController { // destructing. ~Context(); + // Reset current Context, so it will be reinitialized next time. + void Reset(); + private: friend class DxgiDuplicatorController; @@ -87,6 +91,11 @@ class DxgiDuplicatorController { // Detects whether the system supports DXGI based capturer. bool IsSupported(); + // Calls Deinitialize() function with lock. Consumers can call this function + // to force the DxgiDuplicatorController to be reinitialized to avoid an + // expected failure in next Duplicate() call. + void Reset(); + // Returns a copy of D3dInfo composed by last Initialize() function call. bool RetrieveD3dInfo(D3dInfo* info); @@ -167,6 +176,10 @@ class DxgiDuplicatorController { int monitor_id, SharedDesktopFrame* target); + bool DoDuplicateUnlocked(Context* context, + int monitor_id, + SharedDesktopFrame* target); + // This lock must be locked whenever accessing any of the following objects. rtc::CriticalSection lock_; @@ -177,6 +190,7 @@ class DxgiDuplicatorController { DesktopVector dpi_; std::vector duplicators_; D3dInfo d3d_info_; + ResolutionChangeDetector resolution_change_detector_; }; } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc index 9e35b6cdc5..e2b2235352 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc +++ b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc @@ -85,13 +85,10 @@ DxgiOutputDuplicator::~DxgiOutputDuplicator() { bool DxgiOutputDuplicator::Initialize() { if (DuplicateOutput()) { - DesktopSize unrotated_size = - RotateSize(desktop_rect().size(), ReverseRotation(rotation_)); if (desc_.DesktopImageInSystemMemory) { - texture_.reset( - new DxgiTextureMapping(unrotated_size, duplication_.Get())); + texture_.reset(new DxgiTextureMapping(duplication_.Get())); } else { - texture_.reset(new DxgiTextureStaging(unrotated_size, device_)); + texture_.reset(new DxgiTextureStaging(device_)); } return true; } else { diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture.cc b/webrtc/modules/desktop_capture/win/dxgi_texture.cc index 9af8a06cd5..27ccbf6230 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture.cc +++ b/webrtc/modules/desktop_capture/win/dxgi_texture.cc @@ -10,7 +10,15 @@ #include "webrtc/modules/desktop_capture/win/dxgi_texture.h" +#include +#include +#include + +#include "webrtc/base/checks.h" #include "webrtc/modules/desktop_capture/desktop_region.h" +#include "webrtc/system_wrappers/include/logging.h" + +using Microsoft::WRL::ComPtr; namespace webrtc { @@ -29,10 +37,33 @@ class DxgiDesktopFrame : public DesktopFrame { } // namespace -DxgiTexture::DxgiTexture(const DesktopSize& desktop_size) - : desktop_size_(desktop_size) {} +DxgiTexture::DxgiTexture() = default; +DxgiTexture::~DxgiTexture() = default; -DxgiTexture::~DxgiTexture() {} +bool DxgiTexture::CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, + IDXGIResource* resource) { + RTC_DCHECK(resource && frame_info.AccumulatedFrames > 0); + ComPtr texture; + _com_error error = resource->QueryInterface( + __uuidof(ID3D11Texture2D), + reinterpret_cast(texture.GetAddressOf())); + if (error.Error() != S_OK || !texture) { + LOG(LS_ERROR) << "Failed to convert IDXGIResource to ID3D11Texture2D, " + "error " + << error.ErrorMessage() << ", code " << error.Error(); + return false; + } + + D3D11_TEXTURE2D_DESC desc = {0}; + texture->GetDesc(&desc); + desktop_size_.set(desc.Width, desc.Height); + if (resolution_change_detector_.IsChanged(desktop_size_)) { + LOG(LS_ERROR) << "Texture size is not consistent with current DxgiTexture."; + return false; + } + + return CopyFromTexture(frame_info, texture.Get()); +} const DesktopFrame& DxgiTexture::AsDesktopFrame() { if (!frame_) { @@ -46,4 +77,8 @@ bool DxgiTexture::Release() { return DoRelease(); } +DXGI_MAPPED_RECT* DxgiTexture::rect() { + return &rect_; +} + } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture.h b/webrtc/modules/desktop_capture/win/dxgi_texture.h index a4bd237e01..6f3e29b07f 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture.h +++ b/webrtc/modules/desktop_capture/win/dxgi_texture.h @@ -11,12 +11,14 @@ #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_TEXTURE_H_ #define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_TEXTURE_H_ +#include #include #include #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/desktop_geometry.h" +#include "webrtc/modules/desktop_capture/resolution_change_detector.h" namespace webrtc { @@ -27,14 +29,14 @@ class DxgiTexture { public: // Creates a DxgiTexture instance, which represents the |desktop_size| area of // entire screen -- usually a monitor on the system. - explicit DxgiTexture(const DesktopSize& desktop_size); + DxgiTexture(); virtual ~DxgiTexture(); // Copies selected regions of a frame represented by frame_info and resource. // Returns false if anything wrong. - virtual bool CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, - IDXGIResource* resource) = 0; + bool CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, + IDXGIResource* resource); const DesktopSize& desktop_size() const { return desktop_size_; } @@ -54,13 +56,18 @@ class DxgiTexture { const DesktopFrame& AsDesktopFrame(); protected: - DXGI_MAPPED_RECT rect_ = {0}; + DXGI_MAPPED_RECT* rect(); + + virtual bool CopyFromTexture(const DXGI_OUTDUPL_FRAME_INFO& frame_info, + ID3D11Texture2D* texture) = 0; - private: virtual bool DoRelease() = 0; - const DesktopSize desktop_size_; + private: + DXGI_MAPPED_RECT rect_ = {0}; + DesktopSize desktop_size_; std::unique_ptr frame_; + ResolutionChangeDetector resolution_change_detector_; }; } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc b/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc index dbe4948506..f60edc775e 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc +++ b/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc @@ -19,21 +19,21 @@ namespace webrtc { -DxgiTextureMapping::DxgiTextureMapping(const DesktopSize& desktop_size, - IDXGIOutputDuplication* duplication) - : DxgiTexture(desktop_size), duplication_(duplication) { +DxgiTextureMapping::DxgiTextureMapping(IDXGIOutputDuplication* duplication) + : duplication_(duplication) { RTC_DCHECK(duplication_); } DxgiTextureMapping::~DxgiTextureMapping() = default; -bool DxgiTextureMapping::CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, - IDXGIResource* resource) { - RTC_DCHECK(resource && frame_info.AccumulatedFrames > 0); - rect_ = {0}; - _com_error error = duplication_->MapDesktopSurface(&rect_); +bool DxgiTextureMapping::CopyFromTexture( + const DXGI_OUTDUPL_FRAME_INFO& frame_info, + ID3D11Texture2D* texture) { + RTC_DCHECK(texture && frame_info.AccumulatedFrames > 0); + *rect() = {0}; + _com_error error = duplication_->MapDesktopSurface(rect()); if (error.Error() != S_OK) { - rect_ = {0}; + *rect() = {0}; LOG(LS_ERROR) << "Failed to map the IDXGIOutputDuplication to a bitmap, " "error " << error.ErrorMessage() << ", code " << error.Error(); diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.h b/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.h index f6760df6df..0291a90aaa 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.h +++ b/webrtc/modules/desktop_capture/win/dxgi_texture_mapping.h @@ -27,14 +27,14 @@ namespace webrtc { class DxgiTextureMapping : public DxgiTexture { public: // Creates a DxgiTextureMapping instance. Caller must maintain the lifetime - // of input duplication to make sure it outlives this instance. - DxgiTextureMapping(const DesktopSize& desktop_size, - IDXGIOutputDuplication* duplication); + // of input |duplication| to make sure it outlives this instance. + explicit DxgiTextureMapping(IDXGIOutputDuplication* duplication); ~DxgiTextureMapping() override; - bool CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, - IDXGIResource* resource) override; + protected: + bool CopyFromTexture(const DXGI_OUTDUPL_FRAME_INFO& frame_info, + ID3D11Texture2D* texture) override; bool DoRelease() override; diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc index f11a3c1e28..daa910d83a 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc +++ b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc @@ -22,9 +22,8 @@ using Microsoft::WRL::ComPtr; namespace webrtc { -DxgiTextureStaging::DxgiTextureStaging(const DesktopSize& desktop_size, - const D3dDevice& device) - : DxgiTexture(desktop_size), device_(device) {} +DxgiTextureStaging::DxgiTextureStaging(const D3dDevice& device) + : device_(device) {} DxgiTextureStaging::~DxgiTextureStaging() = default; @@ -32,11 +31,6 @@ bool DxgiTextureStaging::InitializeStage(ID3D11Texture2D* texture) { RTC_DCHECK(texture); D3D11_TEXTURE2D_DESC desc = {0}; texture->GetDesc(&desc); - if (static_cast(desc.Width) != desktop_size().width() || - static_cast(desc.Height) != desktop_size().height()) { - LOG(LS_ERROR) << "Texture size is not consistent with current DxgiTexture."; - return false; - } desc.ArraySize = 1; desc.BindFlags = 0; @@ -90,33 +84,24 @@ void DxgiTextureStaging::AssertStageAndSurfaceAreSameObject() { RTC_DCHECK(left.Get() == right.Get()); } -bool DxgiTextureStaging::CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, - IDXGIResource* resource) { - RTC_DCHECK(resource && frame_info.AccumulatedFrames > 0); - ComPtr texture; - _com_error error = resource->QueryInterface( - __uuidof(ID3D11Texture2D), - reinterpret_cast(texture.GetAddressOf())); - if (error.Error() != S_OK || !texture) { - LOG(LS_ERROR) << "Failed to convert IDXGIResource to ID3D11Texture2D, " - "error " - << error.ErrorMessage() << ", code " << error.Error(); - return false; - } +bool DxgiTextureStaging::CopyFromTexture( + const DXGI_OUTDUPL_FRAME_INFO& frame_info, + ID3D11Texture2D* texture) { + RTC_DCHECK(texture && frame_info.AccumulatedFrames > 0); // AcquireNextFrame returns a CPU inaccessible IDXGIResource, so we need to // copy it to a CPU accessible staging ID3D11Texture2D. - if (!InitializeStage(texture.Get())) { + if (!InitializeStage(texture)) { return false; } device_.context()->CopyResource(static_cast(stage_.Get()), - static_cast(texture.Get())); + static_cast(texture)); - rect_ = {0}; - error = surface_->Map(&rect_, DXGI_MAP_READ); + *rect() = {0}; + _com_error error = surface_->Map(rect(), DXGI_MAP_READ); if (error.Error() != S_OK) { - rect_ = {0}; + *rect() = {0}; LOG(LS_ERROR) << "Failed to map the IDXGISurface to a bitmap, error " << error.ErrorMessage() << ", code " << error.Error(); return false; diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h index 3bdf30e215..a7e9b86b48 100644 --- a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h +++ b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h @@ -33,14 +33,15 @@ class DxgiTextureStaging : public DxgiTexture { public: // Creates a DxgiTextureStaging instance. Caller must maintain the lifetime // of input device to make sure it outlives this instance. - DxgiTextureStaging(const DesktopSize& desktop_size, const D3dDevice& device); + explicit DxgiTextureStaging(const D3dDevice& device); ~DxgiTextureStaging() override; - // Copies selected regions of a frame represented by frame_info and resource. + protected: + // Copies selected regions of a frame represented by frame_info and texture. // Returns false if anything wrong. - bool CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info, - IDXGIResource* resource) override; + bool CopyFromTexture(const DXGI_OUTDUPL_FRAME_INFO& frame_info, + ID3D11Texture2D* texture) override; bool DoRelease() override; diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc index c30356e575..f6222d0d1a 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc @@ -10,12 +10,14 @@ #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" +#include #include #include "webrtc/base/checks.h" #include "webrtc/base/logging.h" #include "webrtc/base/timeutils.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" +#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" namespace webrtc { @@ -66,6 +68,26 @@ void ScreenCapturerWinDirectx::CaptureFrame() { int64_t capture_start_time_nanos = rtc::TimeNanos(); + // The dxgi components and APIs do not update the screen resolution without + // a reinitialization. So we use the GetDC() function to retrieve the screen + // resolution to decide whether dxgi components need to be reinitialized. + // If the screen resolution changed, it's very likely the next Duplicate() + // function call will fail because of a missing monitor or the frame size is + // not enough to store the output. So we reinitialize dxgi components in-place + // to avoid a capture failure. + // But there is no guarantee GetDC() function returns the same resolution as + // dxgi APIs, we still rely on dxgi components to return the output frame + // size. + // TODO(zijiehe): Confirm whether IDXGIOutput::GetDesc() and + // IDXGIOutputDuplication::GetDesc() can detect the resolution change without + // reinitialization. + if (resolution_change_detector_.IsChanged( + GetScreenRect(kFullDesktopScreenId, std::wstring()).size())) { + frames_.Reset(); + DxgiDuplicatorController::Instance()->Reset(); + resolution_change_detector_.Reset(); + } + frames_.MoveToNextFrame(); if (!frames_.current_frame()) { std::unique_ptr new_frame; @@ -90,6 +112,7 @@ void ScreenCapturerWinDirectx::CaptureFrame() { &context_, frames_.current_frame())) { // Screen size may be changed, so we need to reset the frames. frames_.Reset(); + resolution_change_detector_.Reset(); callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); return; } @@ -98,6 +121,7 @@ void ScreenCapturerWinDirectx::CaptureFrame() { &context_, current_screen_id_, frames_.current_frame())) { // Screen size may be changed, so we need to reset the frames. frames_.Reset(); + resolution_change_detector_.Reset(); if (current_screen_id_ >= DxgiDuplicatorController::Instance()->ScreenCount()) { // Current monitor has been removed from the system. @@ -133,12 +157,14 @@ bool ScreenCapturerWinDirectx::SelectSource(SourceId id) { // frames only when a Duplicate() function call returns false. if (id == kFullDesktopScreenId) { current_screen_id_ = id; + context_.Reset(); return true; } int screen_count = DxgiDuplicatorController::Instance()->ScreenCount(); if (id >= 0 && id < screen_count) { current_screen_id_ = id; + context_.Reset(); return true; } return false; diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h index 188fddd006..a48bda9954 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h @@ -19,6 +19,7 @@ #include "webrtc/modules/desktop_capture/desktop_capturer.h" #include "webrtc/modules/desktop_capture/desktop_capture_options.h" #include "webrtc/modules/desktop_capture/desktop_region.h" +#include "webrtc/modules/desktop_capture/resolution_change_detector.h" #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" #include "webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h" @@ -61,10 +62,9 @@ class ScreenCapturerWinDirectx : public DesktopCapturer { ScreenCaptureFrameQueue frames_; std::unique_ptr shared_memory_factory_; Callback* callback_ = nullptr; - DxgiDuplicatorController::Context context_; - SourceId current_screen_id_ = kFullDesktopScreenId; + ResolutionChangeDetector resolution_change_detector_; RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWinDirectx); };