Add pipewire plugin
It is quite similar to the remoting plugin. It just exports the frames via pipewire instead of the builtin GStreamer pipeline. It implements the same virtual output API. Virtual outputs can be created by adding 'pipewire-output' sections to weston.ini. The generated frames can be accessed with any pipewire client. e.g. with GStreamer: gst-launch-1.0 pipewiresrc ! video/x-raw,format=BGRx ! ... Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
This commit is contained in:
@@ -64,6 +64,7 @@
|
||||
#include <libweston/windowed-output-api.h>
|
||||
#include <libweston/weston-log.h>
|
||||
#include "../remoting/remoting-plugin.h"
|
||||
#include "../pipewire/pipewire-plugin.h"
|
||||
|
||||
#define WINDOW_TITLE "Weston Compositor"
|
||||
/* flight recorder size (in bytes) */
|
||||
@@ -2332,6 +2333,130 @@ load_remoting(struct weston_compositor *c, struct weston_config *wc)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
drm_backend_pipewire_output_configure(struct weston_output *output,
|
||||
struct weston_config_section *section,
|
||||
char *modeline,
|
||||
const struct weston_pipewire_api *api)
|
||||
{
|
||||
char *seat = NULL;
|
||||
int ret;
|
||||
|
||||
ret = api->set_mode(output, modeline);
|
||||
if (ret < 0) {
|
||||
weston_log("Cannot configure an output \"%s\" using "
|
||||
"weston_pipewire_api. Invalid mode\n",
|
||||
output->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wet_output_set_scale(output, section, 1, 0);
|
||||
wet_output_set_transform(output, section, WL_OUTPUT_TRANSFORM_NORMAL,
|
||||
UINT32_MAX);
|
||||
|
||||
weston_config_section_get_string(section, "seat", &seat, "");
|
||||
|
||||
api->set_seat(output, seat);
|
||||
free(seat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pipewire_output_init(struct weston_compositor *c,
|
||||
struct weston_config_section *section,
|
||||
const struct weston_pipewire_api *api)
|
||||
{
|
||||
struct weston_output *output = NULL;
|
||||
char *output_name, *modeline = NULL;
|
||||
int ret;
|
||||
|
||||
weston_config_section_get_string(section, "name", &output_name,
|
||||
NULL);
|
||||
if (!output_name)
|
||||
return;
|
||||
|
||||
weston_config_section_get_string(section, "mode", &modeline, "off");
|
||||
if (strcmp(modeline, "off") == 0)
|
||||
goto err;
|
||||
|
||||
output = api->create_output(c, output_name);
|
||||
if (!output) {
|
||||
weston_log("Cannot create pipewire output \"%s\".\n",
|
||||
output_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_backend_pipewire_output_configure(output, section, modeline,
|
||||
api);
|
||||
if (ret < 0) {
|
||||
weston_log("Cannot configure pipewire output \"%s\".\n",
|
||||
output_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (weston_output_enable(output) < 0) {
|
||||
weston_log("Enabling pipewire output \"%s\" failed.\n",
|
||||
output_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
free(modeline);
|
||||
free(output_name);
|
||||
weston_log("pipewire output '%s' enabled\n", output->name);
|
||||
return;
|
||||
|
||||
err:
|
||||
free(modeline);
|
||||
free(output_name);
|
||||
if (output)
|
||||
weston_output_destroy(output);
|
||||
}
|
||||
|
||||
static void
|
||||
load_pipewire(struct weston_compositor *c, struct weston_config *wc)
|
||||
{
|
||||
const struct weston_pipewire_api *api = NULL;
|
||||
int (*module_init)(struct weston_compositor *ec);
|
||||
struct weston_config_section *section = NULL;
|
||||
const char *section_name;
|
||||
|
||||
/* read pipewire-output section in weston.ini */
|
||||
while (weston_config_next_section(wc, §ion, §ion_name)) {
|
||||
if (strcmp(section_name, "pipewire-output"))
|
||||
continue;
|
||||
|
||||
if (!api) {
|
||||
char *module_name;
|
||||
struct weston_config_section *core_section =
|
||||
weston_config_get_section(wc, "core", NULL,
|
||||
NULL);
|
||||
|
||||
weston_config_section_get_string(core_section,
|
||||
"pipewire",
|
||||
&module_name,
|
||||
"pipewire-plugin.so");
|
||||
module_init = weston_load_module(module_name,
|
||||
"weston_module_init");
|
||||
free(module_name);
|
||||
if (!module_init) {
|
||||
weston_log("Can't load pipewire-plugin\n");
|
||||
return;
|
||||
}
|
||||
if (module_init(c) < 0) {
|
||||
weston_log("Pipewire-plugin init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
api = weston_pipewire_get_api(c);
|
||||
if (!api)
|
||||
return;
|
||||
}
|
||||
|
||||
pipewire_output_init(c, section, api);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
load_drm_backend(struct weston_compositor *c,
|
||||
int *argc, char **argv, struct weston_config *wc)
|
||||
@@ -2387,6 +2512,9 @@ load_drm_backend(struct weston_compositor *c,
|
||||
/* remoting */
|
||||
load_remoting(c, wc);
|
||||
|
||||
/* pipewire */
|
||||
load_pipewire(c, wc);
|
||||
|
||||
free(config.gbm_format);
|
||||
free(config.seat_id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user