mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-07-08 20:05:52 +00:00
backend-pipewire: add PipeWire backend
Add a separate PipeWire backend based on the PipeWire plugin. The backend requires PipeWire 0.3.x. The PipeWire backend can be used as a standalone-backend backend for streaming and composing Wayland clients to PipeWire. The backend supports the on-demand creation of heads via the weston_pipewire_output_api_v1. It also supports per-output pixel format configuration via a gbm-format option. Multiple PipeWire outputs can be created by setting the num-outputs option in the [pipewire] section. Co-authored-by: Michael Tretter <m.tretter@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
This commit is contained in:
parent
bcacd9ec5a
commit
ebc3a22b09
|
@ -40,6 +40,7 @@ struct {
|
|||
} backend_name_map[] = {
|
||||
{ "drm", "drm-backend.so", WESTON_BACKEND_DRM },
|
||||
{ "headless", "headless-backend.so", WESTON_BACKEND_HEADLESS },
|
||||
{ "pipewire", "pipewire-backend.so", WESTON_BACKEND_PIPEWIRE },
|
||||
{ "rdp", "rdp-backend.so", WESTON_BACKEND_RDP },
|
||||
{ "vnc", "vnc-backend.so", WESTON_BACKEND_VNC },
|
||||
{ "wayland", "wayland-backend.so", WESTON_BACKEND_WAYLAND },
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
|
||||
#include <libweston/backend-drm.h>
|
||||
#include <libweston/backend-headless.h>
|
||||
#include <libweston/backend-pipewire.h>
|
||||
#include <libweston/backend-rdp.h>
|
||||
#include <libweston/backend-vnc.h>
|
||||
#include <libweston/backend-x11.h>
|
||||
|
@ -658,6 +659,9 @@ usage(int error_code)
|
|||
#if defined(BUILD_HEADLESS_COMPOSITOR)
|
||||
"\t\t\t\theadless\n"
|
||||
#endif
|
||||
#if defined(BUILD_PIPEWIRE_COMPOSITOR)
|
||||
"\t\t\t\tpipewire\n"
|
||||
#endif
|
||||
#if defined(BUILD_RDP_COMPOSITOR)
|
||||
"\t\t\t\trdp\n"
|
||||
#endif
|
||||
|
@ -721,6 +725,14 @@ usage(int error_code)
|
|||
"\n");
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_PIPEWIRE_COMPOSITOR)
|
||||
fprintf(out,
|
||||
"Options for pipewire\n\n"
|
||||
" --width=WIDTH\t\tWidth of desktop\n"
|
||||
" --height=HEIGHT\tHeight of desktop\n"
|
||||
"\n");
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_RDP_COMPOSITOR)
|
||||
fprintf(out,
|
||||
"Options for rdp:\n\n"
|
||||
|
@ -3071,6 +3083,98 @@ load_headless_backend(struct weston_compositor *c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pipewire_backend_output_configure(struct weston_output *output)
|
||||
{
|
||||
struct wet_output_config defaults = {
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
};
|
||||
struct wet_compositor *compositor = to_wet_compositor(output->compositor);
|
||||
struct wet_output_config *parsed_options = compositor->parsed_options;
|
||||
const struct weston_pipewire_output_api *api = weston_pipewire_output_get_api(output->compositor);
|
||||
struct weston_config *wc = wet_get_config(output->compositor);
|
||||
struct weston_config_section *section;
|
||||
char *gbm_format = NULL;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
assert(parsed_options);
|
||||
|
||||
if (!api) {
|
||||
weston_log("Cannot use weston_pipewire_output_api.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
section = weston_config_get_section(wc, "output", "name", output->name);
|
||||
|
||||
parse_simple_mode(output, section, &width, &height, &defaults,
|
||||
parsed_options);
|
||||
|
||||
if (section)
|
||||
weston_config_section_get_string(section, "gbm-format",
|
||||
&gbm_format, NULL);
|
||||
|
||||
weston_output_set_scale(output, 1);
|
||||
weston_output_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
|
||||
api->set_gbm_format(output, gbm_format);
|
||||
free(gbm_format);
|
||||
|
||||
if (api->output_set_size(output, width, height) < 0) {
|
||||
weston_log("Cannot configure output \"%s\" using weston_pipewire_output_api.\n",
|
||||
output->name);
|
||||
return -1;
|
||||
}
|
||||
weston_log("pipewire_backend_output_configure.. Done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
weston_pipewire_backend_config_init(struct weston_pipewire_backend_config *config)
|
||||
{
|
||||
config->base.struct_version = WESTON_PIPEWIRE_BACKEND_CONFIG_VERSION;
|
||||
config->base.struct_size = sizeof(struct weston_pipewire_backend_config);
|
||||
}
|
||||
|
||||
static int
|
||||
load_pipewire_backend(struct weston_compositor *c,
|
||||
int *argc, char *argv[], struct weston_config *wc,
|
||||
enum weston_renderer_type renderer)
|
||||
{
|
||||
struct weston_pipewire_backend_config config = {{ 0, }};
|
||||
struct weston_config_section *section;
|
||||
struct wet_output_config *parsed_options = wet_init_parsed_options(c);
|
||||
|
||||
if (!parsed_options)
|
||||
return -1;
|
||||
|
||||
weston_pipewire_backend_config_init(&config);
|
||||
|
||||
const struct weston_option pipewire_options[] = {
|
||||
{ WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
|
||||
{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
|
||||
};
|
||||
|
||||
parse_options(pipewire_options, ARRAY_LENGTH(pipewire_options), argc, argv);
|
||||
|
||||
config.renderer = renderer;
|
||||
|
||||
wet_set_simple_head_configurator(c, pipewire_backend_output_configure);
|
||||
|
||||
section = weston_config_get_section(wc, "core", NULL, NULL);
|
||||
weston_config_section_get_string(section, "gbm-format",
|
||||
&config.gbm_format, NULL);
|
||||
|
||||
section = weston_config_get_section(wc, "pipewire", NULL, NULL);
|
||||
weston_config_section_get_int(section, "num-outputs",
|
||||
&config.num_outputs, 1);
|
||||
|
||||
return weston_compositor_load_backend(c, WESTON_BACKEND_PIPEWIRE,
|
||||
&config.base);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
|
||||
{
|
||||
|
@ -3608,6 +3712,9 @@ load_backend(struct weston_compositor *compositor, const char *name,
|
|||
case WESTON_BACKEND_HEADLESS:
|
||||
return load_headless_backend(compositor, argc, argv, config,
|
||||
renderer);
|
||||
case WESTON_BACKEND_PIPEWIRE:
|
||||
return load_pipewire_backend(compositor, argc, argv, config,
|
||||
renderer);
|
||||
case WESTON_BACKEND_RDP:
|
||||
return load_rdp_backend(compositor, argc, argv, config,
|
||||
renderer);
|
||||
|
|
108
include/libweston/backend-pipewire.h
Normal file
108
include/libweston/backend-pipewire.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright © 2021-2023 Philipp Zabel <p.zabel@pengutronix.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WESTON_COMPOSITOR_PIPEWIRE_H
|
||||
#define WESTON_COMPOSITOR_PIPEWIRE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/plugin-registry.h>
|
||||
|
||||
#define WESTON_PIPEWIRE_OUTPUT_API_NAME "weston_pipewire_output_api_v1"
|
||||
|
||||
struct pipewire_config {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
uint32_t framerate;
|
||||
};
|
||||
|
||||
struct weston_pipewire_output_api {
|
||||
/** Create a new PipeWire head.
|
||||
*
|
||||
* \param compositor The compositor instance.
|
||||
* \param name Desired name for the new head
|
||||
* \param config The pipewire_config of the new head.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
void (*head_create)(struct weston_compositor *compositor,
|
||||
const char *name,
|
||||
const struct pipewire_config *config);
|
||||
|
||||
/** Set the size of a PipeWire output to the specified width and height.
|
||||
*
|
||||
* If the width or height are set to -1, the size of the underlying
|
||||
* PipeWire head will be used.
|
||||
*
|
||||
* \param output The weston output for which the size shall be set
|
||||
* \param width Desired width of the output
|
||||
* \param height Desired height of the output
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int (*output_set_size)(struct weston_output *output,
|
||||
int width, int height);
|
||||
|
||||
/** The pixel format to be used by the output.
|
||||
*
|
||||
* \param output The weston output for which the pixel format is set
|
||||
* \param gbm_format String representation of the pixel format
|
||||
*
|
||||
* Valid values for the gbm_format are:
|
||||
* - NULL - The format set at backend creation time will be used;
|
||||
* - "xrgb8888";
|
||||
* - "rgb565";
|
||||
*/
|
||||
void (*set_gbm_format)(struct weston_output *output,
|
||||
const char *gbm_format);
|
||||
};
|
||||
|
||||
static inline const struct weston_pipewire_output_api *
|
||||
weston_pipewire_output_get_api(struct weston_compositor *compositor)
|
||||
{
|
||||
const void *api;
|
||||
api = weston_plugin_api_get(compositor, WESTON_PIPEWIRE_OUTPUT_API_NAME,
|
||||
sizeof(struct weston_pipewire_output_api));
|
||||
|
||||
return (const struct weston_pipewire_output_api *)api;
|
||||
}
|
||||
|
||||
#define WESTON_PIPEWIRE_BACKEND_CONFIG_VERSION 1
|
||||
|
||||
struct weston_pipewire_backend_config {
|
||||
struct weston_backend_config base;
|
||||
enum weston_renderer_type renderer;
|
||||
char *gbm_format;
|
||||
int32_t num_outputs;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WESTON_COMPOSITOR_PIPEWIRE_H */
|
|
@ -2252,6 +2252,7 @@ weston_compositor_add_destroy_listener_once(struct weston_compositor *compositor
|
|||
enum weston_compositor_backend {
|
||||
WESTON_BACKEND_DRM,
|
||||
WESTON_BACKEND_HEADLESS,
|
||||
WESTON_BACKEND_PIPEWIRE,
|
||||
WESTON_BACKEND_RDP,
|
||||
WESTON_BACKEND_VNC,
|
||||
WESTON_BACKEND_WAYLAND,
|
||||
|
|
|
@ -15,6 +15,7 @@ install_headers(
|
|||
|
||||
backend_drm_h = files('backend-drm.h')
|
||||
backend_headless_h = files('backend-headless.h')
|
||||
backend_pipewire_h = files('backend-pipewire.h')
|
||||
backend_rdp_h = files('backend-rdp.h')
|
||||
backend_vnc_h = files('backend-vnc.h')
|
||||
backend_wayland_h = files('backend-wayland.h')
|
||||
|
|
35
libweston/backend-pipewire/meson.build
Normal file
35
libweston/backend-pipewire/meson.build
Normal file
|
@ -0,0 +1,35 @@
|
|||
if not get_option('backend-pipewire')
|
||||
subdir_done()
|
||||
endif
|
||||
user_hint = 'If you rather not build this, set \'-Dbackend-pipewire=false\'.'
|
||||
|
||||
config_h.set('BUILD_PIPEWIRE_COMPOSITOR', '1')
|
||||
|
||||
dep_libpipewire = dependency('libpipewire-0.3', required: false)
|
||||
if not dep_libpipewire.found()
|
||||
error('PipeWire backend requires libpipewire 0.3 which was not found. ' + user_hint)
|
||||
endif
|
||||
|
||||
dep_libspa = dependency('libspa-0.2', required: false)
|
||||
if not dep_libspa.found()
|
||||
error('Pipewire plugin requires libspa 0.2 which was not found. ' + user_hint)
|
||||
endif
|
||||
|
||||
deps_pipewire = [
|
||||
dep_libweston_private,
|
||||
dep_libpipewire,
|
||||
dep_libspa,
|
||||
dep_libdrm_headers,
|
||||
]
|
||||
|
||||
plugin_pipewire = shared_library(
|
||||
'pipewire-backend',
|
||||
[ 'pipewire.c' ],
|
||||
include_directories: common_inc,
|
||||
dependencies: deps_pipewire,
|
||||
name_prefix: '',
|
||||
install: true,
|
||||
install_dir: dir_module_libweston
|
||||
)
|
||||
env_modmap += 'pipewire-backend.so=@0@;'.format(plugin_pipewire.full_path())
|
||||
install_headers(backend_pipewire_h, subdir: dir_include_libweston_install)
|
1001
libweston/backend-pipewire/pipewire.c
Normal file
1001
libweston/backend-pipewire/pipewire.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -9024,6 +9024,7 @@ weston_compositor_get_user_data(struct weston_compositor *compositor)
|
|||
static const char * const backend_map[] = {
|
||||
[WESTON_BACKEND_DRM] = "drm-backend.so",
|
||||
[WESTON_BACKEND_HEADLESS] = "headless-backend.so",
|
||||
[WESTON_BACKEND_PIPEWIRE] = "pipewire-backend.so",
|
||||
[WESTON_BACKEND_RDP] = "rdp-backend.so",
|
||||
[WESTON_BACKEND_VNC] = "vnc-backend.so",
|
||||
[WESTON_BACKEND_WAYLAND] = "wayland-backend.so",
|
||||
|
|
|
@ -268,6 +268,7 @@ subdir('color-lcms')
|
|||
subdir('renderer-gl')
|
||||
subdir('backend-drm')
|
||||
subdir('backend-headless')
|
||||
subdir('backend-pipewire')
|
||||
subdir('backend-rdp')
|
||||
subdir('backend-vnc')
|
||||
subdir('backend-wayland')
|
||||
|
|
|
@ -20,6 +20,12 @@ option(
|
|||
value: true,
|
||||
description: 'Weston backend: headless (testing)'
|
||||
)
|
||||
option(
|
||||
'backend-pipewire',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'PipeWire backend: screencasting via PipeWire'
|
||||
)
|
||||
option(
|
||||
'backend-rdp',
|
||||
type: 'boolean',
|
||||
|
|
Loading…
Reference in New Issue
Block a user