mirror of
https://github.com/mpv-player/mpv
synced 2024-12-27 09:32:40 +00:00
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.
This commit is contained in:
parent
fd339e3f53
commit
2b58738545
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user