Remove thread for pipewire and all locking. Add support for elogind in meson.

This commit is contained in:
Dan Shick 2020-03-06 14:41:53 -05:00 committed by Simon Ser
parent b0c50ff911
commit eb229b708e
8 changed files with 42 additions and 37 deletions

View file

@ -14,5 +14,6 @@
#define ALIGN 16
void *pwr_start(void *data);
int pwr_dispatch(struct pw_loop *loop);
#endif

View file

@ -1,7 +1,6 @@
#ifndef SCREENCAST_COMMON_H
#define SCREENCAST_COMMON_H
#include <pthread.h>
#include <pipewire/pipewire.h>
#include <spa/param/video/format-utils.h>
#include <libdrm/drm_fourcc.h>
@ -42,7 +41,7 @@ struct screencast_context {
// pipewire
struct pwr_type type;
struct pw_main_loop *loop;
struct pw_loop *loop;
struct spa_source *event;
struct pw_core *core;
struct pw_type *t;
@ -54,7 +53,6 @@ struct screencast_context {
uint32_t seq;
uint32_t node_id;
bool stream_state;
pthread_t pwr_thread;
// wlroots
struct wl_display *display;
@ -76,9 +74,6 @@ struct screencast_context {
struct zwlr_screencopy_frame_v1 *wlr_frame;
struct simple_frame simple_frame;
// frame mutex
pthread_mutex_t lock;
// cli options
const char *output_name;
const char *forced_pixelformat;

View file

@ -16,6 +16,7 @@
#include <unistd.h>
#include <wayland-client-protocol.h>
#include "pipewire_screencast.h"
#include "screencast_common.h"
#define SC_MANAGER_VERSION 2

View file

@ -2,7 +2,11 @@
#define XDPW_H
#include <wayland-client.h>
#ifdef HAVE_SYSTEMD
#include <systemd/sd-bus.h>
#elif HAVE_ELOGIND
#include <elogind/sd-bus.h>
#endif
#include "logger.h"
struct xdpw_request {

View file

@ -28,7 +28,14 @@ pipewire = dependency('libpipewire-0.2')
spa = dependency('libspa-0.1')
wayland_client = dependency('wayland-client')
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
systemd = dependency('libsystemd')
logind = dependency('libsystemd', required: false)
if logind.found()
add_project_arguments('-DHAVE_SYSTEMD=1', language: 'c')
else
logind = dependency('libelogind')
add_project_arguments('-DHAVE_ELOGIND=1', language: 'c')
endif
subdir('protocols')
@ -48,7 +55,7 @@ executable(
dependencies: [
wayland_client,
wlr_protos,
systemd,
logind,
pipewire,
spa,
threads,

View file

@ -57,7 +57,6 @@ static void pwr_on_event(void *data, uint64_t expirations) {
d[0].type = ctx->t->data.MemPtr;
d[0].maxsize = ctx->simple_frame.size;
// d[0].data = ctx->simple_frame.data;
d[0].mapoffset = 0;
d[0].chunk->size = ctx->simple_frame.size;
d[0].chunk->stride = ctx->simple_frame.stride;
@ -152,7 +151,8 @@ static void pwr_handle_state_changed(void *data, enum pw_remote_state old,
logprint(INFO, "pipewire: remote state changed to \"%s\"",
pw_remote_state_as_string(state));
logprint(ERROR, "pipewire: remote error: %s", error);
pw_main_loop_quit(ctx->loop);
pw_loop_leave(ctx->loop);
pw_loop_destroy(ctx->loop);
break;
case PW_REMOTE_STATE_CONNECTED: {
@ -210,9 +210,12 @@ void *pwr_start(void *data) {
pw_init(NULL, NULL);
/* create a main loop */
ctx->loop = pw_main_loop_new(NULL);
ctx->core = pw_core_new(pw_main_loop_get_loop(ctx->loop), NULL);
/* create a loop */
ctx->loop = pw_loop_new(NULL);
pw_loop_enter(ctx->loop);
/* create a core, a remote, and initialize types */
ctx->core = pw_core_new(ctx->loop, NULL);
ctx->t = pw_core_get_type(ctx->core);
ctx->remote = pw_remote_new(ctx->core, NULL, 0);
@ -220,16 +223,22 @@ void *pwr_start(void *data) {
/* make an event to signal frame ready */
ctx->event =
pw_loop_add_event(pw_main_loop_get_loop(ctx->loop), pwr_on_event, ctx);
pw_loop_add_event(ctx->loop, pwr_on_event, ctx);
pw_remote_add_listener(ctx->remote, &ctx->remote_listener, &pwr_remote_events,
ctx);
pw_remote_connect(ctx->remote);
/* run the loop, this will trigger the callbacks */
pw_main_loop_run(ctx->loop);
pw_core_destroy(ctx->core);
pw_main_loop_destroy(ctx->loop);
return NULL;
}
int pwr_dispatch(struct pw_loop *loop) {
logprint(TRACE, "pipewire: dispatch");
int res;
res = pw_loop_iterate(loop, 0);
if (res < 0)
logprint(ERROR, "pw_loop_iterate failed: %s", spa_strerror(res));
return res;
}

View file

@ -42,17 +42,13 @@ void *start_screencast(void *data){
struct screencast_context *ctx = data;
pthread_mutex_init(&ctx->lock, NULL);
wlr_register_cb(ctx);
pthread_create(&ctx->pwr_thread, NULL, pwr_start, ctx);
pwr_start((void *) ctx);
/* Run capture */
while (wl_display_dispatch(ctx->display) != -1 && !ctx->err && !ctx->quit);
pthread_join(ctx->pwr_thread, NULL);
return NULL;
}
@ -310,7 +306,6 @@ int init_screencast(sd_bus *bus, const char *output_name, const char *forced_pix
// TODO: cleanup
sd_bus_slot *slot = NULL;
//struct screencast_context ctx = (struct screencast_context){0};
ctx.forced_pixelformat = forced_pixelformat;
ctx.output_name = output_name;
ctx.simple_frame = (struct simple_frame){0};

View file

@ -6,7 +6,6 @@ void wlr_frame_free(struct screencast_context *ctx) {
munmap(ctx->simple_frame.data, ctx->simple_frame.size);
wl_buffer_destroy(ctx->simple_frame.buffer);
logprint(TRACE, "wlroots: frame destroyed");
pthread_mutex_unlock(&ctx->lock);
}
@ -56,8 +55,6 @@ static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame,
uint32_t stride) {
struct screencast_context *ctx = data;
pthread_mutex_lock(&ctx->lock);
logprint(TRACE, "wlroots: buffer event handler");
ctx->wlr_frame = frame;
ctx->simple_frame.width = width;
@ -72,21 +69,16 @@ static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame,
exit(EXIT_FAILURE);
}
// zwlr_screencopy_frame_v1_copy(frame, ctx->simple_frame.buffer);
zwlr_screencopy_frame_v1_copy_with_damage(frame, ctx->simple_frame.buffer);
pthread_mutex_unlock(&ctx->lock);
}
static void wlr_frame_flags(void *data, struct zwlr_screencopy_frame_v1 *frame,
uint32_t flags) {
struct screencast_context *ctx = data;
pthread_mutex_lock(&ctx->lock);
logprint(TRACE, "wlroots: flags event handler");
ctx->simple_frame.y_invert = flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT;
pthread_mutex_unlock(&ctx->lock);
}
static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 *frame,
@ -94,16 +86,17 @@ static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 *frame,
uint32_t tv_nsec) {
struct screencast_context *ctx = data;
pthread_mutex_lock(&ctx->lock);
logprint(TRACE, "wlroots: ready event handler");
ctx->simple_frame.tv_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo);
ctx->simple_frame.tv_nsec = tv_nsec;
if (!ctx->quit && !ctx->err) {
pw_loop_signal_event(pw_main_loop_get_loop(ctx->loop), ctx->event);
// sleep(1);
pw_loop_signal_event(ctx->loop, ctx->event);
if(ctx->loop)
if(pwr_dispatch(ctx->loop) < 0) ctx->err = true;
wlr_register_cb(ctx);
}
}