/* * Copyright (c) 2022 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_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ #include #include #include #include #include #include "api/ref_counted_base.h" #include "api/scoped_refptr.h" #include "modules/portal/pipewire_utils.h" #include "modules/video_capture/linux/camera_portal.h" #include "modules/video_capture/video_capture.h" #include "modules/video_capture/video_capture_options.h" #include "rtc_base/synchronization/mutex.h" namespace webrtc { namespace videocapturemodule { class PipeWireSession; class VideoCaptureModulePipeWire; // PipeWireNode objects are the local representation of PipeWire node objects. // The portal API ensured that only camera nodes are visible to the client. // So they all represent one camera that is available via PipeWire. class PipeWireNode { public: PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props); ~PipeWireNode(); uint32_t id() const { return id_; } std::string display_name() const { return display_name_; } std::string unique_id() const { return unique_id_; } std::string model_id() const { return model_id_; } std::vector capabilities() const { return capabilities_; } private: static void OnNodeInfo(void* data, const pw_node_info* info); static void OnNodeParam(void* data, int seq, uint32_t id, uint32_t index, uint32_t next, const spa_pod* param); static bool ParseFormat(const spa_pod* param, VideoCaptureCapability* cap); pw_proxy* proxy_; spa_hook node_listener_; PipeWireSession* session_; uint32_t id_; std::string display_name_; std::string unique_id_; std::string model_id_; std::vector capabilities_; }; class CameraPortalNotifier : public CameraPortal::PortalNotifier { public: CameraPortalNotifier(PipeWireSession* session); ~CameraPortalNotifier() = default; void OnCameraRequestResult(xdg_portal::RequestResponse result, int fd) override; private: PipeWireSession* session_; }; class PipeWireSession : public rtc::RefCountedNonVirtual { public: PipeWireSession(); ~PipeWireSession(); void Init(VideoCaptureOptions::Callback* callback, int fd = kInvalidPipeWireFd); const std::deque& nodes() const { return nodes_; } friend class CameraPortalNotifier; friend class PipeWireNode; friend class VideoCaptureModulePipeWire; private: void InitPipeWire(int fd); bool StartPipeWire(int fd); void StopPipeWire(); void PipeWireSync(); static void OnCoreError(void* data, uint32_t id, int seq, int res, const char* message); static void OnCoreDone(void* data, uint32_t id, int seq); static void OnRegistryGlobal(void* data, uint32_t id, uint32_t permissions, const char* type, uint32_t version, const spa_dict* props); static void OnRegistryGlobalRemove(void* data, uint32_t id); void Finish(VideoCaptureOptions::Status status); void Cleanup(); webrtc::Mutex callback_lock_; VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) = nullptr; VideoCaptureOptions::Status status_; struct pw_thread_loop* pw_main_loop_ = nullptr; struct pw_context* pw_context_ = nullptr; struct pw_core* pw_core_ = nullptr; struct spa_hook core_listener_; struct pw_registry* pw_registry_ = nullptr; struct spa_hook registry_listener_; int sync_seq_ = 0; std::deque nodes_; std::unique_ptr portal_; std::unique_ptr portal_notifier_; }; } // namespace videocapturemodule } // namespace webrtc #endif // MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_