base_capturer_pipewire.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2018 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. #ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
  11. #define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
  12. #include <gio/gio.h>
  13. #define typeof __typeof__
  14. #include <pipewire/pipewire.h>
  15. #include <spa/param/video/format-utils.h>
  16. #include "modules/desktop_capture/desktop_capture_options.h"
  17. #include "modules/desktop_capture/desktop_capturer.h"
  18. #include "rtc_base/constructor_magic.h"
  19. namespace webrtc {
  20. class PipeWireType {
  21. public:
  22. spa_type_media_type media_type;
  23. spa_type_media_subtype media_subtype;
  24. spa_type_format_video format_video;
  25. spa_type_video_format video_format;
  26. };
  27. class BaseCapturerPipeWire : public DesktopCapturer {
  28. public:
  29. enum CaptureSourceType { Screen = 1, Window };
  30. explicit BaseCapturerPipeWire(CaptureSourceType source_type);
  31. ~BaseCapturerPipeWire() override;
  32. // DesktopCapturer interface.
  33. void Start(Callback* delegate) override;
  34. void CaptureFrame() override;
  35. bool GetSourceList(SourceList* sources) override;
  36. bool SelectSource(SourceId id) override;
  37. private:
  38. // PipeWire types -->
  39. pw_core* pw_core_ = nullptr;
  40. pw_type* pw_core_type_ = nullptr;
  41. pw_stream* pw_stream_ = nullptr;
  42. pw_remote* pw_remote_ = nullptr;
  43. pw_loop* pw_loop_ = nullptr;
  44. pw_thread_loop* pw_main_loop_ = nullptr;
  45. PipeWireType* pw_type_ = nullptr;
  46. spa_hook spa_stream_listener_ = {};
  47. spa_hook spa_remote_listener_ = {};
  48. pw_stream_events pw_stream_events_ = {};
  49. pw_remote_events pw_remote_events_ = {};
  50. spa_video_info_raw* spa_video_format_ = nullptr;
  51. gint32 pw_fd_ = -1;
  52. CaptureSourceType capture_source_type_ =
  53. BaseCapturerPipeWire::CaptureSourceType::Screen;
  54. // <-- end of PipeWire types
  55. GDBusConnection* connection_ = nullptr;
  56. GDBusProxy* proxy_ = nullptr;
  57. GCancellable *cancellable_ = nullptr;
  58. gchar* portal_handle_ = nullptr;
  59. gchar* session_handle_ = nullptr;
  60. gchar* sources_handle_ = nullptr;
  61. gchar* start_handle_ = nullptr;
  62. guint session_request_signal_id_ = 0;
  63. guint sources_request_signal_id_ = 0;
  64. guint start_request_signal_id_ = 0;
  65. DesktopSize desktop_size_ = {};
  66. DesktopCaptureOptions options_ = {};
  67. uint8_t* current_frame_ = nullptr;
  68. Callback* callback_ = nullptr;
  69. bool portal_init_failed_ = false;
  70. void InitPortal();
  71. void InitPipeWire();
  72. void InitPipeWireTypes();
  73. void CreateReceivingStream();
  74. void HandleBuffer(pw_buffer* buffer);
  75. void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
  76. static void OnStateChanged(void* data,
  77. pw_remote_state old_state,
  78. pw_remote_state state,
  79. const char* error);
  80. static void OnStreamStateChanged(void* data,
  81. pw_stream_state old_state,
  82. pw_stream_state state,
  83. const char* error_message);
  84. static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
  85. static void OnStreamProcess(void* data);
  86. static void OnNewBuffer(void* data, uint32_t id);
  87. guint SetupRequestResponseSignal(const gchar* object_path,
  88. GDBusSignalCallback callback);
  89. static void OnProxyRequested(GObject* object,
  90. GAsyncResult* result,
  91. gpointer user_data);
  92. static gchar* PrepareSignalHandle(GDBusConnection* connection,
  93. const gchar* token);
  94. void SessionRequest();
  95. static void OnSessionRequested(GDBusProxy *proxy,
  96. GAsyncResult* result,
  97. gpointer user_data);
  98. static void OnSessionRequestResponseSignal(GDBusConnection* connection,
  99. const gchar* sender_name,
  100. const gchar* object_path,
  101. const gchar* interface_name,
  102. const gchar* signal_name,
  103. GVariant* parameters,
  104. gpointer user_data);
  105. void SourcesRequest();
  106. static void OnSourcesRequested(GDBusProxy *proxy,
  107. GAsyncResult* result,
  108. gpointer user_data);
  109. static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
  110. const gchar* sender_name,
  111. const gchar* object_path,
  112. const gchar* interface_name,
  113. const gchar* signal_name,
  114. GVariant* parameters,
  115. gpointer user_data);
  116. void StartRequest();
  117. static void OnStartRequested(GDBusProxy *proxy,
  118. GAsyncResult* result,
  119. gpointer user_data);
  120. static void OnStartRequestResponseSignal(GDBusConnection* connection,
  121. const gchar* sender_name,
  122. const gchar* object_path,
  123. const gchar* interface_name,
  124. const gchar* signal_name,
  125. GVariant* parameters,
  126. gpointer user_data);
  127. void OpenPipeWireRemote();
  128. static void OnOpenPipeWireRemoteRequested(GDBusProxy *proxy,
  129. GAsyncResult* result,
  130. gpointer user_data);
  131. RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire);
  132. };
  133. } // namespace webrtc
  134. #endif // MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_