mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-22 22:35:59 +01:00
screencast: support modifiers in build_format
When announcing support for dmabufs via PipeWire this is done by adding the SPA_FORMAT_VIDEO_modifier property to an EnumFormat. Producers can choose between two different ways [1]: * Supporting only implicit modifiers by adding the property as a sigle value together with the SPA_POD_PROP_FLAG_MANDATORY flag * Support for multiple modifiers. This is done by announcing a SPA_CHOICE_ENUM array together with the use of the SPA_POD_PROP_FLAG_MANDATORY and SPA_POD_PROP_FLAG_DONT_FIXATE flag [1] https://docs.pipewire.org/page_dma_buf.html
This commit is contained in:
parent
6630525b7a
commit
bae393a684
1 changed files with 27 additions and 4 deletions
|
@ -8,6 +8,7 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <libdrm/drm_fourcc.h>
|
||||||
|
|
||||||
#include "wlr_screencast.h"
|
#include "wlr_screencast.h"
|
||||||
#include "xdpw.h"
|
#include "xdpw.h"
|
||||||
|
@ -35,8 +36,10 @@ static struct spa_pod *build_buffer(struct spa_pod_builder *b, uint32_t blocks,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spa_pod *build_format(struct spa_pod_builder *b, enum spa_video_format format,
|
static struct spa_pod *build_format(struct spa_pod_builder *b, enum spa_video_format format,
|
||||||
uint32_t width, uint32_t height, uint32_t framerate) {
|
uint32_t width, uint32_t height, uint32_t framerate,
|
||||||
struct spa_pod_frame f[1];
|
uint64_t *modifiers, int modifier_count) {
|
||||||
|
struct spa_pod_frame f[2];
|
||||||
|
int i, c;
|
||||||
|
|
||||||
enum spa_video_format format_without_alpha = xdpw_format_pw_strip_alpha(format);
|
enum spa_video_format format_without_alpha = xdpw_format_pw_strip_alpha(format);
|
||||||
|
|
||||||
|
@ -44,12 +47,31 @@ static struct spa_pod *build_format(struct spa_pod_builder *b, enum spa_video_fo
|
||||||
spa_pod_builder_add(b, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), 0);
|
spa_pod_builder_add(b, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), 0);
|
||||||
spa_pod_builder_add(b, SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), 0);
|
spa_pod_builder_add(b, SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), 0);
|
||||||
/* format */
|
/* format */
|
||||||
if (format_without_alpha == SPA_VIDEO_FORMAT_UNKNOWN) {
|
if (modifier_count > 0 || format_without_alpha == SPA_VIDEO_FORMAT_UNKNOWN) {
|
||||||
|
// modifiers are defined only in combinations with their format
|
||||||
|
// we should not announce the format without alpha
|
||||||
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format), 0);
|
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format), 0);
|
||||||
} else {
|
} else {
|
||||||
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_format,
|
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_format,
|
||||||
SPA_POD_CHOICE_ENUM_Id(3, format, format, format_without_alpha), 0);
|
SPA_POD_CHOICE_ENUM_Id(3, format, format, format_without_alpha), 0);
|
||||||
}
|
}
|
||||||
|
/* modifiers */
|
||||||
|
if (modifier_count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) {
|
||||||
|
// we only support implicit modifiers, use shortpath to skip fixation phase
|
||||||
|
spa_pod_builder_prop(b, SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY);
|
||||||
|
spa_pod_builder_long(b, modifiers[0]);
|
||||||
|
} else if (modifier_count > 0) {
|
||||||
|
// build an enumeration of modifiers
|
||||||
|
spa_pod_builder_prop(b, SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE);
|
||||||
|
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Enum, 0);
|
||||||
|
// modifiers from the array
|
||||||
|
for (i = 0, c = 0; i < modifier_count; i++) {
|
||||||
|
spa_pod_builder_long(b, modifiers[i]);
|
||||||
|
if (c++ == 0)
|
||||||
|
spa_pod_builder_long(b, modifiers[i]);
|
||||||
|
}
|
||||||
|
spa_pod_builder_pop(b, &f[1]);
|
||||||
|
}
|
||||||
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_size,
|
spa_pod_builder_add(b, SPA_FORMAT_VIDEO_size,
|
||||||
SPA_POD_Rectangle(&SPA_RECTANGLE(width, height)),
|
SPA_POD_Rectangle(&SPA_RECTANGLE(width, height)),
|
||||||
0);
|
0);
|
||||||
|
@ -69,7 +91,8 @@ static uint32_t build_formats(struct spa_pod_builder *b, struct xdpw_screencast_
|
||||||
const struct spa_pod *params[static 1]) {
|
const struct spa_pod *params[static 1]) {
|
||||||
uint32_t param_count = 1;
|
uint32_t 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, 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);
|
||||||
|
|
||||||
return param_count;
|
return param_count;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue