mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 00:02:13 +00:00
Add a calc_src_dst_rects that calculates from window size, panscan etc.
which part of the video source must be scaled onto which part of the window. Direct3D and (future) VDPAU need this, for XvMC it makes it easier to add cropping support and Xv is changed to keep the diff to XvMC small. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@28546 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8c2821f32d
commit
694c3dc03f
@ -355,6 +355,66 @@ int lookup_keymap_table(const struct 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop) {
|
||||
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 (vo_fs) {
|
||||
aspect(&scaled_width, &scaled_height, A_ZOOM);
|
||||
panscan_calc();
|
||||
scaled_width += vo_panscan_x;
|
||||
scaled_height += vo_panscan_y;
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FBDEV) || defined(CONFIG_VESA)
|
||||
/* Borrowed from vo_fbdev.c
|
||||
Monitor ranges related functions*/
|
||||
|
@ -269,5 +269,9 @@ struct keymap {
|
||||
int to;
|
||||
};
|
||||
int lookup_keymap_table(const struct keymap *map, int key);
|
||||
struct vo_rect {
|
||||
int left, right, top, bottom, width, height;
|
||||
};
|
||||
void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop);
|
||||
|
||||
#endif /* MPLAYER_VIDEO_OUT_H */
|
||||
|
@ -147,47 +147,18 @@ typedef enum back_buffer_action {
|
||||
*/
|
||||
static void calc_fs_rect(void)
|
||||
{
|
||||
int scaled_height = 0;
|
||||
int scaled_width = 0;
|
||||
struct vo_rect src_rect;
|
||||
struct vo_rect dst_rect;
|
||||
calc_src_dst_rects(priv->src_width, priv->src_height, &src_rect, &dst_rect, NULL);
|
||||
|
||||
// set default values
|
||||
priv->fs_movie_rect.left = 0;
|
||||
priv->fs_movie_rect.right = vo_dwidth;
|
||||
priv->fs_movie_rect.top = 0;
|
||||
priv->fs_movie_rect.bottom = vo_dheight;
|
||||
priv->fs_panscan_rect.left = 0;
|
||||
priv->fs_panscan_rect.right = priv->src_width;
|
||||
priv->fs_panscan_rect.top = 0;
|
||||
priv->fs_panscan_rect.bottom = priv->src_height;
|
||||
if (!vo_fs)
|
||||
return;
|
||||
|
||||
// adjust for fullscreen aspect and panscan
|
||||
aspect(&scaled_width, &scaled_height, A_ZOOM);
|
||||
panscan_calc();
|
||||
scaled_width += vo_panscan_x;
|
||||
scaled_height += vo_panscan_y;
|
||||
|
||||
// note: border is rounded to a multiple of two since at least
|
||||
// ATI drivers can not handle odd values with YV12 input
|
||||
if (scaled_width > vo_dwidth) {
|
||||
int border = priv->src_width * (scaled_width - vo_dwidth) / scaled_width;
|
||||
border = (border / 2 + 1) & ~1;
|
||||
priv->fs_panscan_rect.left = border;
|
||||
priv->fs_panscan_rect.right = priv->src_width - border;
|
||||
} else {
|
||||
priv->fs_movie_rect.left = (vo_dwidth - scaled_width) / 2;
|
||||
priv->fs_movie_rect.right = priv->fs_movie_rect.left + scaled_width;
|
||||
}
|
||||
if (scaled_height > vo_dheight) {
|
||||
int border = priv->src_height * (scaled_height - vo_dheight) / scaled_height;
|
||||
border = (border / 2 + 1) & ~1;
|
||||
priv->fs_panscan_rect.top = border;
|
||||
priv->fs_panscan_rect.bottom = priv->src_height - border;
|
||||
} else {
|
||||
priv->fs_movie_rect.top = (vo_dheight - scaled_height) / 2;
|
||||
priv->fs_movie_rect.bottom = priv->fs_movie_rect.top + scaled_height;
|
||||
}
|
||||
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;
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V,
|
||||
"<vo_direct3d>Fullscreen movie rectangle: t: %ld, l: %ld, r: %ld, b:%ld\n",
|
||||
|
@ -106,7 +106,8 @@ static uint32_t image_format;
|
||||
|
||||
static int int_pause;
|
||||
|
||||
static uint32_t drwX, drwY;
|
||||
static struct vo_rect src_rect;
|
||||
static struct vo_rect dst_rect;
|
||||
static uint32_t max_width = 0, max_height = 0; // zero means: not set
|
||||
|
||||
static void (*draw_alpha_fnc) (int x0, int y0, int w, int h,
|
||||
@ -158,6 +159,13 @@ static void draw_alpha_null(int x0, int y0, int w, int h,
|
||||
|
||||
static void deallocate_xvimage(int foo);
|
||||
|
||||
static void resize(void)
|
||||
{
|
||||
calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL);
|
||||
vo_x11_clearwindow_part(mDisplay, vo_window, dst_rect.width, dst_rect.height, 1);
|
||||
vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height);
|
||||
}
|
||||
|
||||
/*
|
||||
* connect to server, create and map window,
|
||||
* allocate colors and (shared) memory
|
||||
@ -288,17 +296,8 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
|
||||
current_ip_buf = 0;
|
||||
|
||||
if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;
|
||||
vo_calc_drwXY(&drwX, &drwY);
|
||||
|
||||
panscan_calc();
|
||||
|
||||
vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1),
|
||||
drwY - (vo_panscan_y >> 1),
|
||||
vo_dwidth + vo_panscan_x - 1,
|
||||
vo_dheight + vo_panscan_y - 1);
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX,
|
||||
drwY, vo_dwidth, vo_dheight);
|
||||
resize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -371,19 +370,17 @@ static inline void put_xvimage( XvImage * xvi )
|
||||
if (Shmem_Flag)
|
||||
{
|
||||
XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc,
|
||||
xvi, 0, 0, image_width,
|
||||
image_height, drwX - (vo_panscan_x >> 1),
|
||||
drwY - (vo_panscan_y >> 1), vo_dwidth + vo_panscan_x,
|
||||
vo_dheight + vo_panscan_y,
|
||||
xvi,
|
||||
src_rect.left, src_rect.top, src_rect.width, src_rect.height,
|
||||
dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height,
|
||||
False);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
XvPutImage(mDisplay, xv_port, vo_window, vo_gc,
|
||||
xvi, 0, 0, image_width, image_height,
|
||||
drwX - (vo_panscan_x >> 1), drwY - (vo_panscan_y >> 1),
|
||||
vo_dwidth + vo_panscan_x,
|
||||
vo_dheight + vo_panscan_y);
|
||||
xvi,
|
||||
src_rect.left, src_rect.top, src_rect.width, src_rect.height,
|
||||
dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,17 +388,9 @@ static void check_events(void)
|
||||
{
|
||||
int e = vo_x11_check_events(mDisplay);
|
||||
|
||||
if (e & VO_EVENT_RESIZE)
|
||||
{
|
||||
vo_calc_drwXY(&drwX, &drwY);
|
||||
}
|
||||
|
||||
if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE)
|
||||
{
|
||||
vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1),
|
||||
drwY - (vo_panscan_y >> 1),
|
||||
vo_dwidth + vo_panscan_x - 1,
|
||||
vo_dheight + vo_panscan_y - 1);
|
||||
resize();
|
||||
}
|
||||
|
||||
if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause)
|
||||
@ -777,14 +766,7 @@ static int control(uint32_t request, void *data, ...)
|
||||
|
||||
if (old_y != vo_panscan_y)
|
||||
{
|
||||
vo_x11_clearwindow_part(mDisplay, vo_window,
|
||||
vo_dwidth + vo_panscan_x - 1,
|
||||
vo_dheight + vo_panscan_y - 1,
|
||||
1);
|
||||
vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1),
|
||||
drwY - (vo_panscan_y >> 1),
|
||||
vo_dwidth + vo_panscan_x - 1,
|
||||
vo_dheight + vo_panscan_y - 1);
|
||||
resize();
|
||||
flip_page();
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ static int top_field_first;
|
||||
|
||||
static int image_width,image_height;
|
||||
static int image_format;
|
||||
static uint32_t drwX,drwY;
|
||||
|
||||
#define NO_SUBPICTURE 0
|
||||
#define OVERLAY_SUBPICTURE 1
|
||||
@ -676,11 +675,6 @@ skip_surface_allocation:
|
||||
}
|
||||
|
||||
if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;
|
||||
vo_calc_drwXY(&drwX, &drwY);
|
||||
|
||||
panscan_calc();
|
||||
|
||||
mp_msg(MSGT_VO,MSGL_V, "[xvmc] dx: %d dy: %d dw: %d dh: %d\n",drwX,drwY,vo_dwidth,vo_dheight );
|
||||
|
||||
//end vo_xv
|
||||
|
||||
@ -950,19 +944,16 @@ int status,rez;
|
||||
static void put_xvmc_image(struct xvmc_render_state * p_render_surface,
|
||||
int draw_ck){
|
||||
int rez;
|
||||
int clipX,clipY,clipW,clipH;
|
||||
struct vo_rect src_rect, dst_rect;
|
||||
int i;
|
||||
|
||||
if(p_render_surface == NULL)
|
||||
return;
|
||||
|
||||
clipX = drwX-(vo_panscan_x>>1);
|
||||
clipY = drwY-(vo_panscan_y>>1);
|
||||
clipW = vo_dwidth+vo_panscan_x;
|
||||
clipH = vo_dheight+vo_panscan_y;
|
||||
calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL);
|
||||
|
||||
if(draw_ck)
|
||||
vo_xv_draw_colorkey(clipX,clipY,clipW,clipH);
|
||||
vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height);
|
||||
|
||||
if(benchmark)
|
||||
return;
|
||||
@ -971,8 +962,8 @@ int i;
|
||||
int field = top_field_first ? i : i ^ 3;
|
||||
rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface,
|
||||
vo_window,
|
||||
0, 0, image_width, image_height,
|
||||
clipX, clipY, clipW, clipH,
|
||||
src_rect.left, src_rect.top, src_rect.width, src_rect.height,
|
||||
dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height,
|
||||
bob_deinterlace ? field : 3);
|
||||
//p_render_surface_to_show->display_flags);
|
||||
if(rez != Success){
|
||||
@ -1036,8 +1027,6 @@ int e=vo_x11_check_events(mDisplay);
|
||||
if(e&VO_EVENT_RESIZE)
|
||||
{
|
||||
e |= VO_EVENT_EXPOSE;
|
||||
|
||||
vo_calc_drwXY(&drwX, &drwY);
|
||||
}
|
||||
if ( e & VO_EVENT_EXPOSE )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user