dirty region than the real screen change. A similar behavior may happen on other platforms with damage notification support. So it's better to have an individual layer to handle the Differ logic, and remove capturing independent logic out of each ScreenCapturer* implementation. So this change does following things, 1. Update differ_block to handle variable height. differ_block_sse2 has been renamed to differ_vector_sse2. 2. A new ScreenCapturerDifferWrapper implementation to help set DesktopFrame::updated_region(). It uses an underlying ScreenCapturer to do the real capture work, and updates the updated region of DesktopFrame returned from OnCaptureResult function. 3. FakeDesktopCapturer and FakeScreenCapturer to generate controllable DesktopFrame by using DesktopFrameGenerator and DesktopFramePainter. 4. Test ScreenCapturerDifferWrapper by using FakeScreenCapturer. After this change, we can eventually remove all Differ logic from ScreenCapturer* implementations, and fix a potential crash bug in ScreenCapturerLinux class. It wrongly assumes previous_frame() has a same size as current_frame(). https://goo.gl/3nSqOC BUG=633802 TBR=kjellander@webrtc.org Review-Url: https://codereview.webrtc.org/2202443002 Cr-Commit-Position: refs/heads/master@{#14076}
122 lines
4.5 KiB
C++
122 lines
4.5 KiB
C++
/*
|
|
* 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 WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_
|
|
#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_
|
|
|
|
#include <memory>
|
|
|
|
#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/shared_memory.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// An interface to generate a DesktopFrame.
|
|
class DesktopFrameGenerator {
|
|
public:
|
|
DesktopFrameGenerator();
|
|
virtual ~DesktopFrameGenerator();
|
|
|
|
virtual std::unique_ptr<DesktopFrame> GetNextFrame(
|
|
SharedMemoryFactory* factory) = 0;
|
|
};
|
|
|
|
// An interface to paint a DesktopFrame. This interface is used by
|
|
// PainterDesktopFrameGenerator.
|
|
class DesktopFramePainter {
|
|
public:
|
|
DesktopFramePainter();
|
|
virtual ~DesktopFramePainter();
|
|
|
|
virtual bool Paint(DesktopFrame* frame, DesktopRegion* updated_region) = 0;
|
|
};
|
|
|
|
// An implementation of DesktopFrameGenerator to take care about the
|
|
// DesktopFrame size, filling updated_region(), etc, but leaves the real
|
|
// painting work to a DesktopFramePainter implementation.
|
|
class PainterDesktopFrameGenerator final : public DesktopFrameGenerator {
|
|
public:
|
|
PainterDesktopFrameGenerator();
|
|
~PainterDesktopFrameGenerator() override;
|
|
|
|
std::unique_ptr<DesktopFrame> GetNextFrame(
|
|
SharedMemoryFactory* factory) override;
|
|
|
|
// Sets the size of the frame which will be returned in next GetNextFrame()
|
|
// call.
|
|
DesktopSize* size();
|
|
|
|
// Decides whether BaseDesktopFrameGenerator returns a frame in next Capture()
|
|
// callback. If return_frame_ is true, BaseDesktopFrameGenerator will create a
|
|
// frame according to both size_ and SharedMemoryFactory input, and uses
|
|
// Paint() function to paint it.
|
|
void set_return_frame(bool return_frame);
|
|
|
|
// Decides whether MockScreenCapturer returns a frame with updated regions.
|
|
// MockScreenCapturer will keep DesktopFrame::updated_region() empty if this
|
|
// field is false.
|
|
void set_provide_updated_region_hints(bool provide_updated_region_hints);
|
|
|
|
// Decides whether MockScreenCapturer randomly enlarges updated regions in the
|
|
// DesktopFrame. Set this field to true to simulate an inaccurate updated
|
|
// regions' return from OS APIs.
|
|
void set_enlarge_updated_region(bool enlarge_updated_region);
|
|
|
|
// The range to enlarge a updated region if |enlarge_updated_region_| is true.
|
|
// If this field is less than zero, it will be treated as zero, and
|
|
// |enlarge_updated_region_| will be ignored.
|
|
void set_enlarge_range(int enlarge_range);
|
|
|
|
// Decides whether BaseDesktopFrameGenerator randomly add some updated regions
|
|
// in the DesktopFrame. Set this field to true to simulate an inaccurate
|
|
// updated regions' return from OS APIs.
|
|
void set_add_random_updated_region(bool add_random_updated_region);
|
|
|
|
// Sets the painter object to do the real painting work, if no |painter_| has
|
|
// been set to this instance, the DesktopFrame returned by GetNextFrame()
|
|
// function will keep in an undefined but valid state.
|
|
// PainterDesktopFrameGenerator does not take ownership of the |painter|.
|
|
void set_desktop_frame_painter(DesktopFramePainter* painter);
|
|
|
|
private:
|
|
DesktopSize size_;
|
|
bool return_frame_;
|
|
bool provide_updated_region_hints_;
|
|
bool enlarge_updated_region_;
|
|
int enlarge_range_;
|
|
bool add_random_updated_region_;
|
|
DesktopFramePainter* painter_;
|
|
};
|
|
|
|
// An implementation of DesktopFramePainter to paint black on
|
|
// mutable_updated_region(), and white elsewhere.
|
|
class BlackWhiteDesktopFramePainter final : public DesktopFramePainter {
|
|
public:
|
|
BlackWhiteDesktopFramePainter();
|
|
~BlackWhiteDesktopFramePainter() override;
|
|
|
|
// The black regions of the frame which will be returned in next Paint()
|
|
// call. BlackWhiteDesktopFramePainter will draw a white frame, with black
|
|
// in the updated_region_. Each Paint() call will consume updated_region_.
|
|
DesktopRegion* updated_region();
|
|
|
|
// DesktopFramePainter interface.
|
|
bool Paint(DesktopFrame* frame, DesktopRegion* updated_region) override;
|
|
|
|
private:
|
|
DesktopRegion updated_region_;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_
|