screencast: relax buffer flip

In case a client doesn't return a buffer early enough we can give it a
second chance by triggering on_process before we pass the buffer to
wlroots in the frame_buffer_done event.
This commit is contained in:
columbarius 2022-03-02 18:06:22 +01:00
parent 074e62d0c3
commit ce9d77c90c
4 changed files with 20 additions and 0 deletions

View file

@ -131,6 +131,7 @@ struct xdpw_screencast_instance {
bool with_cursor; bool with_cursor;
int err; int err;
bool quit; bool quit;
bool need_buffer;
// fps limit // fps limit
struct fps_limit_state fps_limit; struct fps_limit_state fps_limit;

View file

@ -44,6 +44,18 @@ static struct spa_pod *build_format(struct spa_pod_builder *b, enum spa_video_fo
return spa_pod_builder_pop(b, &f[0]); return spa_pod_builder_pop(b, &f[0]);
} }
static void pwr_handle_stream_on_process(void *data) {
logprint(TRACE, "pipewire: stream process");
struct xdpw_screencast_instance *cast = data;
if (cast->need_buffer) {
xdpw_pwr_dequeue_buffer(cast);
if (cast->current_frame.pw_buffer) {
cast->need_buffer = false;
}
}
}
static void pwr_handle_stream_state_changed(void *data, static void pwr_handle_stream_state_changed(void *data,
enum pw_stream_state old, enum pw_stream_state state, const char *error) { enum pw_stream_state old, enum pw_stream_state state, const char *error) {
struct xdpw_screencast_instance *cast = data; struct xdpw_screencast_instance *cast = data;
@ -166,6 +178,7 @@ static const struct pw_stream_events pwr_stream_events = {
.param_changed = pwr_handle_stream_param_changed, .param_changed = pwr_handle_stream_param_changed,
.add_buffer = pwr_handle_stream_add_buffer, .add_buffer = pwr_handle_stream_add_buffer,
.remove_buffer = pwr_handle_stream_remove_buffer, .remove_buffer = pwr_handle_stream_remove_buffer,
.process = pwr_handle_stream_on_process,
}; };
void xdpw_pwr_dequeue_buffer(struct xdpw_screencast_instance *cast) { void xdpw_pwr_dequeue_buffer(struct xdpw_screencast_instance *cast) {
@ -240,7 +253,11 @@ void xdpw_pwr_swap_buffer(struct xdpw_screencast_instance *cast) {
dequeue_buffer: dequeue_buffer:
assert(!cast->current_frame.pw_buffer); assert(!cast->current_frame.pw_buffer);
cast->need_buffer = false;
xdpw_pwr_dequeue_buffer(cast); xdpw_pwr_dequeue_buffer(cast);
if (!cast->current_frame.pw_buffer) {
cast->need_buffer = true;
}
} }
void pwr_update_stream_param(struct xdpw_screencast_instance *cast) { void pwr_update_stream_param(struct xdpw_screencast_instance *cast) {

View file

@ -70,6 +70,7 @@ void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
cast->with_cursor = with_cursor; cast->with_cursor = with_cursor;
cast->refcount = 1; cast->refcount = 1;
cast->node_id = SPA_ID_INVALID; cast->node_id = SPA_ID_INVALID;
cast->need_buffer = false;
wl_list_init(&cast->buffer_list); wl_list_init(&cast->buffer_list);
logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount); logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount);
wl_list_insert(&ctx->screencast_instances, &cast->link); wl_list_insert(&ctx->screencast_instances, &cast->link);

View file

@ -130,6 +130,7 @@ static void wlr_frame_buffer_done(void *data,
xdpw_pwr_dequeue_buffer(cast); xdpw_pwr_dequeue_buffer(cast);
} }
cast->need_buffer = false;
if (!cast->current_frame.xdpw_buffer) { if (!cast->current_frame.xdpw_buffer) {
logprint(WARN, "wlroots: no current buffer"); logprint(WARN, "wlroots: no current buffer");
xdpw_wlr_frame_finish(cast); xdpw_wlr_frame_finish(cast);