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
struct pwr_type type;
struct pw_main_loop *loop;
struct spa_source *event;
struct pw_core *core;
@ -57,13 +56,10 @@ struct screencast_context {
struct spa_video_info_raw pwr_format;
uint32_t seq;
uint32_t node_id;
bool stream_state;
pthread_t pwr_thread;
// wlroots
struct wl_display *display;
struct wl_list output_list;
struct wl_registry *registry;
@ -85,6 +81,9 @@ struct screencast_context {
// frame mutex
pthread_mutex_t lock;
// cli options
const char *forced_pixelformat;
// if something happens during capture
int err;
bool quit;

View file

@ -19,7 +19,7 @@ enum {
};
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);
void request_destroy(struct xdpw_request *req);

View file

@ -1,10 +1,52 @@
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include "xdpw.h"
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[]) {
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;
sd_bus *bus = NULL;
@ -15,7 +57,7 @@ int main(int argc, char *argv[]) {
}
init_screenshot(bus);
init_screencast(bus);
init_screencast(bus, forced_pixelformat);
ret = sd_bus_request_name(bus, service_name, 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_POD_PROP_MIN_MAX(&SPA_RECTANGLE(1, 1), &SPA_RECTANGLE(4096, 4096)),
":", 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));
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
};
int init_screencast(sd_bus *bus) {
int init_screencast(sd_bus *bus, const char *forced_pixelformat) {
// TODO: cleanup
sd_bus_slot *slot = NULL;
//struct screencast_context ctx = (struct screencast_context){0};
ctx.forced_pixelformat = forced_pixelformat;
ctx.simple_frame = (struct simple_frame){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) {
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) {
case WL_SHM_FORMAT_ARGB8888:
return ctx->type.video_format.BGRA;
case WL_SHM_FORMAT_XRGB8888:
return ctx->type.video_format.BGRx;
case WL_SHM_FORMAT_RGBA8888:
return ctx->type.video_format.ABGR;
case WL_SHM_FORMAT_RGBX8888:
return ctx->type.video_format.xBGR;
case WL_SHM_FORMAT_ABGR8888:
return ctx->type.video_format.RGBA;
case WL_SHM_FORMAT_XBGR8888:
return ctx->type.video_format.RGBx;
case WL_SHM_FORMAT_BGRA8888:
return ctx->type.video_format.ARGB;
case WL_SHM_FORMAT_BGRX8888:
return ctx->type.video_format.xRGB;
case WL_SHM_FORMAT_NV12:
return ctx->type.video_format.NV12;
default:
exit(EXIT_FAILURE);
case WL_SHM_FORMAT_ARGB8888:
return ctx->type.video_format.BGRA;
case WL_SHM_FORMAT_XRGB8888:
return ctx->type.video_format.BGRx;
case WL_SHM_FORMAT_RGBA8888:
return ctx->type.video_format.ABGR;
case WL_SHM_FORMAT_RGBX8888:
return ctx->type.video_format.xBGR;
case WL_SHM_FORMAT_ABGR8888:
return ctx->type.video_format.RGBA;
case WL_SHM_FORMAT_XBGR8888:
return ctx->type.video_format.RGBx;
case WL_SHM_FORMAT_BGRA8888:
return ctx->type.video_format.ARGB;
case WL_SHM_FORMAT_BGRX8888:
return ctx->type.video_format.xRGB;
case WL_SHM_FORMAT_NV12:
return ctx->type.video_format.NV12;
default:
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) {
if (flags & WL_OUTPUT_MODE_CURRENT) {
struct wayland_output *output = data;
output->framerate = (float)refresh * 1000;
output->framerate = (float)refresh/1000;
}
}