Merge ScreenCapturerWinDirectx::frames_ and contexts_
The key change of this CL is to merge ScreenCapturerWinDirectx::frames_ and
contexts_ into a new DxgiFrame class. So consumers of DxgiDuplicateController
does not need to maintain two objects. DxgiDuplicateController::Duplicate*()
functions are also updated to accept DxgiFrame parameter instead of
SharedDesktopFrame + Context. The advantages of this change are,
1. Once the screen resolution changes or an existing monitor has been removed,
DxgiFrame can automatically reset the frame without needing to return a capture
failure.
2. Remove public APIs of DxgiDuplicatorController. Some public APIs are not
needed anymore, i.e. consumers of DxgiDuplicatorController do not need to take
care about these internal states anymore. It also helps to remove several lock
acquiements.
3. Reduce the complexity of ScreenCapturerWinDirectx.
But the disadvantage is, instead of a boolean value,
DxgiDuplicateController::Duplicate*() now return an enumeration. Clients need to
use the enumeration to decide whether the error can be recovered or not.
This change also removes a duplicating logic in ScreenCapturerWinDirectx. i.e.
ResolutionChangeDetector, DxgiDuplicateController now takes care of the screen
resolution changes.
I have verified the scenarios with and without SharedMemoryFactory, also the
Desktop capture API example. So far no regression is detected.
BUG=704205
Review-Url: https://codereview.webrtc.org/2788863006
Cr-Original-Commit-Position: refs/heads/master@{#17795}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: cf5753df778c10ec1034076d1f315fd27fad183d
diff --git a/modules/desktop_capture/win/dxgi_frame.cc b/modules/desktop_capture/win/dxgi_frame.cc
new file mode 100644
index 0000000..0ba678d
--- /dev/null
+++ b/modules/desktop_capture/win/dxgi_frame.cc
@@ -0,0 +1,66 @@
+/*
+ * 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/dxgi_frame.h"
+
+#include <utility>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/desktop_capture/desktop_frame.h"
+#include "webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h"
+
+namespace webrtc {
+
+DxgiFrame::DxgiFrame(SharedMemoryFactory* factory)
+ : factory_(factory) {}
+
+DxgiFrame::~DxgiFrame() = default;
+
+bool DxgiFrame::Prepare(DesktopSize size, DesktopCapturer::SourceId source_id) {
+ if (source_id != source_id_) {
+ // Once the source has been changed, the entire source should be copied.
+ source_id_ = source_id;
+ context_.Reset();
+ }
+
+ if (resolution_change_detector_.IsChanged(size)) {
+ // Once the output size changed, recreate the SharedDesktopFrame.
+ frame_.reset();
+ resolution_change_detector_.Reset();
+ }
+
+ if (!frame_) {
+ std::unique_ptr<DesktopFrame> frame;
+ if (factory_) {
+ frame = SharedMemoryDesktopFrame::Create(size, factory_);
+ } else {
+ frame.reset(new BasicDesktopFrame(size));
+ }
+ if (!frame) {
+ return false;
+ }
+
+ frame_ = SharedDesktopFrame::Wrap(std::move(frame));
+ }
+
+ return !!frame_;
+}
+
+SharedDesktopFrame* DxgiFrame::frame() const {
+ RTC_DCHECK(frame_);
+ return frame_.get();
+}
+
+DxgiFrame::Context* DxgiFrame::context() {
+ RTC_DCHECK(frame_);
+ return &context_;
+}
+
+} // namespace webrtc