summaryrefslogtreecommitdiffstats
path: root/video/out/vo_wayland.c
diff options
context:
space:
mode:
authorAlexander Preisinger <alexander.preisinger@gmail.com>2014-03-06 14:24:34 +0100
committerAlexander Preisinger <alexander.preisinger@gmail.com>2014-09-21 09:14:33 +0200
commitf1906e684ae16fd120e2054840f252419910a1c5 (patch)
tree0decccd260bdd72e60ffbadcb21d0e79a20371cc /video/out/vo_wayland.c
parent9f7e1cf70a18f3370b439486dabe3cf81c0296f6 (diff)
downloadmpv-wayland-next.tar.bz2
mpv-wayland-next.tar.xz
wayland/shm: use wl_viewportwayland-next
Lets the compositor scale the video. This relies on the compositors scaling mechanism and efficiency. But should by far more efficient than ffmpeg scaling which burns CPU. In my tests mpv went from 66 % cpu load to 9 %. But the scaling wasn't as nice as ffmpegs. Falls back to software scaling if the compositor dosen't advertise the wl_scaler interface.
Diffstat (limited to 'video/out/vo_wayland.c')
-rw-r--r--video/out/vo_wayland.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c
index 0bb1934c05..3b08735050 100644
--- a/video/out/vo_wayland.c
+++ b/video/out/vo_wayland.c
@@ -105,6 +105,8 @@ struct priv {
struct vo *vo;
struct vo_wayland_state *wl;
+ struct wl_viewport *viewport; // optional scaler in case swscale is not available
+
struct wl_list format_list;
const format_t *video_format; // pointer to element in supported_format list
@@ -137,6 +139,7 @@ struct priv {
// options
int enable_alpha;
int use_rgb565;
+ int use_viewport;
};
static bool is_alpha_format(const format_t *fmt)
@@ -297,22 +300,42 @@ static bool resize(struct priv *p)
mp_sws_set_from_cmdline(p->sws, p->vo->opts->sws_opts);
p->sws->src = p->in_format;
- p->sws->dst = (struct mp_image_params) {
- .imgfmt = p->video_format->mp_format,
- .w = p->dst_w,
- .h = p->dst_h,
- .d_w = p->dst_w,
- .d_h = p->dst_h,
- };
+ if (p->use_viewport) {
+ p->sws->dst = (struct mp_image_params) {
+ .imgfmt = p->video_format->mp_format,
+ .w = p->width,
+ .h = p->height,
+ .d_w = p->width,
+ .d_h = p->height,
+ };
+ }
+ else {
+ p->sws->dst = (struct mp_image_params) {
+ .imgfmt = p->video_format->mp_format,
+ .w = p->dst_w,
+ .h = p->dst_h,
+ .d_w = p->dst_w,
+ .d_h = p->dst_h,
+ };
+ }
mp_image_params_guess_csp(&p->sws->dst);
if (mp_sws_reinit(p->sws) < 0)
return false;
- if (!buffer_pool_resize(&p->video_bufpool, p->dst_w, p->dst_h)) {
- MP_ERR(wl, "failed to resize video buffers\n");
- return false;
+ if (p->use_viewport) {
+ wl_viewport_set(p->viewport,
+ wl_fixed_from_int(0), wl_fixed_from_int(0),
+ wl_fixed_from_int(p->width), wl_fixed_from_int(p->height),
+ p->dst_w, p->dst_h);
+ }
+ else {
+ // use swscale
+ if (!buffer_pool_resize(&p->video_bufpool, p->dst_w, p->dst_h)) {
+ MP_ERR(wl, "failed to resize video buffers\n");
+ return false;
+ }
}
wl->window.width = p->dst_w;
@@ -615,6 +638,9 @@ static void uninit(struct vo *vo)
wl_surface_destroy(p->osd_surfaces[i]);
}
+ if (p->viewport)
+ wl_viewport_destroy(p->viewport);
+
vo_wayland_uninit(vo);
}
@@ -656,6 +682,16 @@ static int preinit(struct vo *vo)
}
wl_region_destroy(input);
+ if (p->use_viewport && wl->display.scaler == NULL) {
+ MP_WARN(wl, "No wl_scaler interface available\n"
+ "Falling back to software scaling\n");
+ p->use_viewport = 0;
+ }
+
+ if (p->use_viewport)
+ p->viewport = wl_scaler_get_viewport(wl->display.scaler,
+ wl->window.video_surface);
+
return 0;
}
@@ -709,7 +745,11 @@ const struct vo_driver video_out_wayland = {
.options = (const struct m_option[]) {
OPT_FLAG("alpha", enable_alpha, 0),
OPT_FLAG("rgb565", use_rgb565, 0),
+ OPT_FLAG("viewport", use_viewport, 0),
{0}
},
+ .priv_defaults = &(const struct priv) {
+ .use_viewport = 1
+ },
};