mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

Earlier, we were relying on CRD to periodically do frame captures. This is however not needed since Wayland captures are event based and once the compositor has send the event/frame to us, we can just handover the frame to a registered callback. This ensures that we have a single frame clock that (i.e. one present in the compositor). Without this change, there is a chance that CRD capture clock is run out of sync with the compositor's clock and cause unnecessary frame delays. See the following ideal scenario, for example, where '+' indicates when a frame is sent by the compositor and when CRD tries to capture it. This assumes that the same clock cycle for both CRD and the compositor, each cycle length is enclosed within | .... |). Compositor Frame Ready | +... | | +... | CRD Frame Capture | .+.. | | .+.. | In this case, when both the clocks are in sync, CRD is able to capture frame right after it is generated by the compositor. But if they are completely out of sync, then CRD can always see a stale frame (delayed by one cycle and it can cause users to feel stutter). Compositor Frame Ready | .+.. | | .+.. | CRD Frame Capture | +... | | +... | This stutter can become worse if the compositor is delayed in generating the frames for some reason (e.g. load on the system). Bug: chromium:1291247 Change-Id: I7c10c724fbbd87dc523d474e7ece8e8aa146fd7b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291080 Reviewed-by: Alexander Cooper <alcooper@chromium.org> Commit-Queue: Salman Malik <salmanmalik@chromium.org> Cr-Commit-Position: refs/heads/main@{#39218}
100 lines
4 KiB
C++
100 lines
4 KiB
C++
/*
|
|
* Copyright (c) 2013 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_DESKTOP_AND_CURSOR_COMPOSER_H_
|
|
#define MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_
|
|
|
|
#include <memory>
|
|
#if defined(WEBRTC_USE_GIO)
|
|
#include "modules/desktop_capture/desktop_capture_metadata.h"
|
|
#endif // defined(WEBRTC_USE_GIO)
|
|
#include "modules/desktop_capture/desktop_capture_options.h"
|
|
#include "modules/desktop_capture/desktop_capture_types.h"
|
|
#include "modules/desktop_capture/desktop_capturer.h"
|
|
#include "modules/desktop_capture/desktop_frame.h"
|
|
#include "modules/desktop_capture/desktop_geometry.h"
|
|
#include "modules/desktop_capture/mouse_cursor.h"
|
|
#include "modules/desktop_capture/mouse_cursor_monitor.h"
|
|
#include "modules/desktop_capture/shared_memory.h"
|
|
#include "rtc_base/system/rtc_export.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// A wrapper for DesktopCapturer that also captures mouse using specified
|
|
// MouseCursorMonitor and renders it on the generated streams.
|
|
class RTC_EXPORT DesktopAndCursorComposer
|
|
: public DesktopCapturer,
|
|
public DesktopCapturer::Callback,
|
|
public MouseCursorMonitor::Callback {
|
|
public:
|
|
// Creates a new composer that captures mouse cursor using
|
|
// MouseCursorMonitor::Create(options) and renders it into the frames
|
|
// generated by `desktop_capturer`.
|
|
DesktopAndCursorComposer(std::unique_ptr<DesktopCapturer> desktop_capturer,
|
|
const DesktopCaptureOptions& options);
|
|
|
|
~DesktopAndCursorComposer() override;
|
|
|
|
DesktopAndCursorComposer(const DesktopAndCursorComposer&) = delete;
|
|
DesktopAndCursorComposer& operator=(const DesktopAndCursorComposer&) = delete;
|
|
|
|
// Creates a new composer that relies on an external source for cursor shape
|
|
// and position information via the MouseCursorMonitor::Callback interface.
|
|
static std::unique_ptr<DesktopAndCursorComposer>
|
|
CreateWithoutMouseCursorMonitor(
|
|
std::unique_ptr<DesktopCapturer> desktop_capturer);
|
|
|
|
// DesktopCapturer interface.
|
|
void Start(DesktopCapturer::Callback* callback) override;
|
|
void SetSharedMemoryFactory(
|
|
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
|
|
void CaptureFrame() override;
|
|
void SetExcludedWindow(WindowId window) override;
|
|
bool GetSourceList(SourceList* sources) override;
|
|
bool SelectSource(SourceId id) override;
|
|
bool FocusOnSelectedSource() override;
|
|
bool IsOccluded(const DesktopVector& pos) override;
|
|
void SetMaxFrameRate(uint32_t max_frame_rate) override;
|
|
#if defined(WEBRTC_USE_GIO)
|
|
DesktopCaptureMetadata GetMetadata() override;
|
|
#endif // defined(WEBRTC_USE_GIO)
|
|
|
|
// MouseCursorMonitor::Callback interface.
|
|
void OnMouseCursor(MouseCursor* cursor) override;
|
|
void OnMouseCursorPosition(const DesktopVector& position) override;
|
|
|
|
private:
|
|
// Allows test cases to use a fake MouseCursorMonitor implementation.
|
|
friend class DesktopAndCursorComposerTest;
|
|
|
|
// Constructor to delegate both deprecated and new constructors and allows
|
|
// test cases to use a fake MouseCursorMonitor implementation.
|
|
DesktopAndCursorComposer(DesktopCapturer* desktop_capturer,
|
|
MouseCursorMonitor* mouse_monitor);
|
|
|
|
// DesktopCapturer::Callback interface.
|
|
void OnFrameCaptureStart() override;
|
|
void OnCaptureResult(DesktopCapturer::Result result,
|
|
std::unique_ptr<DesktopFrame> frame) override;
|
|
|
|
const std::unique_ptr<DesktopCapturer> desktop_capturer_;
|
|
const std::unique_ptr<MouseCursorMonitor> mouse_monitor_;
|
|
|
|
DesktopCapturer::Callback* callback_;
|
|
|
|
std::unique_ptr<MouseCursor> cursor_;
|
|
DesktopVector cursor_position_;
|
|
DesktopRect previous_cursor_rect_;
|
|
bool cursor_changed_ = false;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_
|