Use variable framerate, add CLI option to override pixelformat metadata

This commit is contained in:
Dan Shick 2020-02-19 11:48:36 -05:00 committed by Simon Ser
parent 2a31d2d922
commit 7b699f3344
7 changed files with 84 additions and 28 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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,

View file

@ -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};

View file

@ -10,26 +10,36 @@ 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;
case WL_SHM_FORMAT_XRGB8888: case WL_SHM_FORMAT_XRGB8888:
return ctx->type.video_format.BGRx; return ctx->type.video_format.BGRx;
case WL_SHM_FORMAT_RGBA8888: case WL_SHM_FORMAT_RGBA8888:
return ctx->type.video_format.ABGR; return ctx->type.video_format.ABGR;
case WL_SHM_FORMAT_RGBX8888: case WL_SHM_FORMAT_RGBX8888:
return ctx->type.video_format.xBGR; return ctx->type.video_format.xBGR;
case WL_SHM_FORMAT_ABGR8888: case WL_SHM_FORMAT_ABGR8888:
return ctx->type.video_format.RGBA; return ctx->type.video_format.RGBA;
case WL_SHM_FORMAT_XBGR8888: case WL_SHM_FORMAT_XBGR8888:
return ctx->type.video_format.RGBx; return ctx->type.video_format.RGBx;
case WL_SHM_FORMAT_BGRA8888: case WL_SHM_FORMAT_BGRA8888:
return ctx->type.video_format.ARGB; return ctx->type.video_format.ARGB;
case WL_SHM_FORMAT_BGRX8888: case WL_SHM_FORMAT_BGRX8888:
return ctx->type.video_format.xRGB; return ctx->type.video_format.xRGB;
case WL_SHM_FORMAT_NV12: case WL_SHM_FORMAT_NV12:
return ctx->type.video_format.NV12; return ctx->type.video_format.NV12;
default: default:
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }

View file

@ -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;
} }
} }