blob: 56b101acbaa601b83f81c7b48890c79f3cb66755 [file] [log] [blame]
/*
* Copyright 2018 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_LINUX_BASE_CAPTURER_PIPEWIRE_H_
#define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
#include <gio/gio.h>
#define typeof __typeof__
#include <pipewire/pipewire.h>
#include <spa/param/video/format-utils.h>
#include "modules/desktop_capture/desktop_capture_options.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "rtc_base/constructormagic.h"
namespace webrtc {
class PipeWireType {
public:
spa_type_media_type media_type;
spa_type_media_subtype media_subtype;
spa_type_format_video format_video;
spa_type_video_format video_format;
};
class BaseCapturerPipeWire : public DesktopCapturer {
public:
enum CaptureSourceType { Screen = 1, Window };
explicit BaseCapturerPipeWire(CaptureSourceType source_type);
~BaseCapturerPipeWire() override;
// DesktopCapturer interface.
void Start(Callback* delegate) override;
void CaptureFrame() override;
bool GetSourceList(SourceList* sources) override;
bool SelectSource(SourceId id) override;
private:
// PipeWire types -->
pw_core* pw_core_ = nullptr;
pw_type* pw_core_type_ = nullptr;
pw_stream* pw_stream_ = nullptr;
pw_remote* pw_remote_ = nullptr;
pw_loop* pw_loop_ = nullptr;
pw_thread_loop* pw_main_loop_ = nullptr;
PipeWireType* pw_type_ = nullptr;
spa_hook spa_stream_listener_ = {};
spa_hook spa_remote_listener_ = {};
pw_stream_events pw_stream_events_ = {};
pw_remote_events pw_remote_events_ = {};
spa_video_info_raw* spa_video_format_ = nullptr;
gint32 pw_fd_ = -1;
CaptureSourceType capture_source_type_ =
BaseCapturerPipeWire::CaptureSourceType::Screen;
// <-- end of PipeWire types
GDBusConnection* connection_ = nullptr;
GDBusProxy* proxy_ = nullptr;
gchar* portal_handle_ = nullptr;
gchar* session_handle_ = nullptr;
gchar* sources_handle_ = nullptr;
gchar* start_handle_ = nullptr;
guint session_request_signal_id_ = 0;
guint sources_request_signal_id_ = 0;
guint start_request_signal_id_ = 0;
DesktopSize desktop_size_ = {};
DesktopCaptureOptions options_ = {};
uint8_t* current_frame_ = nullptr;
Callback* callback_ = nullptr;
bool portal_init_failed_ = false;
void InitPortal();
void InitPipeWire();
void InitPipeWireTypes();
void CreateReceivingStream();
void HandleBuffer(pw_buffer* buffer);
void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
static void OnStateChanged(void* data,
pw_remote_state old_state,
pw_remote_state state,
const char* error);
static void OnStreamStateChanged(void* data,
pw_stream_state old_state,
pw_stream_state state,
const char* error_message);
static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
static void OnStreamProcess(void* data);
static void OnNewBuffer(void* data, uint32_t id);
guint SetupRequestResponseSignal(const gchar* object_path,
GDBusSignalCallback callback);
static void OnProxyRequested(GObject* object,
GAsyncResult* result,
gpointer user_data);
static gchar* PrepareSignalHandle(GDBusConnection* connection,
const gchar* token);
void SessionRequest();
static void OnSessionRequested(GDBusConnection* connection,
GAsyncResult* result,
gpointer user_data);
static void OnSessionRequestResponseSignal(GDBusConnection* connection,
const gchar* sender_name,
const gchar* object_path,
const gchar* interface_name,
const gchar* signal_name,
GVariant* parameters,
gpointer user_data);
void SourcesRequest();
static void OnSourcesRequested(GDBusConnection* connection,
GAsyncResult* result,
gpointer user_data);
static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
const gchar* sender_name,
const gchar* object_path,
const gchar* interface_name,
const gchar* signal_name,
GVariant* parameters,
gpointer user_data);
void StartRequest();
static void OnStartRequested(GDBusConnection* connection,
GAsyncResult* result,
gpointer user_data);
static void OnStartRequestResponseSignal(GDBusConnection* connection,
const gchar* sender_name,
const gchar* object_path,
const gchar* interface_name,
const gchar* signal_name,
GVariant* parameters,
gpointer user_data);
void OpenPipeWireRemote();
static void OnOpenPipeWireRemoteRequested(GDBusConnection* connection,
GAsyncResult* result,
gpointer user_data);
RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire);
};
} // namespace webrtc
#endif // MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_