mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-26 07:55:58 +01:00
Use variable framerate, add CLI option to override pixelformat metadata
This commit is contained in:
parent
2a31d2d922
commit
7b699f3344
7 changed files with 84 additions and 28 deletions
|
@ -45,7 +45,6 @@ struct screencast_context {
|
||||||
|
|
||||||
// pipewire
|
// pipewire
|
||||||
struct pwr_type type;
|
struct pwr_type type;
|
||||||
|
|
||||||
struct pw_main_loop *loop;
|
struct pw_main_loop *loop;
|
||||||
struct spa_source *event;
|
struct spa_source *event;
|
||||||
struct pw_core *core;
|
struct pw_core *core;
|
||||||
|
@ -57,13 +56,10 @@ struct screencast_context {
|
||||||
struct spa_video_info_raw pwr_format;
|
struct spa_video_info_raw pwr_format;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
uint32_t node_id;
|
uint32_t node_id;
|
||||||
|
|
||||||
bool stream_state;
|
bool stream_state;
|
||||||
|
|
||||||
pthread_t pwr_thread;
|
pthread_t pwr_thread;
|
||||||
|
|
||||||
// wlroots
|
// wlroots
|
||||||
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
struct wl_list output_list;
|
struct wl_list output_list;
|
||||||
struct wl_registry *registry;
|
struct wl_registry *registry;
|
||||||
|
@ -85,6 +81,9 @@ struct screencast_context {
|
||||||
// frame mutex
|
// frame mutex
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
|
|
||||||
|
// cli options
|
||||||
|
const char *forced_pixelformat;
|
||||||
|
|
||||||
// if something happens during capture
|
// if something happens during capture
|
||||||
int err;
|
int err;
|
||||||
bool quit;
|
bool quit;
|
||||||
|
|
|
@ -19,7 +19,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
int init_screenshot(sd_bus *bus);
|
int init_screenshot(sd_bus *bus);
|
||||||
int init_screencast(sd_bus *bus);
|
int init_screencast(sd_bus *bus, const char *forced_pixelformat);
|
||||||
|
|
||||||
struct xdpw_request *request_create(sd_bus *bus, const char *object_path);
|
struct xdpw_request *request_create(sd_bus *bus, const char *object_path);
|
||||||
void request_destroy(struct xdpw_request *req);
|
void request_destroy(struct xdpw_request *req);
|
||||||
|
|
|
@ -1,10 +1,52 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "xdpw.h"
|
#include "xdpw.h"
|
||||||
|
|
||||||
static const char service_name[] = "org.freedesktop.impl.portal.desktop.wlr";
|
static const char service_name[] = "org.freedesktop.impl.portal.desktop.wlr";
|
||||||
|
|
||||||
|
int xdpw_usage(FILE* stream, int rc)
|
||||||
|
{
|
||||||
|
static const char* usage =
|
||||||
|
"Usage: xdg-desktop-portal-wlr [options]\n"
|
||||||
|
"\n"
|
||||||
|
" -p,--pixelformat=BGRx|RGBx Force a pixelformat in pipewire\n"
|
||||||
|
" metadata (performs no conversion).\n"
|
||||||
|
" -h,--help Get help (this text).\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
fprintf(stream, "%s", usage);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
const char* forced_pixelformat = NULL;
|
||||||
|
|
||||||
|
static const char* shortopts = "p:h";
|
||||||
|
static const struct option longopts[] = {
|
||||||
|
{ "pixelformat", required_argument, NULL, 'p' },
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int c = getopt_long(argc, argv, shortopts, longopts, NULL);
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'p':
|
||||||
|
forced_pixelformat = optarg;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
return xdpw_usage(stdout, 0);
|
||||||
|
default:
|
||||||
|
return xdpw_usage(stderr, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
sd_bus *bus = NULL;
|
sd_bus *bus = NULL;
|
||||||
|
@ -15,7 +57,7 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
init_screenshot(bus);
|
init_screenshot(bus);
|
||||||
init_screencast(bus);
|
init_screencast(bus, forced_pixelformat);
|
||||||
|
|
||||||
ret = sd_bus_request_name(bus, service_name, 0);
|
ret = sd_bus_request_name(bus, service_name, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -174,6 +174,10 @@ static void pwr_handle_state_changed(void *data, enum pw_remote_state old,
|
||||||
&SPA_RECTANGLE(ctx->simple_frame.width, ctx->simple_frame.height),
|
&SPA_RECTANGLE(ctx->simple_frame.width, ctx->simple_frame.height),
|
||||||
SPA_POD_PROP_MIN_MAX(&SPA_RECTANGLE(1, 1), &SPA_RECTANGLE(4096, 4096)),
|
SPA_POD_PROP_MIN_MAX(&SPA_RECTANGLE(1, 1), &SPA_RECTANGLE(4096, 4096)),
|
||||||
":", ctx->type.format_video.framerate, "F",
|
":", ctx->type.format_video.framerate, "F",
|
||||||
|
// specify variable framerate
|
||||||
|
&SPA_FRACTION(0, 1),
|
||||||
|
":", ctx->type.format_video.max_framerate, "F",
|
||||||
|
// with a maximum at the wlroots specified hardware framerate
|
||||||
&SPA_FRACTION(ctx->framerate, 1));
|
&SPA_FRACTION(ctx->framerate, 1));
|
||||||
|
|
||||||
pw_stream_add_listener(ctx->stream, &ctx->stream_listener,
|
pw_stream_add_listener(ctx->stream, &ctx->stream_listener,
|
||||||
|
|
|
@ -300,11 +300,12 @@ static const sd_bus_vtable screencast_vtable[] = {
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
int init_screencast(sd_bus *bus) {
|
int init_screencast(sd_bus *bus, const char *forced_pixelformat) {
|
||||||
// TODO: cleanup
|
// TODO: cleanup
|
||||||
sd_bus_slot *slot = NULL;
|
sd_bus_slot *slot = NULL;
|
||||||
|
|
||||||
//struct screencast_context ctx = (struct screencast_context){0};
|
//struct screencast_context ctx = (struct screencast_context){0};
|
||||||
|
ctx.forced_pixelformat = forced_pixelformat;
|
||||||
ctx.simple_frame = (struct simple_frame){0};
|
ctx.simple_frame = (struct simple_frame){0};
|
||||||
ctx.simple_frame.damage = &(struct damage){0};
|
ctx.simple_frame.damage = &(struct damage){0};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,16 @@ char *strdup(const char *src) {
|
||||||
|
|
||||||
uint32_t pipewire_from_wl_shm(void *data) {
|
uint32_t pipewire_from_wl_shm(void *data) {
|
||||||
struct screencast_context *ctx = data;
|
struct screencast_context *ctx = data;
|
||||||
|
|
||||||
|
if(ctx->forced_pixelformat){
|
||||||
|
if(strcmp(ctx->forced_pixelformat, "BGRx") == 0) {
|
||||||
|
return ctx->type.video_format.BGRx;
|
||||||
|
}
|
||||||
|
if(strcmp(ctx->forced_pixelformat, "RGBx") == 0){
|
||||||
|
return ctx->type.video_format.RGBx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (ctx->simple_frame.format) {
|
switch (ctx->simple_frame.format) {
|
||||||
case WL_SHM_FORMAT_ARGB8888:
|
case WL_SHM_FORMAT_ARGB8888:
|
||||||
return ctx->type.video_format.BGRA;
|
return ctx->type.video_format.BGRA;
|
||||||
|
|
|
@ -161,7 +161,7 @@ static void wlr_output_handle_mode(void *data, struct wl_output *wl_output,
|
||||||
int32_t height, int32_t refresh) {
|
int32_t height, int32_t refresh) {
|
||||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||||
struct wayland_output *output = data;
|
struct wayland_output *output = data;
|
||||||
output->framerate = (float)refresh * 1000;
|
output->framerate = (float)refresh/1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue