tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pipewire_session.h (6187B)


      1 /*
      2 *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_
     12 #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_
     13 
     14 #include <pipewire/pipewire.h>
     15 #include <spa/pod/pod.h>
     16 #include <spa/utils/dict.h>
     17 #include <spa/utils/hook.h>
     18 
     19 #include <cstdint>
     20 #include <deque>
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include "api/ref_counted_base.h"
     26 #include "modules/portal/pipewire_utils.h"
     27 #include "modules/portal/portal_request_response.h"
     28 #include "modules/video_capture/linux/camera_portal.h"
     29 #include "modules/video_capture/video_capture_defines.h"
     30 #include "modules/video_capture/video_capture_options.h"
     31 #include "rtc_base/synchronization/mutex.h"
     32 #include "rtc_base/thread_annotations.h"
     33 
     34 namespace webrtc {
     35 namespace videocapturemodule {
     36 
     37 class DeviceInfoPipeWire;
     38 class PipeWireSession;
     39 class VideoCaptureModulePipeWire;
     40 
     41 // PipeWireNode objects are the local representation of PipeWire node objects.
     42 // The portal API ensured that only camera nodes are visible to the client.
     43 // So they all represent one camera that is available via PipeWire.
     44 class PipeWireNode {
     45 public:
     46  struct PipeWireNodeDeleter {
     47    void operator()(PipeWireNode* node) const noexcept;
     48  };
     49 
     50  using PipeWireNodePtr =
     51      std::unique_ptr<PipeWireNode, PipeWireNode::PipeWireNodeDeleter>;
     52  static PipeWireNodePtr Create(PipeWireSession* session,
     53                                uint32_t id,
     54                                const spa_dict* props);
     55 
     56  uint32_t id() const { return id_; }
     57  std::string display_name() const { return display_name_; }
     58  std::string unique_id() const { return unique_id_; }
     59  std::string model_id() const { return model_id_; }
     60  std::vector<VideoCaptureCapability> capabilities() const {
     61    return capabilities_;
     62  }
     63 
     64 protected:
     65  PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props);
     66 
     67 private:
     68  static void OnNodeInfo(void* data, const pw_node_info* info);
     69  static void OnNodeParam(void* data,
     70                          int seq,
     71                          uint32_t id,
     72                          uint32_t index,
     73                          uint32_t next,
     74                          const spa_pod* param);
     75  static bool ParseFormat(const spa_pod* param, VideoCaptureCapability* cap);
     76 
     77  struct pw_proxy* proxy_;
     78  struct spa_hook node_listener_;
     79  PipeWireSession* session_;
     80  uint32_t id_;
     81  std::string display_name_;
     82  std::string unique_id_;
     83  std::string model_id_;
     84  std::vector<VideoCaptureCapability> capabilities_;
     85 };
     86 
     87 class CameraPortalNotifier : public CameraPortal::PortalNotifier {
     88 public:
     89  CameraPortalNotifier(PipeWireSession* session);
     90  ~CameraPortalNotifier() = default;
     91 
     92  void OnCameraRequestResult(xdg_portal::RequestResponse result,
     93                             int fd) override;
     94 
     95 private:
     96  PipeWireSession* session_;
     97 };
     98 
     99 class PipeWireSession : public webrtc::RefCountedNonVirtual<PipeWireSession> {
    100 public:
    101  PipeWireSession();
    102  ~PipeWireSession();
    103 
    104  void Init(VideoCaptureOptions::Callback* callback,
    105            int fd = kInvalidPipeWireFd);
    106 
    107  // [De]Register DeviceInfo for device change updates
    108  // These methods will add or remove references to DeviceInfo
    109  // objects that we want to notify about device changes.
    110  // NOTE: We do not take ownership of these objects and
    111  // they should never be released by us. All the instances
    112  // of DeviceInfoPipeWire must outlive their registration.
    113 
    114  // Returns true when DeviceInfo was successfuly registered
    115  // or false otherwise, when it was already registered before.
    116  bool RegisterDeviceInfo(DeviceInfoPipeWire* device_info);
    117  // Returns true when DeviceInfo was successfuly unregistered
    118  // or false otherwise, when it was not previously registered.
    119  bool DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info);
    120 
    121  const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
    122    return nodes_;
    123  }
    124 
    125  friend class CameraPortalNotifier;
    126  friend class PipeWireNode;
    127  friend class VideoCaptureModulePipeWire;
    128 
    129 private:
    130  void InitPipeWire(int fd);
    131  bool StartPipeWire(int fd);
    132  void StopPipeWire();
    133  void PipeWireSync();
    134 
    135  void NotifyDeviceChange();
    136 
    137  static void OnCoreError(void* data,
    138                          uint32_t id,
    139                          int seq,
    140                          int res,
    141                          const char* message);
    142  static void OnCoreDone(void* data, uint32_t id, int seq);
    143 
    144  static void OnRegistryGlobal(void* data,
    145                               uint32_t id,
    146                               uint32_t permissions,
    147                               const char* type,
    148                               uint32_t version,
    149                               const spa_dict* props);
    150  static void OnRegistryGlobalRemove(void* data, uint32_t id);
    151 
    152  void Finish(VideoCaptureOptions::Status status);
    153  void Cleanup();
    154 
    155  webrtc::Mutex callback_lock_;
    156  VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) =
    157      nullptr;
    158 
    159  webrtc::Mutex device_info_lock_;
    160  std::vector<DeviceInfoPipeWire*> device_info_list_
    161      RTC_GUARDED_BY(device_info_lock_);
    162  // Guard with device_info_lock, because currently it's the only place where
    163  // we use this status information.
    164  VideoCaptureOptions::Status status_
    165      RTC_GUARDED_BY(device_info_lock_);
    166 
    167  struct pw_thread_loop* pw_main_loop_ = nullptr;
    168  struct pw_context* pw_context_ = nullptr;
    169  struct pw_core* pw_core_ = nullptr;
    170  struct spa_hook core_listener_;
    171 
    172  struct pw_registry* pw_registry_ = nullptr;
    173  struct spa_hook registry_listener_;
    174 
    175  int sync_seq_ = 0;
    176 
    177  std::deque<PipeWireNode::PipeWireNodePtr> nodes_;
    178  std::unique_ptr<CameraPortal> portal_;
    179  std::unique_ptr<CameraPortalNotifier> portal_notifier_;
    180 };
    181 
    182 }  // namespace videocapturemodule
    183 }  // namespace webrtc
    184 
    185 #endif  // MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_