/* * Copyright (c) 2014 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_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_ #define WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_ /* * video_capture_impl.h */ #include #include #include #include "api/sequence_checker.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "modules/desktop_capture/desktop_capturer.h" #include "modules/video_capture/video_capture.h" #include "desktop_device_info.h" #include "mozilla/DataMutex.h" #include "mozilla/Maybe.h" #include "mozilla/TimeStamp.h" #include "nsCOMPtr.h" #include "PerformanceRecorder.h" class nsIThread; class nsITimer; namespace mozilla::camera { enum class CaptureDeviceType; } namespace webrtc { class VideoCaptureEncodeInterface; // simulate deviceInfo interface for video engine, bridge screen/application and // real screen/application device info class ScreenDeviceInfoImpl : public VideoCaptureModule::DeviceInfo { public: ScreenDeviceInfoImpl(int32_t aId) : mId(aId) {} virtual ~ScreenDeviceInfoImpl() = default; int32_t Init(); int32_t Refresh(); virtual uint32_t NumberOfDevices(); virtual int32_t GetDeviceName(uint32_t aDeviceNumber, char* aDeviceNameUTF8, uint32_t aDeviceNameUTF8Size, char* aDeviceUniqueIdUTF8, uint32_t aDeviceUniqueIdUTF8Size, char* aProductUniqueIdUTF8, uint32_t aProductUniqueIdUTF8Size, pid_t* aPid); virtual int32_t DisplayCaptureSettingsDialogBox( const char* aDeviceUniqueIdUTF8, const char* aDialogTitleUTF8, void* aParentWindow, uint32_t aPositionX, uint32_t aPositionY); virtual int32_t NumberOfCapabilities(const char* aDeviceUniqueIdUTF8); virtual int32_t GetCapability(const char* aDeviceUniqueIdUTF8, uint32_t aDeviceCapabilityNumber, VideoCaptureCapability& aCapability); virtual int32_t GetBestMatchedCapability( const char* aDeviceUniqueIdUTF8, const VideoCaptureCapability& aRequested, VideoCaptureCapability& aResulting); virtual int32_t GetOrientation(const char* aDeviceUniqueIdUTF8, VideoRotation& aOrientation); protected: int32_t mId; std::unique_ptr mDesktopDeviceInfo; }; class WindowDeviceInfoImpl : public VideoCaptureModule::DeviceInfo { public: WindowDeviceInfoImpl(int32_t aId) : mId(aId){}; virtual ~WindowDeviceInfoImpl() = default; int32_t Init(); int32_t Refresh(); virtual uint32_t NumberOfDevices(); virtual int32_t GetDeviceName(uint32_t aDeviceNumber, char* aDeviceNameUTF8, uint32_t aDeviceNameUTF8Size, char* aDeviceUniqueIdUTF8, uint32_t aDeviceUniqueIdUTF8Size, char* aProductUniqueIdUTF8, uint32_t aProductUniqueIdUTF8Size, pid_t* aPid); virtual int32_t DisplayCaptureSettingsDialogBox( const char* aDeviceUniqueIdUTF8, const char* aDialogTitleUTF8, void* aParentWindow, uint32_t aPositionX, uint32_t aPositionY); virtual int32_t NumberOfCapabilities(const char* aDeviceUniqueIdUTF8); virtual int32_t GetCapability(const char* aDeviceUniqueIdUTF8, uint32_t aDeviceCapabilityNumber, VideoCaptureCapability& aCapability); virtual int32_t GetBestMatchedCapability( const char* aDeviceUniqueIdUTF8, const VideoCaptureCapability& aRequested, VideoCaptureCapability& aResulting); virtual int32_t GetOrientation(const char* aDeviceUniqueIdUTF8, VideoRotation& aOrientation); protected: int32_t mId; std::unique_ptr mDesktopDeviceInfo; }; class BrowserDeviceInfoImpl : public VideoCaptureModule::DeviceInfo { public: BrowserDeviceInfoImpl(int32_t aId) : mId(aId){}; virtual ~BrowserDeviceInfoImpl() = default; int32_t Init(); int32_t Refresh(); virtual uint32_t NumberOfDevices(); virtual int32_t GetDeviceName(uint32_t aDeviceNumber, char* aDeviceNameUTF8, uint32_t aDeviceNameUTF8Size, char* aDeviceUniqueIdUTF8, uint32_t aDeviceUniqueIdUTF8Size, char* aProductUniqueIdUTF8, uint32_t aProductUniqueIdUTF8Size, pid_t* aPid); virtual int32_t DisplayCaptureSettingsDialogBox( const char* aDeviceUniqueIdUTF8, const char* aDialogTitleUTF8, void* aParentWindow, uint32_t aPositionX, uint32_t aPositionY); virtual int32_t NumberOfCapabilities(const char* aDeviceUniqueIdUTF8); virtual int32_t GetCapability(const char* aDeviceUniqueIdUTF8, uint32_t aDeviceCapabilityNumber, VideoCaptureCapability& aCapability); virtual int32_t GetBestMatchedCapability( const char* aDeviceUniqueIdUTF8, const VideoCaptureCapability& aRequested, VideoCaptureCapability& aResulting); virtual int32_t GetOrientation(const char* aDeviceUniqueIdUTF8, VideoRotation& aOrientation); protected: int32_t mId; std::unique_ptr mDesktopDeviceInfo; }; // Reuses the video engine pipeline for screen sharing. // As with video, DesktopCaptureImpl is a proxy for screen sharing // and follows the video pipeline design class DesktopCaptureImpl : public DesktopCapturer::Callback, public VideoCaptureModule { public: /* Create a screen capture modules object */ static VideoCaptureModule* Create( const int32_t aModuleId, const char* aUniqueId, const mozilla::camera::CaptureDeviceType aType); [[nodiscard]] static std::shared_ptr CreateDeviceInfo(const int32_t aId, const mozilla::camera::CaptureDeviceType aType); // mControlThread only. void RegisterCaptureDataCallback( rtc::VideoSinkInterface* aCallback) override; void RegisterCaptureDataCallback( RawVideoSinkInterface* dataCallback) override {} void DeRegisterCaptureDataCallback( rtc::VideoSinkInterface* aCallback) override; int32_t StopCaptureIfAllClientsClose() override; int32_t SetCaptureRotation(VideoRotation aRotation) override; bool SetApplyRotation(bool aEnable) override; bool GetApplyRotation() override { return true; } const char* CurrentDeviceName() const override; int32_t StartCapture(const VideoCaptureCapability& aCapability) override; virtual bool FocusOnSelectedSource() override; int32_t StopCapture() override; bool CaptureStarted() override; int32_t CaptureSettings(VideoCaptureCapability& aSettings) override; void CaptureFrameOnThread(); const int32_t mModuleId; const mozilla::TrackingId mTrackingId; const std::string mDeviceUniqueId; const mozilla::camera::CaptureDeviceType mDeviceType; protected: DesktopCaptureImpl(const int32_t aId, const char* aUniqueId, const mozilla::camera::CaptureDeviceType aType); virtual ~DesktopCaptureImpl(); private: // Maximum CPU usage in %. static constexpr uint32_t kMaxDesktopCaptureCpuUsage = 50; void InitOnThread(std::unique_ptr aCapturer, int aFramerate); void ShutdownOnThread(); // DesktopCapturer::Callback interface. void OnCaptureResult(DesktopCapturer::Result aResult, std::unique_ptr aFrame) override; // Notifies all mCallbacks of OnFrame(). mCaptureThread only. void NotifyOnFrame(const VideoFrame& aFrame); // Control thread on which the public API is called. const nsCOMPtr mControlThread; // Set in StartCapture. mozilla::Maybe mRequestedCapability RTC_GUARDED_BY(mControlThreadChecker); // The DesktopCapturer is created on mControlThread but assigned and accessed // only on mCaptureThread. std::unique_ptr mCapturer RTC_GUARDED_BY(mCaptureThreadChecker); // Dedicated thread that does the capturing. nsCOMPtr mCaptureThread RTC_GUARDED_BY(mControlThreadChecker); // Checks that API methods are called on mControlThread. webrtc::SequenceChecker mControlThreadChecker; // Checks that frame delivery only happens on mCaptureThread. webrtc::SequenceChecker mCaptureThreadChecker; // Timer that triggers frame captures. Only used on mCaptureThread. // TODO(Bug 1806646): Drive capture with vsync instead. nsCOMPtr mCaptureTimer RTC_GUARDED_BY(mCaptureThreadChecker); // Interval between captured frames, based on the framerate in // mRequestedCapability. mCaptureThread only. mozilla::Maybe mRequestedCaptureInterval RTC_GUARDED_BY(mCaptureThreadChecker); // Used to make sure incoming timestamp is increasing for every frame. webrtc::Timestamp mNextFrameMinimumTime RTC_GUARDED_BY(mCaptureThreadChecker); // Callbacks for captured frames. Mutated on mControlThread, callbacks happen // on mCaptureThread. mozilla::DataMutex*>> mCallbacks; }; } // namespace webrtc #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_