Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Unified Diff: webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc

Issue 2788863006: Merge ScreenCapturerWinDirectx::frames_ and contexts_ (Closed)
Patch Set: Resolve review comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
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 36e43fbad7e47e44452713d66a04e6c80a25e3c8..9630265c63e8720ee3089b9fccb9f1b873aa05e8 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
@@ -18,7 +18,6 @@
#include "webrtc/base/ptr_util.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 {
@@ -55,97 +54,55 @@ void ScreenCapturerWinDirectx::SetSharedMemoryFactory(
shared_memory_factory_ = std::move(shared_memory_factory);
}
-DesktopSize ScreenCapturerWinDirectx::SelectedDesktopSize() const {
- if (current_screen_id_ == kFullDesktopScreenId) {
- return DxgiDuplicatorController::Instance()->desktop_size();
- }
- return DxgiDuplicatorController::Instance()
- ->ScreenRect(current_screen_id_)
- .size();
-}
-
void ScreenCapturerWinDirectx::CaptureFrame() {
RTC_DCHECK(callback_);
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<DesktopFrame> new_frame;
- if (shared_memory_factory_) {
- new_frame = SharedMemoryDesktopFrame::Create(
- SelectedDesktopSize(), shared_memory_factory_.get());
- } else {
- new_frame.reset(new BasicDesktopFrame(SelectedDesktopSize()));
- }
- if (!new_frame) {
+ frames_.ReplaceCurrentFrame(
+ rtc::MakeUnique<DxgiFrame>(shared_memory_factory_.get()));
+ }
+
+ DxgiDuplicatorController::Result result;
+ if (current_screen_id_ == kFullDesktopScreenId) {
+ result = DxgiDuplicatorController::Instance()->Duplicate(
+ frames_.current_frame());
+ } else {
+ result = DxgiDuplicatorController::Instance()->DuplicateMonitor(
+ frames_.current_frame(), current_screen_id_);
+ }
+
+ using DuplicateResult = DxgiDuplicatorController::Result;
+ switch (result) {
+ case DuplicateResult::FRAME_PREPARE_FAILED: {
LOG(LS_ERROR) << "Failed to allocate a new DesktopFrame.";
// This usually means we do not have enough memory or SharedMemoryFactory
// cannot work correctly.
callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
- return;
+ break;
}
- frames_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(new_frame)));
- }
- contexts_.MoveToNextFrame();
- if (!contexts_.current_frame()) {
- contexts_.ReplaceCurrentFrame(
- rtc::MakeUnique<DxgiDuplicatorController::Context>());
- }
-
- if (current_screen_id_ == kFullDesktopScreenId) {
- if (!DxgiDuplicatorController::Instance()->Duplicate(
- contexts_.current_frame(), frames_.current_frame())) {
- // Screen size may be changed, so we need to reset the frames.
- frames_.Reset();
- resolution_change_detector_.Reset();
+ case DuplicateResult::INVALID_MONITOR_ID: {
+ callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
+ break;
+ }
+ case DuplicateResult::INITIALIZATION_FAILED:
+ case DuplicateResult::DUPLICATION_FAILED: {
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
- return;
+ break;
}
- } else {
- if (!DxgiDuplicatorController::Instance()->DuplicateMonitor(
- contexts_.current_frame(), 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.
- callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
- } else {
- callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
- }
- return;
+ case DuplicateResult::SUCCEEDED: {
+ std::unique_ptr<DesktopFrame> frame =
+ frames_.current_frame()->frame()->Share();
+ frame->set_capture_time_ms(
+ (rtc::TimeNanos() - capture_start_time_nanos) /
+ rtc::kNumNanosecsPerMillisec);
+ frame->set_capturer_id(DesktopCapturerId::kScreenCapturerWinDirectx);
+ callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
+ break;
}
}
-
- std::unique_ptr<DesktopFrame> result = frames_.current_frame()->Share();
- result->set_capture_time_ms(
- (rtc::TimeNanos() - capture_start_time_nanos) /
- rtc::kNumNanosecsPerMillisec);
- result->set_capturer_id(DesktopCapturerId::kScreenCapturerWinDirectx);
- callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
}
bool ScreenCapturerWinDirectx::GetSourceList(SourceList* sources) {
@@ -161,18 +118,14 @@ bool ScreenCapturerWinDirectx::SelectSource(SourceId id) {
return true;
}
- // Changing target screen may or may not impact frame size. So resetting
- // frames only when a Duplicate() function call returns false.
if (id == kFullDesktopScreenId) {
current_screen_id_ = id;
- contexts_.Reset();
return true;
}
int screen_count = DxgiDuplicatorController::Instance()->ScreenCount();
if (id >= 0 && id < screen_count) {
current_screen_id_ = id;
- contexts_.Reset();
return true;
}
return false;
« no previous file with comments | « webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698