diff --git a/src/screencast/pipewire_screencast.c b/src/screencast/pipewire_screencast.c index ef8d7983..d8d2354c 100644 --- a/src/screencast/pipewire_screencast.c +++ b/src/screencast/pipewire_screencast.c @@ -12,22 +12,6 @@ #include "xdpw.h" #include "logger.h" -static void writeFrameData(void *pwFramePointer, void *wlrFramePointer, - uint32_t height, uint32_t stride, bool inverted) { - if (!inverted) { - memcpy(pwFramePointer, wlrFramePointer, height * stride); - return; - } - - for (size_t i = 0; i < (size_t)height; ++i) { - void *flippedWlrRowPointer = wlrFramePointer + ((height - i - 1) * stride); - void *pwRowPointer = pwFramePointer + (i * stride); - memcpy(pwRowPointer, flippedWlrRowPointer, stride); - } - - return; -} - static inline struct spa_pod *build_format(struct spa_pod_builder *b, uint32_t format, uint32_t width, uint32_t height, uint32_t framerate) { @@ -158,12 +142,9 @@ static void pwr_handle_stream_add_buffer(void *data, struct pw_buffer *buffer) { return; } - // mmap buffer, so we can use the data_ptr int on_process - 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; - } + // create wl_buffer + d[0].data = import_shm_buffer(cast, d[0].fd, cast->screencopy_frame.format, + cast->screencopy_frame.width, cast->screencopy_frame.height, cast->screencopy_frame.stride); } } @@ -175,7 +156,7 @@ static void pwr_handle_stream_remove_buffer(void *data, struct pw_buffer *buffer d = buffer->buffer->datas; switch (d[0].type) { case SPA_DATA_MemFd: - munmap(d[0].data, d[0].maxsize); + wl_buffer_destroy(d[0].data); close(d[0].fd); break; default: @@ -201,6 +182,7 @@ void xdpw_pwr_import_buffer(struct xdpw_screencast_instance *cast) { if ((pw_buf = pw_stream_dequeue_buffer(cast->stream)) == NULL) { logprint(WARN, "pipewire: out of buffers"); cast->simple_frame.current_pw_buffer = pw_buf; + cast->simple_frame.buffer = NULL; return; } @@ -209,6 +191,7 @@ void xdpw_pwr_import_buffer(struct xdpw_screencast_instance *cast) { cast->simple_frame.current_pw_buffer = pw_buf; cast->simple_frame.size = d[0].chunk->size; cast->simple_frame.stride = d[0].chunk->stride; + cast->simple_frame.buffer = d[0].data; } void xdpw_pwr_export_buffer(struct xdpw_screencast_instance *cast) { @@ -234,13 +217,10 @@ void xdpw_pwr_export_buffer(struct xdpw_screencast_instance *cast) { h->seq = cast->seq++; h->dts_offset = 0; } - if ((d[0].data) == NULL) { - logprint(TRACE, "pipewire: data pointer undefined"); - goto queue; - } - writeFrameData(d[0].data, cast->screencopy_frame.data, cast->screencopy_frame.height, - cast->screencopy_frame.stride, cast->screencopy_frame.y_invert); + if (cast->screencopy_frame.y_invert) { + //TODO: Flip buffer or set stride negative + } logprint(TRACE, "********************"); logprint(TRACE, "pipewire: pointer %p", d[0].data); @@ -251,10 +231,10 @@ void xdpw_pwr_export_buffer(struct xdpw_screencast_instance *cast) { logprint(TRACE, "pipewire: y_invert %d", cast->screencopy_frame.y_invert); logprint(TRACE, "********************"); -queue: pw_stream_queue_buffer(cast->stream, pw_buf); cast->simple_frame.current_pw_buffer = NULL; + cast->simple_frame.buffer = NULL; } void pwr_update_stream_param(struct xdpw_screencast_instance *cast) { diff --git a/src/screencast/wlr_screencast.c b/src/screencast/wlr_screencast.c index d62abc39..7f7abb7f 100644 --- a/src/screencast/wlr_screencast.c +++ b/src/screencast/wlr_screencast.c @@ -20,28 +20,9 @@ #include "logger.h" #include "fps_limit.h" -static void wlr_frame_buffer_destroy(struct xdpw_screencast_instance *cast) { - // Even though this check may be deemed unnecessary, - // this has been found to cause SEGFAULTs, like this one: - // https://github.com/emersion/xdg-desktop-portal-wlr/issues/50 - if (cast->screencopy_frame.data != NULL) { - munmap(cast->screencopy_frame.data, cast->screencopy_frame.size); - cast->screencopy_frame.data = NULL; - } - - if (cast->screencopy_frame.buffer != NULL) { - wl_buffer_destroy(cast->screencopy_frame.buffer); - cast->screencopy_frame.buffer = NULL; - } -} - void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) { zwlr_screencopy_frame_v1_destroy(cast->wlr_frame); cast->wlr_frame = NULL; - if (cast->quit || cast->err) { - wlr_frame_buffer_destroy(cast); - logprint(TRACE, "xdpw: screencopy_frame buffer destroyed"); - } logprint(TRACE, "wlroots: frame destroyed"); if (cast->quit || cast->err) { @@ -64,44 +45,6 @@ void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) { } } -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) { - struct xdpw_screencast_context *ctx = cast->ctx; - int size = stride * height; - - int fd = anonymous_shm_open(); - if (fd < 0) { - logprint(ERROR, "wlroots: shm_open failed"); - return NULL; - } - - int ret; - while ((ret = ftruncate(fd, size)) == EINTR); - - if (ret < 0) { - close(fd); - logprint(ERROR, "wlroots: ftruncate failed"); - return NULL; - } - - void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) { - logprint(ERROR, "wlroots: mmap failed: %m"); - close(fd); - return NULL; - } - - struct wl_shm_pool *pool = wl_shm_create_pool(ctx->shm, fd, size); - close(fd); - struct wl_buffer *buffer = - wl_shm_pool_create_buffer(pool, 0, width, height, stride, fmt); - wl_shm_pool_destroy(pool); - - *data_out = data; - return buffer; -} - static void wlr_frame_linux_dmabuf(void *data, struct zwlr_screencopy_frame_v1 *frame, uint32_t format, uint32_t width, uint32_t height) { @@ -142,7 +85,12 @@ static void wlr_frame_buffer_done(void *data, return; } - zwlr_screencopy_frame_v1_copy_with_damage(frame, cast->screencopy_frame.buffer); + if (cast->simple_frame.buffer == NULL) { + logprint(ERROR, "wlroots: imported buffer doesn't contain a wlr_buffer"); + abort(); + } + + zwlr_screencopy_frame_v1_copy_with_damage(frame, cast->simple_frame.buffer); logprint(TRACE, "wlroots: frame copied"); fps_limit_measure_start(&cast->fps_limit, cast->ctx->state->config->screencast_conf.max_fps); @@ -165,19 +113,6 @@ static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame, xdpw_pwr_import_buffer(cast); } - if (cast->screencopy_frame.buffer == NULL) { - logprint(DEBUG, "wlroots: create shm buffer"); - cast->screencopy_frame.buffer = create_shm_buffer(cast, format, width, height, - stride, &cast->screencopy_frame.data); - } else { - logprint(TRACE,"wlroots: shm buffer exists"); - } - - if (cast->screencopy_frame.buffer == NULL) { - logprint(ERROR, "wlroots: failed to create buffer"); - abort(); - } - if (zwlr_screencopy_manager_v1_get_version(cast->ctx->screencopy_manager) < 3) { wlr_frame_buffer_done(cast,frame); }