Skip to content

Commit

Permalink
Change to self allocation of shm buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
columbarius committed Oct 27, 2020
1 parent 4127c55 commit 231e270
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
1 change: 1 addition & 0 deletions include/screencast_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ struct xdpw_wlr_output {
};

void randname(char *buf);
int anonymous_shm_open(void);
enum spa_video_format xdpw_format_pw_from_wl_shm(
struct xdpw_screencast_instance *cast);
enum spa_video_format xdpw_format_pw_strip_alpha(enum spa_video_format format);
Expand Down
37 changes: 34 additions & 3 deletions src/screencast/pipewire_screencast.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <spa/param/props.h>
#include <spa/param/format-utils.h>
#include <spa/param/video/format-utils.h>
#include <sys/mman.h>
#include <unistd.h>

#include "wlr_screencast.h"
#include "xdpw.h"
Expand Down Expand Up @@ -148,18 +150,47 @@ static void pwr_handle_stream_add_buffer(void *data, struct pw_buffer *buffer) {

// Prepare buffer for choosen type
if (d[0].type == SPA_DATA_MemPtr) {
d[0].type = SPA_DATA_MemFd;
d[0].maxsize = cast->simple_frame.size;
d[0].mapoffset = 0;
d[0].chunk->size = cast->simple_frame.size;
d[0].chunk->stride = cast->simple_frame.stride;
d[0].chunk->offset = 0;
d[0].flags = 0;
d[0].fd = -1;
d[0].flags = SPA_DATA_FLAG_READWRITE;
d[0].fd = anonymous_shm_open();

if (d[0].fd == -1) {
logprint(ERROR, "pipewire: unable to create anonymous filedescriptor");
return;
}

if (ftruncate(d[0].fd, d[0].maxsize) < 0) {
logprint(ERROR, "pipewire: unable to truncate filedescriptor");
return;
}

d[0].data = mmap(NULL, d[0].maxsize, PROT_READ | PROT_WRITE, MAP_SHARED, d[0].fd, d[0].mapoffset);
if (d[0].data == MAP_FAILED) {
logprint(ERROR, "pipewire: unable to mmap memory");
return;
}
}
}

static void pwr_handle_stream_remove_buffer(void *data, struct pw_buffer *buffer) {
struct spa_data *d;

logprint(TRACE, "pipewire: remove buffer event handle");

d = buffer->buffer->datas;
switch (d[0].type) {
case SPA_DATA_MemFd:
munmap(d[0].data, d[0].maxsize);
close(d[0].fd);
break;
default:
break;
}
}

static const struct pw_stream_events pwr_stream_events = {
Expand Down Expand Up @@ -228,7 +259,7 @@ void xdpw_pwr_stream_init(struct xdpw_screencast_instance *cast) {
pw_stream_connect(cast->stream,
PW_DIRECTION_OUTPUT,
PW_ID_ANY,
PW_STREAM_FLAG_DRIVER,
PW_STREAM_FLAG_DRIVER | PW_STREAM_FLAG_ALLOC_BUFFERS,
&param, 1);

}
Expand Down
23 changes: 23 additions & 0 deletions src/screencast/screencast_common.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "screencast_common.h"
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

void randname(char *buf) {
struct timespec ts;
Expand All @@ -12,6 +16,25 @@ void randname(char *buf) {
}
}

int anonymous_shm_open(void) {
char name[] = "/xdpw-shm-XXXXXX";
int retries = 100;

do {
randname(name + strlen(name) - 6);

--retries;
// shm_open guarantees that O_CLOEXEC is set
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd >= 0) {
shm_unlink(name);
return fd;
}
} while (retries > 0 && errno == EEXIST);

return -1;
}

enum spa_video_format xdpw_format_pw_from_wl_shm(
struct xdpw_screencast_instance *cast) {
switch (cast->simple_frame.format) {
Expand Down
19 changes: 0 additions & 19 deletions src/screencast/wlr_screencast.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,6 @@ void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) {
xdpw_wlr_register_cb(cast);
}

static int anonymous_shm_open(void) {
char name[] = "/xdpw-shm-XXXXXX";
int retries = 100;

do {
randname(name + strlen(name) - 6);

--retries;
// shm_open guarantees that O_CLOEXEC is set
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd >= 0) {
shm_unlink(name);
return fd;
}
} while (retries > 0 && errno == EEXIST);

return -1;
}

static struct wl_buffer *create_shm_buffer(struct xdpw_screencast_instance *cast,
enum wl_shm_format fmt, int width, int height, int stride,
void **data_out) {
Expand Down

0 comments on commit 231e270

Please sign in to comment.