Index: webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h |
diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h |
index 310eff02c99123ee0b851b37d79f3812c39e6d3d..364690bcb933ed667038993210cb4943e6ad4cc7 100644 |
--- a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h |
+++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h |
@@ -18,11 +18,12 @@ |
#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" |
+#include "webrtc/modules/desktop_capture/win/dxgi_context.h" |
+#include "webrtc/modules/desktop_capture/win/dxgi_frame.h" |
namespace webrtc { |
@@ -39,29 +40,7 @@ namespace webrtc { |
// but according to hardware performance, this time may vary.) |
class DxgiDuplicatorController { |
public: |
- // A context to store the status of a single consumer of |
- // DxgiDuplicatorController. |
- class Context { |
- public: |
- Context(); |
- // Unregister this Context instance from all Dxgi duplicators during |
- // destructing. |
- ~Context(); |
- |
- // Reset current Context, so it will be reinitialized next time. |
- void Reset(); |
- |
- private: |
- friend class DxgiDuplicatorController; |
- |
- // A Context will have an exactly same |identity_| as |
- // DxgiDuplicatorController, to ensure it has been correctly setted up after |
- // each DxgiDuplicatorController::Initialize(). |
- int identity_ = 0; |
- |
- // Child DxgiAdapterDuplicator::Context belongs to this Context. |
- std::vector<DxgiAdapterDuplicator::Context> contexts_; |
- }; |
+ using Context = DxgiFrameContext; |
// A collection of D3d information we are interested on, which may impact |
// capturer performance or reliability. |
@@ -78,87 +57,80 @@ class DxgiDuplicatorController { |
// version. |
}; |
+ enum class Result { |
+ SUCCEEDED, |
+ FRAME_PREPARE_FAILED, |
+ INITIALIZATION_FAILED, |
+ DUPLICATION_FAILED, |
+ INVALID_MONITOR_ID, |
+ }; |
+ |
// Returns the singleton instance of DxgiDuplicatorController. |
static DxgiDuplicatorController* Instance(); |
// Destructs current instance. We need to make sure COM components and their |
- // containers are destructed in correct order. |
+ // containers are destructed in correct order. This function calls |
+ // Deinitialize() to do the real work. |
~DxgiDuplicatorController(); |
- // All the following functions implicitly call Initialize() function if |
- // current instance has not been initialized. |
+ // All the following public functions implicitly call Initialize() function. |
// 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); |
- // Captures current screen and writes into target. Since we are using double |
- // buffering, |last_frame|.updated_region() is used to represent the not |
- // updated regions in current |target| frame, which should also be copied this |
- // time. |
+ // Captures current screen and writes into |frame|. |
// TODO(zijiehe): Windows cannot guarantee the frames returned by each |
// IDXGIOutputDuplication are synchronized. But we are using a totally |
// different threading model than the way Windows suggested, it's hard to |
// synchronize them manually. We should find a way to do it. |
- bool Duplicate(Context* context, SharedDesktopFrame* target); |
+ Result Duplicate(DxgiFrame* frame); |
// Captures one monitor and writes into target. |monitor_id| should >= 0. If |
// |monitor_id| is greater than the total screen count of all the Duplicators, |
// this function returns false. |
- bool DuplicateMonitor(Context* context, |
- int monitor_id, |
- SharedDesktopFrame* target); |
+ Result DuplicateMonitor(DxgiFrame* frame, int monitor_id); |
// Returns dpi of current system. Returns an empty DesktopVector if system |
// does not support DXGI based capturer. |
DesktopVector dpi(); |
- // Returns entire desktop size. Returns an empty DesktopRect if system does |
- // not support DXGI based capturer. |
- DesktopRect desktop_rect(); |
- |
- // Returns a DesktopSize to cover entire desktop_rect. This may be different |
- // than desktop_rect().size(), since top-left screen does not need to start |
- // from (0, 0). |
- DesktopSize desktop_size(); |
- |
- // Returns the size of one screen. |monitor_id| should be >= 0. If system does |
- // not support DXGI based capturer, or |monitor_id| is greater than the total |
- // screen count of all the Duplicators, this function returns an empty |
- // DesktopRect. |
- DesktopRect ScreenRect(int id); |
- |
// Returns the count of screens on the system. These screens can be retrieved |
// by an integer in the range of [0, ScreenCount()). If system does not |
// support DXGI based capturer, this function returns 0. |
int ScreenCount(); |
private: |
- // Context calls private Unregister(Context*) function during |
+ // DxgiFrameContext calls private Unregister(Context*) function during |
// destructing. |
- friend class Context; |
+ friend DxgiFrameContext::~DxgiFrameContext(); |
// A private constructor to ensure consumers to use |
// DxgiDuplicatorController::Instance(). |
DxgiDuplicatorController(); |
+ // Does the real duplication work. Setting |monitor_id| < 0 to capture entire |
+ // screen. This function calls Initialize(). And if the duplication failed, |
+ // this function calls Deinitialize() to ensure the Dxgi components can be |
+ // reinitialized next time. |
+ Result DoDuplicate(DxgiFrame* frame, int monitor_id); |
+ |
// Unregisters Context from this instance and all DxgiAdapterDuplicator(s) |
// it owns. |
void Unregister(const Context* const context); |
- // All functions below should be called in |lock_| locked scope. |
+ // All functions below should be called in |lock_| locked scope and should be |
+ // after a successful Initialize(). |
- // If current instance has not been initialized, executes DoInitialize |
+ // If current instance has not been initialized, executes DoInitialize() |
// function, and returns initialize result. Otherwise directly returns true. |
+ // This function may calls Deinitialize() if initialization failed. |
bool Initialize(); |
+ // Does the real initialization work, this function should only be called in |
+ // Initialize(). |
bool DoInitialize(); |
// Clears all COM components referred by this instance. So next Duplicate() |
@@ -171,11 +143,6 @@ class DxgiDuplicatorController { |
// Updates Context if needed. |
void Setup(Context* context); |
- // Does the real duplication work. |monitor_id < 0| to capture entire screen. |
- bool DoDuplicate(Context* context, |
- int monitor_id, |
- SharedDesktopFrame* target); |
- |
bool DoDuplicateUnlocked(Context* context, |
int monitor_id, |
SharedDesktopFrame* target); |
@@ -191,7 +158,21 @@ class DxgiDuplicatorController { |
// The minimum GetNumFramesCaptured() returned by |duplicators_|. |
int64_t GetNumFramesCaptured() const; |
- int ScreenCountUnlocked(); |
+ // Returns a DesktopSize to cover entire desktop_rect. This may be different |
+ // than desktop_rect().size(), since top-left of the screen does not need to |
+ // be started from (0, 0). |
+ DesktopSize desktop_size() const; |
+ |
+ // Returns the size of one screen. |id| should be >= 0. If system does not |
+ // support DXGI based capturer, or |id| is greater than the total screen count |
+ // of all the Duplicators, this function returns an empty DesktopRect. |
+ DesktopRect ScreenRect(int id) const; |
+ |
+ int ScreenCountUnlocked() 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; |
// Retries DoDuplicateAll() for several times until GetNumFramesCaptured() is |
// large enough. Returns false if DoDuplicateAll() returns false, or |
@@ -203,8 +184,8 @@ class DxgiDuplicatorController { |
// This lock must be locked whenever accessing any of the following objects. |
rtc::CriticalSection lock_; |
- // A self-incremented integer to compare with the one in Context, to |
- // ensure a Context has been initialized after DxgiDuplicatorController. |
+ // A self-incremented integer to compare with the one in Context. It ensures |
+ // a Context instance is always initialized after DxgiDuplicatorController. |
int identity_ = 0; |
DesktopRect desktop_rect_; |
DesktopVector dpi_; |