linux-capture: Query used PipeWire versions

This enables us in the following commit to announce different
capabilities wrt. those versions.
This commit is contained in:
columbarius 2021-11-27 04:28:53 +01:00 committed by Georges Basile Stavracas Neto
parent 243880b9ce
commit 9f7de79004

View File

@ -35,6 +35,7 @@
#include <spa/debug/format.h>
#include <spa/debug/types.h>
#include <spa/param/video/type-info.h>
#include <spa/utils/result.h>
#define REQUEST_PATH "/org/freedesktop/portal/desktop/request/%s/obs%u"
#define SESSION_PATH "/org/freedesktop/portal/desktop/session/%s/obs%u"
@ -60,6 +61,12 @@
fourcc_code('A', 'B', '2', \
'4') /* [31:0] A:B:G:R 8:8:8:8 little endian */
struct obs_pw_version {
int major;
int minor;
int micro;
};
struct _obs_pipewire_data {
GCancellable *cancellable;
@ -82,6 +89,9 @@ struct _obs_pipewire_data {
struct pw_core *core;
struct spa_hook core_listener;
int server_version_sync;
struct obs_pw_version server_version;
struct pw_stream *stream;
struct spa_hook stream_listener;
@ -116,6 +126,35 @@ struct dbus_call_data {
/* auxiliary methods */
static bool parse_pw_version(struct obs_pw_version *dst, const char *version)
{
int n_matches = sscanf(version, "%d.%d.%d", &dst->major, &dst->minor,
&dst->micro);
return n_matches == 3;
}
static bool check_pw_version(const struct obs_pw_version *pw_version, int major,
int minor, int micro)
{
if (pw_version->major != major)
return pw_version->major > major;
if (pw_version->minor != minor)
return pw_version->minor > minor;
return pw_version->micro >= micro;
}
static void update_pw_versions(obs_pipewire_data *obs_pw, const char *version)
{
blog(LOG_INFO, "[pipewire] server version: %s", version);
blog(LOG_INFO, "[pipewire] library version: %s",
pw_get_library_version());
blog(LOG_INFO, "[pipewire] header version: %s",
pw_get_headers_version());
if (!parse_pw_version(&obs_pw->server_version, version))
blog(LOG_WARNING, "[pipewire] failed to parse server version");
}
static const char *capture_type_to_string(enum obs_pw_capture_type capture_type)
{
switch (capture_type) {
@ -595,6 +634,13 @@ static const struct pw_stream_events stream_events = {
.process = on_process_cb,
};
static void on_core_info_cb(void *user_data, const struct pw_core_info *info)
{
obs_pipewire_data *obs_pw = user_data;
update_pw_versions(obs_pw, info->version);
}
static void on_core_error_cb(void *user_data, uint32_t id, int seq, int res,
const char *message)
{
@ -610,16 +656,15 @@ static void on_core_error_cb(void *user_data, uint32_t id, int seq, int res,
static void on_core_done_cb(void *user_data, uint32_t id, int seq)
{
UNUSED_PARAMETER(seq);
obs_pipewire_data *obs_pw = user_data;
if (id == PW_ID_CORE)
if (id == PW_ID_CORE && obs_pw->server_version_sync == seq)
pw_thread_loop_signal(obs_pw->thread_loop, FALSE);
}
static const struct pw_core_events core_events = {
PW_VERSION_CORE_EVENTS,
.info = on_core_info_cb,
.done = on_core_done_cb,
.error = on_core_error_cb,
};
@ -655,6 +700,11 @@ static void play_pipewire_stream(obs_pipewire_data *obs_pw)
pw_core_add_listener(obs_pw->core, &obs_pw->core_listener, &core_events,
obs_pw);
// Dispatch to receive the info core event
obs_pw->server_version_sync = pw_core_sync(obs_pw->core, PW_ID_CORE,
obs_pw->server_version_sync);
pw_thread_loop_wait(obs_pw->thread_loop);
/* Stream */
obs_pw->stream = pw_stream_new(
obs_pw->core, "OBS Studio",