Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions player/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>

#include <libavutil/rational.h>

#include "mpv_talloc.h"

#include "osdep/io.h"
Expand Down Expand Up @@ -174,6 +177,28 @@ void issue_refresh_seek(struct MPContext *mpctx, enum seek_precision min_prec)
queue_seek(mpctx, MPSEEK_ABSOLUTE, get_current_time(mpctx), min_prec, 0);
}

static void update_content_frame_rate(struct MPContext *mpctx, struct track *track)
{
struct voctrl_content_frame_rate frame_rate = {
.numerator = 0,
.denominator = 1,
};

if (track && track->vo_c && !track->image) {
double fps = track->vo_c->filter->container_fps;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we use estimated fps, if available? Container value is often invalid.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this rate should be what mpv is actually presenting at so estimated-vf-fps is the right value to use here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course it's different in display-resync mode, but as I understand we prefer content framerate as target and on top of that display-resync would work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I guess I'm not sure if reporting 23.976 in display-sync mode would confuse the compositor or not with this protocol. The content rate is that 23.976 number but we're technically drawing every vblank in that mode.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I think, it should mostly be used for frame rate adaptation on compositor side, so that it should presentation limit us, but I have not read it at all, so there is that.

if (fps > 0) {
AVRational rate = av_d2q(fps, INT_MAX);
if (rate.num > 0 && rate.den > 0) {
frame_rate.numerator = rate.num;
frame_rate.denominator = rate.den;
}
}
}

if (mpctx->video_out)
vo_control(mpctx->video_out, VOCTRL_CONTENT_FRAME_RATE, &frame_rate);
}

void update_content_type(struct MPContext *mpctx, struct track *track)
{
enum mp_content_type content_type;
Expand All @@ -186,6 +211,8 @@ void update_content_type(struct MPContext *mpctx, struct track *track)
}
if (mpctx->video_out)
vo_control(mpctx->video_out, VOCTRL_CONTENT_TYPE, &content_type);

update_content_frame_rate(mpctx, track);
}

void update_vo_playback_state(struct MPContext *mpctx)
Expand Down
9 changes: 9 additions & 0 deletions video/out/meson.build
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
fs = import('fs')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to use this module.


wl_protocol_dir = wayland['deps'][2].get_variable(pkgconfig: 'pkgdatadir', internal: 'pkgdatadir')
protocols = [[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
Expand All @@ -17,6 +19,13 @@ protocols = [[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
wl_protocols_source = []
wl_protocols_headers = []

features += {'wayland-protocols-content-frame-rate': fs.is_file(join_paths(
wl_protocol_dir, 'staging/content-frame-rate/content-frame-rate-v1.xml'))}

if features['wayland-protocols-content-frame-rate']
protocols += [[wl_protocol_dir, 'staging/content-frame-rate/content-frame-rate-v1.xml']]
endif

foreach v: ['1.39', '1.41', '1.44', '1.47', '1.48']
features += {'wayland-protocols-' + v.replace('.', '-'):
wayland['deps'][2].version().version_compare('>=' + v)}
Expand Down
6 changes: 6 additions & 0 deletions video/out/vo.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ enum mp_voctrl {
VOCTRL_SET_CURSOR_VISIBILITY, // bool*

VOCTRL_CONTENT_TYPE, // enum mp_content_type*
VOCTRL_CONTENT_FRAME_RATE, // struct voctrl_content_frame_rate*

VOCTRL_KILL_SCREENSAVER,
VOCTRL_RESTORE_SCREENSAVER,
Expand Down Expand Up @@ -142,6 +143,11 @@ enum mp_content_type {
MP_CONTENT_VIDEO,
};

struct voctrl_content_frame_rate {
uint32_t numerator;
uint32_t denominator;
};
Comment on lines +146 to +149

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this you could just use a uint32_t array.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to use double as in all other code. This needs to be converted only in wayland_common.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure either way is fine with me.


#define VO_TRUE true
#define VO_FALSE false
#define VO_ERROR -1
Expand Down
51 changes: 51 additions & 0 deletions video/out/wayland_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
#include "xdg-shell.h"
#include "viewporter.h"
#include "content-type-v1.h"
#if HAVE_WAYLAND_PROTOCOLS_CONTENT_FRAME_RATE
#include "content-frame-rate-v1.h"
#endif
#include "single-pixel-buffer-v1.h"
#include "fractional-scale-v1.h"
#include "tablet-unstable-v2.h"
Expand Down Expand Up @@ -2857,6 +2860,14 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, ver);
}

#if HAVE_WAYLAND_PROTOCOLS_CONTENT_FRAME_RATE
if (!strcmp(interface, wp_content_frame_rate_manager_v1_interface.name) && found++) {
ver = 1;
wl->content_frame_rate_manager = wl_registry_bind(
reg, id, &wp_content_frame_rate_manager_v1_interface, ver);
}
#endif

if (!strcmp(interface, wp_single_pixel_buffer_manager_v1_interface.name) && found++) {
ver = 1;
wl->single_pixel_manager = wl_registry_bind(reg, id, &wp_single_pixel_buffer_manager_v1_interface, ver);
Expand Down Expand Up @@ -3807,6 +3818,20 @@ static void set_content_type(struct vo_wayland_state *wl)
}
}

static void set_content_frame_rate(struct vo_wayland_state *wl)
{
#if HAVE_WAYLAND_PROTOCOLS_CONTENT_FRAME_RATE
if (!wl->content_frame_rate_manager || !wl->content_frame_rate)
return;

uint32_t den = wl->current_content_frame_rate_den ?
wl->current_content_frame_rate_den : 1;
Comment on lines +3827 to +3828

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it better to just initialize the value as 0/1 so you wouldn't need this check?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I will address it. thanks

wp_content_frame_rate_v1_set_frame_rate(
wl->content_frame_rate,
wl->current_content_frame_rate_num,
den);
#endif
}
static void set_cursor(struct vo_wayland_seat *s, struct wl_surface *cursor_surface,
int32_t hotspot_x, int32_t hotspot_y)
{
Expand Down Expand Up @@ -4277,6 +4302,13 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
set_content_type(wl);
return VO_TRUE;
}
case VOCTRL_CONTENT_FRAME_RATE: {
struct voctrl_content_frame_rate *content_frame_rate = arg;
wl->current_content_frame_rate_num = content_frame_rate->numerator;
wl->current_content_frame_rate_den = content_frame_rate->denominator;
set_content_frame_rate(wl);
return VO_TRUE;
}
case VOCTRL_GET_FOCUSED: {
*(bool *)arg = wl->focused;
return VO_TRUE;
Expand Down Expand Up @@ -4590,6 +4622,17 @@ bool vo_wayland_init(struct vo *vo)
wp_content_type_manager_v1_interface.name);
}

#if HAVE_WAYLAND_PROTOCOLS_CONTENT_FRAME_RATE
if (wl->content_frame_rate_manager) {
wl->content_frame_rate =
wp_content_frame_rate_manager_v1_get_surface_content_frame_rate(
wl->content_frame_rate_manager, wl->surface);
} else {
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_content_frame_rate_manager_v1_interface.name);
}
#endif

if (!wl->single_pixel_manager) {
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_single_pixel_buffer_manager_v1_interface.name);
Expand Down Expand Up @@ -4811,6 +4854,14 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->content_type_manager)
wp_content_type_manager_v1_destroy(wl->content_type_manager);

#if HAVE_WAYLAND_PROTOCOLS_CONTENT_FRAME_RATE
if (wl->content_frame_rate)
wp_content_frame_rate_v1_destroy(wl->content_frame_rate);

if (wl->content_frame_rate_manager)
wp_content_frame_rate_manager_v1_destroy(wl->content_frame_rate_manager);
#endif

if (wl->devman)
wl_data_device_manager_destroy(wl->devman);

Expand Down
6 changes: 6 additions & 0 deletions video/out/wayland_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ struct vo_wayland_state {
struct wp_content_type_v1 *content_type;
int current_content_type;

/* content-frame-rate */
struct wp_content_frame_rate_manager_v1 *content_frame_rate_manager;
struct wp_content_frame_rate_v1 *content_frame_rate;
uint32_t current_content_frame_rate_num;
uint32_t current_content_frame_rate_den;

/* cursor-shape */
struct wp_cursor_shape_manager_v1 *cursor_shape_manager;

Expand Down