| 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_;
|
|
|