summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-27 22:10:32 +0200
committerwm4 <wm4@nowhere>2012-11-01 02:07:46 +0100
commit6f408d0d9d6d0655faec75474bc3074812b41826 (patch)
tree973ef09419d166790c4d909eb2bd90d8709278ab
parent3466057febaf5790b3ce88db1726058d9852f28d (diff)
downloadmpv-6f408d0d9d6d0655faec75474bc3074812b41826.tar.bz2
mpv-6f408d0d9d6d0655faec75474bc3074812b41826.tar.xz
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.
-rw-r--r--libvo/video_out.c148
-rw-r--r--libvo/video_out.h13
-rw-r--r--libvo/vo_direct3d.c45
-rw-r--r--libvo/vo_opengl.c70
-rw-r--r--libvo/vo_vdpau.c41
-rw-r--r--libvo/vo_xv.c41
6 files changed, 170 insertions, 188 deletions
diff --git a/libvo/video_out.c b/libvo/video_out.c
index c16968574d..59600e5ad6 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -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
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 5c8e10a008..4ea4144ffc 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -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;
diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c
index 5fc2a64893..294a101ffe 100644
--- a/libvo/vo_direct3d.c
+++ b/libvo/vo_direct3d.c
@@ -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);
-
- 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;
+ 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.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"
diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c
index eef7405561..261e1b102f 100644
--- a/libvo/vo_opengl.c
+++ b/libvo/vo_opengl.c
@@ -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.
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index dcd6bb321d..90c438e76f 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -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)
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 90eda230b8..de14f039f4 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -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,