Skip to content

Commit

Permalink
linux-capture: Implement stream restoration
Browse files Browse the repository at this point in the history
With the version 4 of the screencast portal, it is now possible
to request and use restore tokens [1] so that apps can restore a
previously configured screencast session without user interaction.

Add the corresponding code to linux-capture's PipeWire source.
Store the restore token in the source data, since each restore
token corresponds to an OBS source, and use it as soon as we try
to create a new session. Implement the obs_source_info.save vfunc,
and save the restore token when it's received by the Start()
response using obs_source_save().

[1] flatpak/xdg-desktop-portal#638
  • Loading branch information
GeorgesStavracas authored and jp9000 committed Nov 24, 2021
1 parent 8537c75 commit 26f1bfd
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
6 changes: 6 additions & 0 deletions plugins/linux-capture/pipewire-capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ static void pipewire_capture_destroy(void *data)
obs_pipewire_destroy(data);
}

static void pipewire_capture_save(void *data, obs_data_t *settings)
{
obs_pipewire_save(data, settings);
}

static void pipewire_capture_get_defaults(obs_data_t *settings)
{
obs_pipewire_get_defaults(settings);
Expand Down Expand Up @@ -132,6 +137,7 @@ void pipewire_capture_load(void)
.get_name = pipewire_desktop_capture_get_name,
.create = pipewire_desktop_capture_create,
.destroy = pipewire_capture_destroy,
.save = pipewire_capture_save,
.get_defaults = pipewire_capture_get_defaults,
.get_properties = pipewire_capture_get_properties,
.update = pipewire_capture_update,
Expand Down
37 changes: 37 additions & 0 deletions plugins/linux-capture/pipewire.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct _obs_pipewire_data {

char *sender_name;
char *session_handle;
char *restore_token;

uint32_t pipewire_node;
int pipewire_fd;
Expand Down Expand Up @@ -808,6 +809,20 @@ static void on_start_response_received_cb(GDBusConnection *connection,
g_variant_iter_loop(&iter, "(u@a{sv})", &obs_pw->pipewire_node,
&stream_properties);

if (portal_get_screencast_version() >= 4) {
g_autoptr(GVariant) restore_token = NULL;

g_clear_pointer(&obs_pw->restore_token, bfree);

restore_token = g_variant_lookup_value(result, "restore_token",
G_VARIANT_TYPE_STRING);
if (restore_token)
obs_pw->restore_token = bstrdup(
g_variant_get_string(restore_token, NULL));

obs_source_save(obs_pw->source);
}

blog(LOG_INFO, "[pipewire] %s selected, setting up screencast",
capture_type_to_string(obs_pw->capture_type));

Expand Down Expand Up @@ -941,6 +956,16 @@ static void select_source(obs_pipewire_data *obs_pw)
g_variant_builder_add(&builder, "{sv}", "cursor_mode",
g_variant_new_uint32(1));

if (portal_get_screencast_version() >= 4) {
g_variant_builder_add(&builder, "{sv}", "persist_mode",
g_variant_new_uint32(2));
if (obs_pw->restore_token && *obs_pw->restore_token) {
g_variant_builder_add(
&builder, "{sv}", "restore_token",
g_variant_new_string(obs_pw->restore_token));
}
}

g_dbus_proxy_call(portal_get_dbus_proxy(), "SelectSources",
g_variant_new("(oa{sv})", obs_pw->session_handle,
&builder),
Expand Down Expand Up @@ -1104,6 +1129,8 @@ static bool reload_session_cb(obs_properties_t *properties,

obs_pipewire_data *obs_pw = data;

g_clear_pointer(&obs_pw->restore_token, bfree);

teardown_pipewire(obs_pw);
destroy_session(obs_pw);

Expand All @@ -1123,6 +1150,8 @@ void *obs_pipewire_create(enum obs_pw_capture_type capture_type,
obs_pw->settings = settings;
obs_pw->capture_type = capture_type;
obs_pw->cursor.visible = obs_data_get_bool(settings, "ShowCursor");
obs_pw->restore_token =
bstrdup(obs_data_get_string(settings, "RestoreToken"));

if (!init_obs_pipewire(obs_pw))
g_clear_pointer(&obs_pw, bfree);
Expand All @@ -1138,12 +1167,20 @@ void obs_pipewire_destroy(obs_pipewire_data *obs_pw)
teardown_pipewire(obs_pw);
destroy_session(obs_pw);

g_clear_pointer(&obs_pw->restore_token, bfree);

bfree(obs_pw);
}

void obs_pipewire_save(obs_pipewire_data *obs_pw, obs_data_t *settings)
{
obs_data_set_string(settings, "RestoreToken", obs_pw->restore_token);
}

void obs_pipewire_get_defaults(obs_data_t *settings)
{
obs_data_set_default_bool(settings, "ShowCursor", true);
obs_data_set_default_string(settings, "RestoreToken", NULL);
}

obs_properties_t *obs_pipewire_get_properties(obs_pipewire_data *obs_pw,
Expand Down
1 change: 1 addition & 0 deletions plugins/linux-capture/pipewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void *obs_pipewire_create(enum obs_pw_capture_type capture_type,

void obs_pipewire_destroy(obs_pipewire_data *obs_pw);

void obs_pipewire_save(obs_pipewire_data *obs_pw, obs_data_t *settings);
void obs_pipewire_get_defaults(obs_data_t *settings);

obs_properties_t *obs_pipewire_get_properties(obs_pipewire_data *obs_pw,
Expand Down

0 comments on commit 26f1bfd

Please sign in to comment.