| Index: webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h
|
| diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h b/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..386cdcef80f37ff7a5e8a4a7dc4033f178b5099a
|
| --- /dev/null
|
| +++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h
|
| @@ -0,0 +1,136 @@
|
| +/*
|
| + * Copyright (c) 2016 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 MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_
|
| +#define MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_
|
| +
|
| +#include <vector>
|
| +
|
| +#include "webrtc/base/criticalsection.h"
|
| +#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
| +#include "webrtc/modules/desktop_capture/desktop_geometry.h"
|
| +#include "webrtc/modules/desktop_capture/desktop_region.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"
|
| +
|
| +namespace webrtc {
|
| +
|
| +// A container for all the objects we need to call Windows DirectX based capture
|
| +// APIs. Note, one application can only have one IDXGIOutputDuplication instance
|
| +// per output, so this class should be singleton.
|
| +//
|
| +// Consumers should create a DxgiContext and keep it through consumer's
|
| +// lifetime. Calls Prepare function with the DxgiContext before each Duplicate
|
| +// function calls. If a previous Prepare function call returns true, but a later
|
| +// one returns false, this usually means the display mode is changing. Consumers
|
| +// should retry after a while. (Typically 50 milliseconds, but according to
|
| +// hardware performance, this time may be various.)
|
| +class DxgiDuplicatorContainer {
|
| + public:
|
| + // Creates or retrieves the singleton instance of DxgiDuplicatorContainer.
|
| + static DxgiDuplicatorContainer* Instance();
|
| +
|
| + // Destructs current instance. We need to make sure COM components and their
|
| + // containers are destructed in correct order.
|
| + ~DxgiDuplicatorContainer();
|
| +
|
| + // Initializes all the components and updates |context|. This function equals
|
| + // to call Prepare() and Setup(DxgiContext*) sequentially.
|
| + bool Prepare(DxgiContext* context);
|
| +
|
| + // Initializes all the components. Returns false if system does not support
|
| + // DirectX based capture, or system resource is not enough to support to
|
| + // capture all monitors. By default, only four applications can capture the
|
| + // screen with DirectX based capture simultaneously. Returns true if this
|
| + // instance has been initialized already.
|
| + bool Prepare();
|
| +
|
| + // 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.
|
| + // 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. But we should find a way to do it.
|
| + bool Duplicate(DxgiContext* context,
|
| + DesktopFrame* target,
|
| + const DesktopFrame* last_frame);
|
| +
|
| + // Captures one screen and writes into target. If id < 0 or greater than
|
| + // the total screen count of all the Duplicators, this function returns false.
|
| + bool Duplicate(DxgiContext* context,
|
| + int id,
|
| + DesktopFrame* target,
|
| + const DesktopFrame* last_frame);
|
| +
|
| + DesktopVector dpi() const {
|
| + return dpi_;
|
| + }
|
| +
|
| + // Returns entire desktop size.
|
| + DesktopRect desktop_rect() const {
|
| + return 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() const {
|
| + return DesktopSize(desktop_rect_.right(), desktop_rect_.bottom());
|
| + }
|
| +
|
| + // Returns the size of one screen. If id < 0 or greater than the total screen
|
| + // count of all the Duplicators, this function returns an empty DesktopRect.
|
| + DesktopRect ScreenRect(int id) const;
|
| +
|
| + // Returns the count of screens on the system. These screens can be retrieved
|
| + // by an integer in the range of [0, ScreenCount()).
|
| + int ScreenCount() const;
|
| +
|
| + private:
|
| + // A class to allow only one thread to enter. This class is used to make sure
|
| + // only one Initialize function call is being performed.
|
| + class SingleEntry {
|
| + public:
|
| + bool Enter();
|
| + void Exit();
|
| + bool Hold() const;
|
| +
|
| + private:
|
| + rtc::CriticalSection lock_;
|
| + bool entered_ = false;
|
| + };
|
| +
|
| + // A helper class to execute SingleEntry::Exit in its destructor.
|
| + class AutoExit;
|
| +
|
| + // Updates DxgiContext if needed.
|
| + void Setup(DxgiContext* context);
|
| +
|
| + bool DoInitialize();
|
| +
|
| + // Clears all COM components referred by this instance. So next Prepare()
|
| + // call will eventually initialize this instance again.
|
| + void Deinitialize();
|
| +
|
| + rtc::CriticalSection lock_;
|
| + SingleEntry initializing_;
|
| + int64_t initialize_time_nanos_ = 0;
|
| + DesktopRect desktop_rect_;
|
| + DesktopVector dpi_;
|
| + std::vector<D3dDevice> devices_;
|
| + std::vector<DxgiAdapterDuplicator> duplicators_;
|
| +};
|
| +
|
| +} // namespace webrtc
|
| +
|
| +#endif // MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_
|
|
|