mirror of
https://github.com/mpv-player/mpv
synced 2025-02-17 04:58:06 +00:00
VO: remove code duplication for setting up mp_osd_res
vo_opengl, vo_vdpau, vo_direct3d had the code for setting up mp_osd_res duplicated. Make things simpler by making calc_src_dst_rects() setup the full mp_osd_res structure, instead of just "borders". Also, rename that function to vo_get_src_dst_rects(), and make it use mp_rect. Remove vo_rect, which was annoying because it contains redundant members (width/height additional to right/bottom). Add code to print the video rect etc. in verbose mode. There should be no actual change how the video rects are calculated. The only exception are the bottom/right subtitle margins, which are now computed slightly differently, but that shouldn't matter.
This commit is contained in:
parent
3466057feb
commit
6f408d0d9d
@ -39,6 +39,7 @@
|
||||
#include "m_config.h"
|
||||
#include "mp_msg.h"
|
||||
#include "libmpcodecs/vfcap.h"
|
||||
#include "sub/sub.h"
|
||||
|
||||
#include "osdep/shmem.h"
|
||||
#ifdef CONFIG_X11
|
||||
@ -416,76 +417,91 @@ int lookup_keymap_table(const struct mp_keymap *map, int key) {
|
||||
return map->to;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief helper function for the kind of panscan-scaling that needs a source
|
||||
* and destination rectangle like Direct3D and VDPAU
|
||||
*/
|
||||
static void src_dst_split_scaling(int src_size, int dst_size, int scaled_src_size,
|
||||
int *src_start, int *src_end, int *dst_start, int *dst_end) {
|
||||
if (scaled_src_size > dst_size) {
|
||||
int border = src_size * (scaled_src_size - dst_size) / scaled_src_size;
|
||||
// round to a multiple of 2, this is at least needed for vo_direct3d and ATI cards
|
||||
border = (border / 2 + 1) & ~1;
|
||||
*src_start = border;
|
||||
*src_end = src_size - border;
|
||||
*dst_start = 0;
|
||||
*dst_end = dst_size;
|
||||
} else {
|
||||
*src_start = 0;
|
||||
*src_end = src_size;
|
||||
*dst_start = (dst_size - scaled_src_size) / 2;
|
||||
*dst_end = *dst_start + scaled_src_size;
|
||||
}
|
||||
static void print_video_rect(struct vo *vo, struct mp_rect src,
|
||||
struct mp_rect dst, struct mp_osd_res osd)
|
||||
{
|
||||
int lv = MSGL_V;
|
||||
|
||||
int sw = src.x1 - src.x0, sh = src.y1 - src.y0;
|
||||
int dw = dst.x1 - dst.x0, dh = dst.y1 - dst.y0;
|
||||
|
||||
mp_msg(MSGT_VO, lv, "[vo] Window size: %dx%d\n",
|
||||
vo->dwidth, vo->dheight);
|
||||
mp_msg(MSGT_VO, lv, "[vo] Video source: %dx%d (%dx%d)\n",
|
||||
vo->aspdat.orgw, vo->aspdat.orgh,
|
||||
vo->aspdat.prew, vo->aspdat.preh);
|
||||
mp_msg(MSGT_VO, lv, "[vo] Video display: (%d, %d) %dx%d -> (%d, %d) %dx%d\n",
|
||||
src.x0, src.y0, sw, sh, dst.x0, dst.y0, dw, dh);
|
||||
mp_msg(MSGT_VO, lv, "[vo] Video scale: %f/%f\n",
|
||||
(double)dw / sw, (double)dh / sh);
|
||||
mp_msg(MSGT_VO, lv, "[vo] OSD borders: l=%d t=%d r=%d b=%d\n",
|
||||
osd.ml, osd.mt, osd.mr, osd.mb);
|
||||
mp_msg(MSGT_VO, lv, "[vo] Video borders: l=%d t=%d r=%d b=%d\n",
|
||||
dst.x0, dst.y0, vo->dwidth - dst.x1, vo->dheight - dst.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the appropriate source and destination rectangle to
|
||||
* get a correctly scaled picture, including pan-scan.
|
||||
* Can be extended to take future cropping support into account.
|
||||
*
|
||||
* \param crop specifies the cropping border size in the left, right, top and bottom members, may be NULL
|
||||
* \param borders the border values as e.g. EOSD (ASS) and properly placed DVD highlight support requires,
|
||||
* may be NULL and only left and top are currently valid.
|
||||
*/
|
||||
void calc_src_dst_rects(struct vo *vo, int src_width, int src_height,
|
||||
struct vo_rect *src, struct vo_rect *dst,
|
||||
struct vo_rect *borders, const struct vo_rect *crop)
|
||||
static void src_dst_split_scaling(int src_size, int dst_size,
|
||||
int scaled_src_size, int *src_start,
|
||||
int *src_end, int *dst_start, int *dst_end)
|
||||
{
|
||||
static const struct vo_rect no_crop = {0, 0, 0, 0, 0, 0};
|
||||
int scaled_width = 0;
|
||||
int scaled_height = 0;
|
||||
if (!crop) crop = &no_crop;
|
||||
src_width -= crop->left + crop->right;
|
||||
src_height -= crop->top + crop->bottom;
|
||||
if (src_width < 2) src_width = 2;
|
||||
if (src_height < 2) src_height = 2;
|
||||
dst->left = 0; dst->right = vo->dwidth;
|
||||
dst->top = 0; dst->bottom = vo->dheight;
|
||||
src->left = 0; src->right = src_width;
|
||||
src->top = 0; src->bottom = src_height;
|
||||
if (borders) {
|
||||
borders->left = 0; borders->top = 0;
|
||||
}
|
||||
if (aspect_scaling()) {
|
||||
aspect(vo, &scaled_width, &scaled_height, A_WINZOOM);
|
||||
panscan_calc_windowed(vo);
|
||||
scaled_width += vo->panscan_x;
|
||||
scaled_height += vo->panscan_y;
|
||||
if (borders) {
|
||||
borders->left = (vo->dwidth - scaled_width ) / 2;
|
||||
borders->top = (vo->dheight - scaled_height) / 2;
|
||||
if (scaled_src_size > dst_size) {
|
||||
int border = src_size * (scaled_src_size - dst_size) / scaled_src_size;
|
||||
// round to a multiple of 2, this is at least needed for vo_direct3d
|
||||
// and ATI cards
|
||||
border = (border / 2 + 1) & ~1;
|
||||
*src_start = border;
|
||||
*src_end = src_size - border;
|
||||
*dst_start = 0;
|
||||
*dst_end = dst_size;
|
||||
} else {
|
||||
*src_start = 0;
|
||||
*src_end = src_size;
|
||||
*dst_start = (dst_size - scaled_src_size) / 2;
|
||||
*dst_end = *dst_start + scaled_src_size;
|
||||
}
|
||||
src_dst_split_scaling(src_width, vo->dwidth, scaled_width,
|
||||
&src->left, &src->right, &dst->left, &dst->right);
|
||||
src_dst_split_scaling(src_height, vo->dheight, scaled_height,
|
||||
&src->top, &src->bottom, &dst->top, &dst->bottom);
|
||||
}
|
||||
src->left += crop->left; src->right += crop->left;
|
||||
src->top += crop->top; src->bottom += crop->top;
|
||||
src->width = src->right - src->left;
|
||||
src->height = src->bottom - src->top;
|
||||
dst->width = dst->right - dst->left;
|
||||
dst->height = dst->bottom - dst->top;
|
||||
}
|
||||
|
||||
// Calculate the appropriate source and destination rectangle to
|
||||
// get a correctly scaled picture, including pan-scan.
|
||||
// out_src: visible part of the video
|
||||
// out_dst: area of screen covered by the video source rectangle
|
||||
// out_osd: OSD size, OSD margins, etc.
|
||||
void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src,
|
||||
struct mp_rect *out_dst, struct mp_osd_res *out_osd)
|
||||
{
|
||||
int src_w = vo->aspdat.orgw;
|
||||
int src_h = vo->aspdat.orgh;
|
||||
struct mp_rect dst = {0, 0, vo->dwidth, vo->dheight};
|
||||
struct mp_rect src = {0, 0, src_w, src_h};
|
||||
struct mp_osd_res osd = {
|
||||
.w = vo->dwidth,
|
||||
.h = vo->dheight,
|
||||
.display_par = vo->monitor_par,
|
||||
.video_par = vo->aspdat.par,
|
||||
};
|
||||
if (aspect_scaling()) {
|
||||
int scaled_width = 0, scaled_height = 0;
|
||||
aspect(vo, &scaled_width, &scaled_height, A_WINZOOM);
|
||||
panscan_calc_windowed(vo);
|
||||
scaled_width += vo->panscan_x;
|
||||
scaled_height += vo->panscan_y;
|
||||
int border_w = vo->dwidth - scaled_width;
|
||||
int border_h = vo->dheight - scaled_height;
|
||||
osd.ml = border_w / 2;
|
||||
osd.mt = border_h / 2;
|
||||
osd.mr = border_w - osd.ml;
|
||||
osd.mb = border_h - osd.mt;
|
||||
src_dst_split_scaling(src_w, vo->dwidth, scaled_width,
|
||||
&src.x0, &src.x1, &dst.x0, &dst.x1);
|
||||
src_dst_split_scaling(src_h, vo->dheight, scaled_height,
|
||||
&src.y0, &src.y1, &dst.y0, &dst.y1);
|
||||
}
|
||||
|
||||
*out_src = src;
|
||||
*out_dst = dst;
|
||||
*out_osd = osd;
|
||||
|
||||
print_video_rect(vo, src, dst, osd);
|
||||
}
|
||||
|
||||
// Return the window title the VO should set. Always returns a null terminated
|
||||
|
@ -257,7 +257,7 @@ struct vo {
|
||||
int event_fd; // check_events() should be called when this has input
|
||||
int registered_fd; // set to event_fd when registered in input system
|
||||
|
||||
// requested position/resolution
|
||||
// requested position/resolution (usually window position/window size)
|
||||
int dx;
|
||||
int dy;
|
||||
int dwidth;
|
||||
@ -338,14 +338,13 @@ struct mp_keymap {
|
||||
int to;
|
||||
};
|
||||
int lookup_keymap_table(const struct mp_keymap *map, int key);
|
||||
struct vo_rect {
|
||||
int left, right, top, bottom, width, height;
|
||||
};
|
||||
void calc_src_dst_rects(struct vo *vo, int src_width, int src_height,
|
||||
struct vo_rect *src, struct vo_rect *dst,
|
||||
struct vo_rect *borders, const struct vo_rect *crop);
|
||||
|
||||
void vo_mouse_movement(struct vo *vo, int posx, int posy);
|
||||
|
||||
struct mp_osd_res;
|
||||
void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src,
|
||||
struct mp_rect *out_dst, struct mp_osd_res *out_osd);
|
||||
|
||||
static inline int aspect_scaling(void)
|
||||
{
|
||||
return vo_keepaspect || vo_fs;
|
||||
|
@ -145,8 +145,7 @@ typedef struct d3d_priv {
|
||||
fullscreen */
|
||||
int src_width; /**< Source (movie) width */
|
||||
int src_height; /**< Source (movie) heigth */
|
||||
int border_x; /**< horizontal border value for OSD */
|
||||
int border_y; /**< vertical border value for OSD */
|
||||
struct mp_osd_res osd_res;
|
||||
int image_format; /**< mplayer image format */
|
||||
bool use_textures; /**< use 3D texture rendering, instead of
|
||||
StretchRect */
|
||||
@ -294,22 +293,18 @@ static bool d3d_begin_scene(d3d_priv *priv)
|
||||
*/
|
||||
static void calc_fs_rect(d3d_priv *priv)
|
||||
{
|
||||
struct vo_rect src_rect;
|
||||
struct vo_rect dst_rect;
|
||||
struct vo_rect borders;
|
||||
calc_src_dst_rects(priv->vo, priv->src_width, priv->src_height, &src_rect,
|
||||
&dst_rect, &borders, NULL);
|
||||
struct mp_rect src_rect;
|
||||
struct mp_rect dst_rect;
|
||||
vo_get_src_dst_rects(priv->vo, &src_rect, &dst_rect, &priv->osd_res);
|
||||
|
||||
priv->fs_movie_rect.left = dst_rect.left;
|
||||
priv->fs_movie_rect.right = dst_rect.right;
|
||||
priv->fs_movie_rect.top = dst_rect.top;
|
||||
priv->fs_movie_rect.bottom = dst_rect.bottom;
|
||||
priv->fs_panscan_rect.left = src_rect.left;
|
||||
priv->fs_panscan_rect.right = src_rect.right;
|
||||
priv->fs_panscan_rect.top = src_rect.top;
|
||||
priv->fs_panscan_rect.bottom = src_rect.bottom;
|
||||
priv->border_x = borders.left;
|
||||
priv->border_y = borders.top;
|
||||
priv->fs_movie_rect.left = dst_rect.x0;
|
||||
priv->fs_movie_rect.right = dst_rect.x1;
|
||||
priv->fs_movie_rect.top = dst_rect.y0;
|
||||
priv->fs_movie_rect.bottom = dst_rect.y1;
|
||||
priv->fs_panscan_rect.left = src_rect.x0;
|
||||
priv->fs_panscan_rect.right = src_rect.x1;
|
||||
priv->fs_panscan_rect.top = src_rect.y0;
|
||||
priv->fs_panscan_rect.bottom = src_rect.y1;
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V,
|
||||
"<vo_direct3d>Video rectangle: t: %ld, l: %ld, r: %ld, b:%ld\n",
|
||||
@ -2063,18 +2058,8 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
|
||||
if (!priv->d3d_device)
|
||||
return;
|
||||
|
||||
struct mp_osd_res res = {
|
||||
.w = vo->dwidth,
|
||||
.h = vo->dheight,
|
||||
.ml = priv->border_x,
|
||||
.mr = priv->border_x,
|
||||
.mt = priv->border_y,
|
||||
.mb = priv->border_y,
|
||||
.display_par = vo->monitor_par,
|
||||
.video_par = vo->aspdat.par,
|
||||
};
|
||||
|
||||
osd_draw(osd, res, osd->vo_pts, 0, osd_fmt_supported, draw_osd_cb, priv);
|
||||
osd_draw(osd, priv->osd_res, osd->vo_pts, 0, osd_fmt_supported,
|
||||
draw_osd_cb, priv);
|
||||
}
|
||||
|
||||
#define AUTHOR "Georgi Petrov (gogothebee) <gogothebee@gmail.com> and others"
|
||||
|
@ -219,9 +219,9 @@ struct gl_priv {
|
||||
int mpi_flipped;
|
||||
int vo_flipped;
|
||||
|
||||
struct vo_rect src_rect; // displayed part of the source video
|
||||
struct vo_rect dst_rect; // video rectangle on output window
|
||||
int border_x, border_y; // OSD borders
|
||||
struct mp_rect src_rect; // displayed part of the source video
|
||||
struct mp_rect dst_rect; // video rectangle on output window
|
||||
struct mp_osd_res osd_rect; // OSD size/margins
|
||||
int vp_x, vp_y, vp_w, vp_h; // GL viewport
|
||||
|
||||
int frames_rendered;
|
||||
@ -790,8 +790,10 @@ static void delete_shaders(struct gl_priv *p)
|
||||
|
||||
static double get_scale_factor(struct gl_priv *p)
|
||||
{
|
||||
double sx = p->dst_rect.width / (double)p->src_rect.width;
|
||||
double sy = p->dst_rect.height / (double)p->src_rect.height;
|
||||
double sx = (p->dst_rect.x1 - p->dst_rect.x0) /
|
||||
(double)(p->src_rect.x1 - p->src_rect.x0);
|
||||
double sy = (p->dst_rect.y1 - p->dst_rect.y0) /
|
||||
(double)(p->src_rect.y1 - p->src_rect.y0);
|
||||
// xxx: actually we should use different scalers in X/Y directions if the
|
||||
// scale factors are different due to anamorphic content
|
||||
return FFMIN(sx, sy);
|
||||
@ -1126,16 +1128,16 @@ static void do_render(struct gl_priv *p)
|
||||
gl->Enable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
if (p->stereo_mode) {
|
||||
int w = p->src_rect.width;
|
||||
int w = p->src_rect.x1 - p->src_rect.x0;
|
||||
int imgw = p->image_width;
|
||||
|
||||
glEnable3DLeft(gl, p->stereo_mode);
|
||||
|
||||
write_quad(vb,
|
||||
p->dst_rect.left, p->dst_rect.top,
|
||||
p->dst_rect.right, p->dst_rect.bottom,
|
||||
p->src_rect.left / 2, p->src_rect.top,
|
||||
p->src_rect.left / 2 + w / 2, p->src_rect.bottom,
|
||||
p->dst_rect.x0, p->dst_rect.y0,
|
||||
p->dst_rect.x1, p->dst_rect.y1,
|
||||
p->src_rect.x0 / 2, p->src_rect.y0,
|
||||
p->src_rect.x0 / 2 + w / 2, p->src_rect.y1,
|
||||
final_texw, final_texh,
|
||||
NULL, is_flipped);
|
||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||
@ -1143,10 +1145,10 @@ static void do_render(struct gl_priv *p)
|
||||
glEnable3DRight(gl, p->stereo_mode);
|
||||
|
||||
write_quad(vb,
|
||||
p->dst_rect.left, p->dst_rect.top,
|
||||
p->dst_rect.right, p->dst_rect.bottom,
|
||||
p->src_rect.left / 2 + imgw / 2, p->src_rect.top,
|
||||
p->src_rect.left / 2 + imgw / 2 + w / 2, p->src_rect.bottom,
|
||||
p->dst_rect.x0, p->dst_rect.y0,
|
||||
p->dst_rect.x1, p->dst_rect.y1,
|
||||
p->src_rect.x0 / 2 + imgw / 2, p->src_rect.y0,
|
||||
p->src_rect.x0 / 2 + imgw / 2 + w / 2, p->src_rect.y1,
|
||||
final_texw, final_texh,
|
||||
NULL, is_flipped);
|
||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||
@ -1154,10 +1156,10 @@ static void do_render(struct gl_priv *p)
|
||||
glDisable3D(gl, p->stereo_mode);
|
||||
} else {
|
||||
write_quad(vb,
|
||||
p->dst_rect.left, p->dst_rect.top,
|
||||
p->dst_rect.right, p->dst_rect.bottom,
|
||||
p->src_rect.left, p->src_rect.top,
|
||||
p->src_rect.right, p->src_rect.bottom,
|
||||
p->dst_rect.x0, p->dst_rect.y0,
|
||||
p->dst_rect.x1, p->dst_rect.y1,
|
||||
p->src_rect.x0, p->src_rect.y0,
|
||||
p->src_rect.x1, p->src_rect.y1,
|
||||
final_texw, final_texh,
|
||||
NULL, is_flipped);
|
||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||
@ -1174,15 +1176,16 @@ static void do_render(struct gl_priv *p)
|
||||
static void update_window_sized_objects(struct gl_priv *p)
|
||||
{
|
||||
if (p->scale_sep_program) {
|
||||
if (p->dst_rect.height > p->scale_sep_fbo.tex_h) {
|
||||
int h = p->dst_rect.y1 - p->dst_rect.y0;
|
||||
if (h > p->scale_sep_fbo.tex_h) {
|
||||
fbotex_uninit(p, &p->scale_sep_fbo);
|
||||
// Round up to an arbitrary alignment to make window resizing or
|
||||
// panscan controls smoother (less texture reallocations).
|
||||
int height = FFALIGN(p->dst_rect.height, 256);
|
||||
int height = FFALIGN(h, 256);
|
||||
fbotex_init(p, &p->scale_sep_fbo, p->image_width, height);
|
||||
}
|
||||
p->scale_sep_fbo.vp_w = p->image_width;
|
||||
p->scale_sep_fbo.vp_h = p->dst_rect.height;
|
||||
p->scale_sep_fbo.vp_h = h;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1196,11 +1199,7 @@ static void resize(struct gl_priv *p)
|
||||
p->vp_w = vo->dwidth, p->vp_h = vo->dheight;
|
||||
gl->Viewport(p->vp_x, p->vp_y, p->vp_w, p->vp_h);
|
||||
|
||||
struct vo_rect borders;
|
||||
calc_src_dst_rects(vo, p->image_width, p->image_height, &p->src_rect,
|
||||
&p->dst_rect, &borders, NULL);
|
||||
p->border_x = borders.left;
|
||||
p->border_y = borders.top;
|
||||
vo_get_src_dst_rects(vo, &p->src_rect, &p->dst_rect, &p->osd_rect);
|
||||
|
||||
bool need_scaler_reinit = false; // filter size change needed
|
||||
bool need_scaler_update = false; // filter LUT change needed
|
||||
@ -1242,9 +1241,9 @@ static void flip_page(struct vo *vo)
|
||||
|
||||
p->glctx->swapGlBuffers(p->glctx);
|
||||
|
||||
if (p->dst_rect.left > p->vp_x || p->dst_rect.top > p->vp_y
|
||||
|| p->dst_rect.right < p->vp_x + p->vp_w
|
||||
|| p->dst_rect.bottom < p->vp_y + p->vp_h)
|
||||
if (p->dst_rect.x0 > p->vp_x || p->dst_rect.y0 > p->vp_y
|
||||
|| p->dst_rect.x1 < p->vp_x + p->vp_w
|
||||
|| p->dst_rect.y1 < p->vp_y + p->vp_h)
|
||||
{
|
||||
gl->Clear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
@ -1449,18 +1448,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
|
||||
struct gl_priv *p = vo->priv;
|
||||
assert(p->osd);
|
||||
|
||||
struct mp_osd_res res = {
|
||||
.w = vo->dwidth,
|
||||
.h = vo->dheight,
|
||||
.ml = p->border_x,
|
||||
.mr = p->border_x,
|
||||
.mt = p->border_y,
|
||||
.mb = p->border_y,
|
||||
.display_par = vo->monitor_par,
|
||||
.video_par = vo->aspdat.par,
|
||||
};
|
||||
|
||||
osd_draw(osd, res, osd->vo_pts, 0, p->osd->formats, draw_osd_cb, p);
|
||||
osd_draw(osd, p->osd_rect, osd->vo_pts, 0, p->osd->formats, draw_osd_cb, p);
|
||||
}
|
||||
|
||||
// Disable features that are not supported with the current OpenGL version.
|
||||
|
@ -137,7 +137,7 @@ struct vdpctx {
|
||||
|
||||
VdpRect src_rect_vid;
|
||||
VdpRect out_rect_vid;
|
||||
int border_x, border_y;
|
||||
struct mp_osd_res osd_rect;
|
||||
|
||||
struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES];
|
||||
int surface_num;
|
||||
@ -370,21 +370,17 @@ static void resize(struct vo *vo)
|
||||
struct vdpctx *vc = vo->priv;
|
||||
struct vdp_functions *vdp = vc->vdp;
|
||||
VdpStatus vdp_st;
|
||||
struct vo_rect src_rect;
|
||||
struct vo_rect dst_rect;
|
||||
struct vo_rect borders;
|
||||
calc_src_dst_rects(vo, vc->vid_width, vc->vid_height, &src_rect, &dst_rect,
|
||||
&borders, NULL);
|
||||
vc->out_rect_vid.x0 = dst_rect.left;
|
||||
vc->out_rect_vid.x1 = dst_rect.right;
|
||||
vc->out_rect_vid.y0 = dst_rect.top;
|
||||
vc->out_rect_vid.y1 = dst_rect.bottom;
|
||||
vc->src_rect_vid.x0 = src_rect.left;
|
||||
vc->src_rect_vid.x1 = src_rect.right;
|
||||
vc->src_rect_vid.y0 = vc->flip ? src_rect.bottom : src_rect.top;
|
||||
vc->src_rect_vid.y1 = vc->flip ? src_rect.top : src_rect.bottom;
|
||||
vc->border_x = borders.left;
|
||||
vc->border_y = borders.top;
|
||||
struct mp_rect src_rect;
|
||||
struct mp_rect dst_rect;
|
||||
vo_get_src_dst_rects(vo, &src_rect, &dst_rect, &vc->osd_rect);
|
||||
vc->out_rect_vid.x0 = dst_rect.x0;
|
||||
vc->out_rect_vid.x1 = dst_rect.x1;
|
||||
vc->out_rect_vid.y0 = dst_rect.y0;
|
||||
vc->out_rect_vid.y1 = dst_rect.y1;
|
||||
vc->src_rect_vid.x0 = src_rect.x0;
|
||||
vc->src_rect_vid.x1 = src_rect.x1;
|
||||
vc->src_rect_vid.y0 = vc->flip ? src_rect.y1 : src_rect.y0;
|
||||
vc->src_rect_vid.y1 = vc->flip ? src_rect.y0 : src_rect.y1;
|
||||
|
||||
int flip_offset_ms = vo_fs ? vc->flip_offset_fs : vc->flip_offset_window;
|
||||
vo->flip_queue_offset = flip_offset_ms / 1000.;
|
||||
@ -1119,18 +1115,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
|
||||
[SUBBITMAP_RGBA] = true,
|
||||
};
|
||||
|
||||
struct mp_osd_res res = {
|
||||
.w = vo->dwidth,
|
||||
.h = vo->dheight,
|
||||
.ml = vc->border_x,
|
||||
.mr = vc->border_x,
|
||||
.mt = vc->border_y,
|
||||
.mb = vc->border_y,
|
||||
.display_par = vo->monitor_par,
|
||||
.video_par = vo->aspdat.par,
|
||||
};
|
||||
|
||||
osd_draw(osd, res, osd->vo_pts, 0, formats, draw_osd_cb, vo);
|
||||
osd_draw(osd, vc->osd_rect, osd->vo_pts, 0, formats, draw_osd_cb, vo);
|
||||
}
|
||||
|
||||
static int update_presentation_queue_status(struct vo *vo)
|
||||
|
@ -77,8 +77,8 @@ struct xvctx {
|
||||
uint32_t image_height;
|
||||
uint32_t image_format;
|
||||
int is_paused;
|
||||
struct vo_rect src_rect;
|
||||
struct vo_rect dst_rect;
|
||||
struct mp_rect src_rect;
|
||||
struct mp_rect dst_rect;
|
||||
uint32_t max_width, max_height; // zero means: not set
|
||||
int mode_switched;
|
||||
#ifdef HAVE_SHM
|
||||
@ -94,11 +94,16 @@ static void resize(struct vo *vo)
|
||||
{
|
||||
struct xvctx *ctx = vo->priv;
|
||||
|
||||
calc_src_dst_rects(vo, ctx->image_width, ctx->image_height, &ctx->src_rect,
|
||||
&ctx->dst_rect, NULL, NULL);
|
||||
struct vo_rect *dst = &ctx->dst_rect;
|
||||
vo_x11_clearwindow_part(vo, vo->x11->window, dst->width, dst->height);
|
||||
vo_xv_draw_colorkey(vo, dst->left, dst->top, dst->width, dst->height);
|
||||
// Can't be used, because the function calculates screen-space coordinates,
|
||||
// while we need video-space.
|
||||
struct mp_osd_res unused;
|
||||
|
||||
vo_get_src_dst_rects(vo, &ctx->src_rect, &ctx->dst_rect, &unused);
|
||||
|
||||
struct mp_rect *dst = &ctx->dst_rect;
|
||||
int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
|
||||
vo_x11_clearwindow_part(vo, vo->x11->window, dw, dh);
|
||||
vo_xv_draw_colorkey(vo, dst->x0, dst->y0, dw, dh);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -275,20 +280,22 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi)
|
||||
{
|
||||
struct xvctx *ctx = vo->priv;
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
struct vo_rect *src = &ctx->src_rect;
|
||||
struct vo_rect *dst = &ctx->dst_rect;
|
||||
struct mp_rect *src = &ctx->src_rect;
|
||||
struct mp_rect *dst = &ctx->dst_rect;
|
||||
int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
|
||||
int sw = src->x1 - src->x0, sh = src->y1 - src->y0;
|
||||
#ifdef HAVE_SHM
|
||||
if (ctx->Shmem_Flag) {
|
||||
XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi,
|
||||
src->left, src->top, src->width, src->height,
|
||||
dst->left, dst->top, dst->width, dst->height,
|
||||
src->x0, src->y0, sw, sh,
|
||||
dst->x0, dst->y0, dw, dh,
|
||||
False);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi,
|
||||
src->left, src->top, src->width, src->height,
|
||||
dst->left, dst->top, dst->width, dst->height);
|
||||
src->x0, src->y0, sw, sh,
|
||||
dst->x0, dst->y0, dw, dh);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,9 +347,11 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
|
||||
|
||||
struct mp_image img = get_xv_buffer(vo, ctx->current_buf);
|
||||
|
||||
struct vo_rect *src = &ctx->src_rect;
|
||||
struct vo_rect *dst = &ctx->dst_rect;
|
||||
double xvpar = (double)dst->width / dst->height * src->height / src->width;
|
||||
struct mp_rect *src = &ctx->src_rect;
|
||||
struct mp_rect *dst = &ctx->dst_rect;
|
||||
int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
|
||||
int sw = src->x1 - src->x0, sh = src->y1 - src->y0;
|
||||
double xvpar = (double)dw / dh * sh / sw;
|
||||
|
||||
struct mp_osd_res res = {
|
||||
.w = ctx->image_width,
|
||||
|
Loading…
Reference in New Issue
Block a user