summaryrefslogtreecommitdiffstats
path: root/video/out/vo_rpi.c
diff options
context:
space:
mode:
authorUros Vampl <mobile.leecher@gmail.com>2016-01-16 21:39:23 +0100
committerwm4 <wm4@nowhere>2016-02-05 17:49:43 +0100
commit2b58738545bdf86177515c6776ac9c36c2a742fb (patch)
treefa17cb60f898cd173aea641f485f4b75e0e0c70a /video/out/vo_rpi.c
parentfd339e3f53996efd2dae9525990da433d1e1bf89 (diff)
downloadmpv-2b58738545bdf86177515c6776ac9c36c2a742fb.tar.bz2
mpv-2b58738545bdf86177515c6776ac9c36c2a742fb.tar.xz
vo_rpi: add geometry handling
This makes it possible to set video size and position using the --geometry and/or --autofit options. It's also possible to switch between fullscreen/non-fullscreen playback during runtime.
Diffstat (limited to 'video/out/vo_rpi.c')
-rw-r--r--video/out/vo_rpi.c69
1 files changed, 59 insertions, 10 deletions
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
index b97f1fdb39..a3f104a13f 100644
--- a/video/out/vo_rpi.c
+++ b/video/out/vo_rpi.c
@@ -36,6 +36,7 @@
#include "common/msg.h"
#include "options/m_config.h"
#include "vo.h"
+#include "win_state.h"
#include "video/mp_image.h"
#include "sub/osd.h"
@@ -48,6 +49,7 @@ struct priv {
DISPMANX_ELEMENT_HANDLE_T osd_overlay;
DISPMANX_UPDATE_HANDLE_T update;
uint32_t w, h;
+ uint32_t x, y;
double display_fps;
double osd_pts;
@@ -156,7 +158,7 @@ static void update_osd(struct vo *vo)
}
gl_sc_set_vao(p->sc, mpgl_osd_get_vao(p->osd));
gl_sc_gen_shader_and_reset(p->sc);
- mpgl_osd_draw_part(p->osd, p->w, -p->h, n);
+ mpgl_osd_draw_part(p->osd, p->osd_res.w, -p->osd_res.h, n);
}
MP_STATS(vo, "stop rpi_osd");
@@ -185,15 +187,18 @@ static void resize(struct vo *vo)
.hdr = { .id = MMAL_PARAMETER_DISPLAYREGION,
.size = sizeof(MMAL_DISPLAYREGION_T), },
.src_rect = { .x = src.x0, .y = src.y0, .width = src_w, .height = src_h },
- .dest_rect = { .x = dst.x0, .y = dst.y0, .width = dst_w, .height = dst_h },
+ .dest_rect = { .x = dst.x0 + p->x, .y = dst.y0 + p->y,
+ .width = dst_w, .height = dst_h },
.layer = p->video_layer,
.display_num = p->display_nr,
.pixel_x = p_x,
.pixel_y = p_y,
.transform = rotate[vo->params ? vo->params->rotate / 90 : 0],
+ .fullscreen = vo->opts->fullscreen,
.set = MMAL_DISPLAY_SET_SRC_RECT | MMAL_DISPLAY_SET_DEST_RECT |
MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_NUM |
- MMAL_DISPLAY_SET_PIXEL | MMAL_DISPLAY_SET_TRANSFORM,
+ MMAL_DISPLAY_SET_PIXEL | MMAL_DISPLAY_SET_TRANSFORM |
+ MMAL_DISPLAY_SET_FULLSCREEN,
};
if (vo->params && (vo->params->rotate % 180) == 90) {
@@ -242,8 +247,15 @@ static int update_display_size(struct vo *vo)
MP_VERBOSE(vo, "Display size: %dx%d\n", p->w, p->h);
+ return 0;
+}
+
+static int create_overlays(struct vo *vo)
+{
+ struct priv *p = vo->priv;
destroy_overlays(vo);
+ if (vo->opts->fullscreen) {
// Use the whole screen.
VC_RECT_T dst = {.width = p->w, .height = p->h};
VC_RECT_T src = {.width = 1 << 16, .height = 1 << 16};
@@ -263,9 +275,13 @@ static int update_display_size(struct vo *vo)
return -1;
}
}
+ }
if (p->enable_osd) {
- alpha = (VC_DISPMANX_ALPHA_T){
+ VC_RECT_T dst = {.x = p->x, .y = p->y,
+ .width = p->osd_res.w, .height = p->osd_res.h};
+ VC_RECT_T src = {.width = p->osd_res.w << 16, .height = p->osd_res.h << 16};
+ VC_DISPMANX_ALPHA_T alpha = {
.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE,
.opacity = 0xFF,
};
@@ -279,7 +295,9 @@ static int update_display_size(struct vo *vo)
return -1;
}
- if (mp_egl_rpi_init(&p->egl, p->osd_overlay, p->w, p->h) < 0) {
+ if (mp_egl_rpi_init(&p->egl, p->osd_overlay,
+ p->osd_res.w, p->osd_res.h) < 0)
+ {
MP_FATAL(vo, "EGL/GLES initialization for OSD renderer failed.\n");
return -1;
}
@@ -314,6 +332,33 @@ static int update_display_size(struct vo *vo)
return 0;
}
+static int set_geometry(struct vo *vo)
+{
+ struct priv *p = vo->priv;
+
+ if (vo->opts->fullscreen) {
+ vo->dwidth = p->w;
+ vo->dheight = p->h;
+ p->x = p->y = 0;
+ } else {
+ struct vo_win_geometry geo;
+ struct mp_rect screenrc = {0, 0, p->w, p->h};
+
+ vo_calc_window_geometry(vo, &screenrc, &geo);
+ vo_apply_window_geometry(vo, &geo);
+
+ p->x = geo.win.x0;
+ p->y = geo.win.y0;
+ }
+
+ resize(vo);
+
+ if (create_overlays(vo) < 0)
+ return -1;
+
+ return 0;
+}
+
static void wait_next_vsync(struct vo *vo)
{
struct priv *p = vo->priv;
@@ -464,9 +509,6 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
MMAL_PORT_T *input = p->renderer->input[0];
bool opaque = params->imgfmt == IMGFMT_MMAL;
- vo->dwidth = p->w;
- vo->dheight = p->h;
-
disable_renderer(vo);
input->format->encoding = opaque ? MMAL_ENCODING_OPAQUE : MMAL_ENCODING_I420;
@@ -498,7 +540,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
}
}
- resize(vo);
+ if (set_geometry(vo) < 0)
+ return -1;
p->renderer_enabled = true;
@@ -552,6 +595,12 @@ static int control(struct vo *vo, uint32_t request, void *data)
struct priv *p = vo->priv;
switch (request) {
+ case VOCTRL_FULLSCREEN:
+ vo->opts->fullscreen = !vo->opts->fullscreen;
+ if (p->renderer_enabled)
+ set_geometry(vo);
+ vo->want_redraw = true;
+ return VO_TRUE;
case VOCTRL_GET_PANSCAN:
return VO_TRUE;
case VOCTRL_SET_PANSCAN:
@@ -571,7 +620,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
atomic_store(&p->update_display, false);
update_display_size(vo);
if (p->renderer_enabled)
- resize(vo);
+ set_geometry(vo);
}
return VO_TRUE;
case VOCTRL_GET_DISPLAY_FPS: