mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-25 23:45:58 +01:00
screencast: use spa-pod-dynamic
This commit is contained in:
parent
78dee83d77
commit
7fc2e78581
1 changed files with 44 additions and 19 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <spa/param/props.h>
|
#include <spa/param/props.h>
|
||||||
#include <spa/param/format-utils.h>
|
#include <spa/param/format-utils.h>
|
||||||
#include <spa/param/video/format-utils.h>
|
#include <spa/param/video/format-utils.h>
|
||||||
|
#include <spa/pod/dynamic.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -139,7 +140,7 @@ static bool build_modifierlist(struct xdpw_screencast_instance *cast,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t build_formats(struct spa_pod_builder *b, struct xdpw_screencast_instance *cast,
|
static uint32_t build_formats(struct spa_pod_builder *b[static 2], struct xdpw_screencast_instance *cast,
|
||||||
const struct spa_pod *params[static 2]) {
|
const struct spa_pod *params[static 2]) {
|
||||||
uint32_t param_count;
|
uint32_t param_count;
|
||||||
uint32_t modifier_count;
|
uint32_t modifier_count;
|
||||||
|
@ -148,17 +149,20 @@ static uint32_t build_formats(struct spa_pod_builder *b, struct xdpw_screencast_
|
||||||
if (!cast->avoid_dmabufs &&
|
if (!cast->avoid_dmabufs &&
|
||||||
build_modifierlist(cast, cast->screencopy_frame_info[DMABUF].format, &modifiers, &modifier_count) && modifier_count > 0) {
|
build_modifierlist(cast, cast->screencopy_frame_info[DMABUF].format, &modifiers, &modifier_count) && modifier_count > 0) {
|
||||||
param_count = 2;
|
param_count = 2;
|
||||||
params[0] = build_format(b, xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[DMABUF].format),
|
params[0] = build_format(b[0], xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[DMABUF].format),
|
||||||
cast->screencopy_frame_info[DMABUF].width, cast->screencopy_frame_info[DMABUF].height, cast->framerate,
|
cast->screencopy_frame_info[DMABUF].width, cast->screencopy_frame_info[DMABUF].height, cast->framerate,
|
||||||
modifiers, modifier_count);
|
modifiers, modifier_count);
|
||||||
params[1] = build_format(b, xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format),
|
assert(params[0] != NULL);
|
||||||
|
params[1] = build_format(b[1], xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format),
|
||||||
cast->screencopy_frame_info[WL_SHM].width, cast->screencopy_frame_info[WL_SHM].height, cast->framerate,
|
cast->screencopy_frame_info[WL_SHM].width, cast->screencopy_frame_info[WL_SHM].height, cast->framerate,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
assert(params[1] != NULL);
|
||||||
} else {
|
} else {
|
||||||
param_count = 1;
|
param_count = 1;
|
||||||
params[0] = build_format(b, xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format),
|
params[0] = build_format(b[0], xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format),
|
||||||
cast->screencopy_frame_info[WL_SHM].width, cast->screencopy_frame_info[WL_SHM].height, cast->framerate,
|
cast->screencopy_frame_info[WL_SHM].width, cast->screencopy_frame_info[WL_SHM].height, cast->framerate,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
assert(params[0] != NULL);
|
||||||
}
|
}
|
||||||
free(modifiers);
|
free(modifiers);
|
||||||
return param_count;
|
return param_count;
|
||||||
|
@ -196,9 +200,8 @@ static void pwr_handle_stream_param_changed(void *data, uint32_t id,
|
||||||
logprint(TRACE, "pipewire: stream parameters changed");
|
logprint(TRACE, "pipewire: stream parameters changed");
|
||||||
struct xdpw_screencast_instance *cast = data;
|
struct xdpw_screencast_instance *cast = data;
|
||||||
struct pw_stream *stream = cast->stream;
|
struct pw_stream *stream = cast->stream;
|
||||||
uint8_t params_buffer[1024];
|
uint8_t params_buffer[3][1024];
|
||||||
struct spa_pod_builder b =
|
struct spa_pod_dynamic_builder b[3];
|
||||||
SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
|
|
||||||
const struct spa_pod *params[3];
|
const struct spa_pod *params[3];
|
||||||
uint32_t blocks;
|
uint32_t blocks;
|
||||||
uint32_t data_type;
|
uint32_t data_type;
|
||||||
|
@ -207,6 +210,10 @@ static void pwr_handle_stream_param_changed(void *data, uint32_t id,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spa_pod_dynamic_builder_init(&b[0], params_buffer[0], sizeof(params_buffer[0]), 2048);
|
||||||
|
spa_pod_dynamic_builder_init(&b[1], params_buffer[1], sizeof(params_buffer[1]), 2048);
|
||||||
|
spa_pod_dynamic_builder_init(&b[2], params_buffer[2], sizeof(params_buffer[2]), 2048);
|
||||||
|
|
||||||
spa_format_video_raw_parse(param, &cast->pwr_format);
|
spa_format_video_raw_parse(param, &cast->pwr_format);
|
||||||
cast->framerate = (uint32_t)(cast->pwr_format.max_framerate.num / cast->pwr_format.max_framerate.denom);
|
cast->framerate = (uint32_t)(cast->pwr_format.max_framerate.num / cast->pwr_format.max_framerate.denom);
|
||||||
|
|
||||||
|
@ -224,6 +231,7 @@ static void pwr_handle_stream_param_changed(void *data, uint32_t id,
|
||||||
uint32_t flags = GBM_BO_USE_RENDERING;
|
uint32_t flags = GBM_BO_USE_RENDERING;
|
||||||
uint64_t modifier;
|
uint64_t modifier;
|
||||||
uint32_t n_params;
|
uint32_t n_params;
|
||||||
|
struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b};
|
||||||
|
|
||||||
struct gbm_bo *bo = gbm_bo_create_with_modifiers2(cast->ctx->gbm,
|
struct gbm_bo *bo = gbm_bo_create_with_modifiers2(cast->ctx->gbm,
|
||||||
cast->screencopy_frame_info[cast->buffer_type].width, cast->screencopy_frame_info[cast->buffer_type].height,
|
cast->screencopy_frame_info[cast->buffer_type].width, cast->screencopy_frame_info[cast->buffer_type].height,
|
||||||
|
@ -260,18 +268,24 @@ static void pwr_handle_stream_param_changed(void *data, uint32_t id,
|
||||||
logprint(WARN, "pipewire: unable to allocate a dmabuf. Falling back to shm");
|
logprint(WARN, "pipewire: unable to allocate a dmabuf. Falling back to shm");
|
||||||
cast->avoid_dmabufs = true;
|
cast->avoid_dmabufs = true;
|
||||||
|
|
||||||
n_params = build_formats(&b, cast, ¶ms[0]);
|
n_params = build_formats(builder, cast, ¶ms[0]);
|
||||||
pw_stream_update_params(stream, params, n_params);
|
pw_stream_update_params(stream, params, n_params);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[0]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[1]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[2]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fixate_format:
|
fixate_format:
|
||||||
params[0] = fixate_format(&b, xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[cast->buffer_type].format),
|
params[0] = fixate_format(&b[2].b, xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[cast->buffer_type].format),
|
||||||
cast->screencopy_frame_info[cast->buffer_type].width, cast->screencopy_frame_info[cast->buffer_type].height, cast->framerate, &modifier);
|
cast->screencopy_frame_info[cast->buffer_type].width, cast->screencopy_frame_info[cast->buffer_type].height, cast->framerate, &modifier);
|
||||||
|
|
||||||
n_params = build_formats(&b, cast, ¶ms[1]);
|
n_params = build_formats(builder, cast, ¶ms[1]);
|
||||||
n_params++;
|
n_params++;
|
||||||
|
|
||||||
pw_stream_update_params(stream, params, n_params);
|
pw_stream_update_params(stream, params, n_params);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[0]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[1]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[2]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,15 +308,17 @@ fixate_format:
|
||||||
logprint(DEBUG, "pipewire: size: (%u, %u)", cast->pwr_format.size.width, cast->pwr_format.size.height);
|
logprint(DEBUG, "pipewire: size: (%u, %u)", cast->pwr_format.size.width, cast->pwr_format.size.height);
|
||||||
logprint(DEBUG, "pipewire: max_framerate: (%u / %u)", cast->pwr_format.max_framerate.num, cast->pwr_format.max_framerate.denom);
|
logprint(DEBUG, "pipewire: max_framerate: (%u / %u)", cast->pwr_format.max_framerate.num, cast->pwr_format.max_framerate.denom);
|
||||||
|
|
||||||
params[0] = build_buffer(&b, blocks, cast->screencopy_frame_info[cast->buffer_type].size,
|
params[0] = build_buffer(&b[0].b, blocks, cast->screencopy_frame_info[cast->buffer_type].size,
|
||||||
cast->screencopy_frame_info[cast->buffer_type].stride, data_type);
|
cast->screencopy_frame_info[cast->buffer_type].stride, data_type);
|
||||||
|
|
||||||
params[1] = spa_pod_builder_add_object(&b,
|
params[1] = spa_pod_builder_add_object(&b[1].b,
|
||||||
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
|
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
|
||||||
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
|
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
|
||||||
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
|
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
|
||||||
|
|
||||||
pw_stream_update_params(stream, params, 2);
|
pw_stream_update_params(stream, params, 2);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[0]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwr_handle_stream_add_buffer(void *data, struct pw_buffer *buffer) {
|
static void pwr_handle_stream_add_buffer(void *data, struct pw_buffer *buffer) {
|
||||||
|
@ -456,14 +472,18 @@ done:
|
||||||
void pwr_update_stream_param(struct xdpw_screencast_instance *cast) {
|
void pwr_update_stream_param(struct xdpw_screencast_instance *cast) {
|
||||||
logprint(TRACE, "pipewire: stream update parameters");
|
logprint(TRACE, "pipewire: stream update parameters");
|
||||||
struct pw_stream *stream = cast->stream;
|
struct pw_stream *stream = cast->stream;
|
||||||
uint8_t params_buffer[1024];
|
uint8_t params_buffer[2][1024];
|
||||||
struct spa_pod_builder b =
|
struct spa_pod_dynamic_builder b[2];
|
||||||
SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
|
spa_pod_dynamic_builder_init(&b[0], params_buffer[0], sizeof(params_buffer[0]), 2048);
|
||||||
|
spa_pod_dynamic_builder_init(&b[1], params_buffer[1], sizeof(params_buffer[1]), 2048);
|
||||||
const struct spa_pod *params[2];
|
const struct spa_pod *params[2];
|
||||||
|
|
||||||
uint32_t n_params = build_formats(&b, cast, params);
|
struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b};
|
||||||
|
uint32_t n_params = build_formats(builder, cast, params);
|
||||||
|
|
||||||
pw_stream_update_params(stream, params, n_params);
|
pw_stream_update_params(stream, params, n_params);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[0]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) {
|
void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) {
|
||||||
|
@ -472,8 +492,10 @@ void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) {
|
||||||
|
|
||||||
pw_loop_enter(state->pw_loop);
|
pw_loop_enter(state->pw_loop);
|
||||||
|
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[2][1024];
|
||||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
struct spa_pod_dynamic_builder b[2];
|
||||||
|
spa_pod_dynamic_builder_init(&b[0], buffer[0], sizeof(buffer[0]), 2048);
|
||||||
|
spa_pod_dynamic_builder_init(&b[1], buffer[1], sizeof(buffer[1]), 2048);
|
||||||
const struct spa_pod *params[2];
|
const struct spa_pod *params[2];
|
||||||
|
|
||||||
char name[] = "xdpw-stream-XXXXXX";
|
char name[] = "xdpw-stream-XXXXXX";
|
||||||
|
@ -489,7 +511,10 @@ void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) {
|
||||||
}
|
}
|
||||||
cast->pwr_stream_state = false;
|
cast->pwr_stream_state = false;
|
||||||
|
|
||||||
uint32_t param_count = build_formats(&b, cast, params);
|
struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b};
|
||||||
|
uint32_t param_count = build_formats(builder, cast, params);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[0]);
|
||||||
|
spa_pod_dynamic_builder_clean(&b[1]);
|
||||||
|
|
||||||
pw_stream_add_listener(cast->stream, &cast->stream_listener,
|
pw_stream_add_listener(cast->stream, &cast->stream_listener,
|
||||||
&pwr_stream_events, cast);
|
&pwr_stream_events, cast);
|
||||||
|
|
Loading…
Reference in a new issue