mirror of
https://github.com/mpv-player/mpv
synced 2025-03-20 02:09:52 +00:00
screenshot: remove hack for passing anamorphic image size
With anamorphic video (display with non-1:1 PAR, e.g. DVD), the display size was passed using the mp_image fields w/h, which was blatantly incorrect. w/h are the normal image dimensions, while width/height are the "uncropped" storage size (used internally by vf.c). Add a display_w/h, and use that for the display size. Make all VOs that can do screenshots use it.
This commit is contained in:
parent
738aeb1c60
commit
c62efc52c6
@ -264,7 +264,9 @@ int write_image(struct mp_image *image, const struct image_writer_opts *opts,
|
||||
{
|
||||
struct mp_image *allocated_image = NULL;
|
||||
struct image_writer_opts defs = image_writer_opts_defaults;
|
||||
bool is_anamorphic = image->w != image->width || image->h != image->height;
|
||||
int d_w = image->display_w ? image->display_w : image->w;
|
||||
int d_h = image->display_h ? image->display_h : image->h;
|
||||
bool is_anamorphic = image->w != d_w || image->h != d_h;
|
||||
|
||||
if (!opts)
|
||||
opts = &defs;
|
||||
@ -287,17 +289,13 @@ int write_image(struct mp_image *image, const struct image_writer_opts *opts,
|
||||
// - RGB->YUV assumes BT.601
|
||||
// - color levels broken in various ways thanks to libswscale
|
||||
if (image->imgfmt != destfmt || is_anamorphic) {
|
||||
struct mp_image hack = *image;
|
||||
hack.w = hack.width;
|
||||
hack.h = hack.height;
|
||||
|
||||
struct mp_image *dst = alloc_mpi(image->w, image->h, destfmt);
|
||||
struct mp_image *dst = alloc_mpi(d_w, d_h, destfmt);
|
||||
vf_clone_mpi_attributes(dst, image);
|
||||
|
||||
int flags = SWS_LANCZOS | SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP |
|
||||
SWS_ACCURATE_RND | SWS_BITEXACT;
|
||||
|
||||
mp_image_swscale(dst, &hack, flags);
|
||||
mp_image_swscale(dst, image, flags);
|
||||
|
||||
allocated_image = dst;
|
||||
image = dst;
|
||||
|
@ -104,8 +104,9 @@ typedef struct mp_image {
|
||||
int number;
|
||||
unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8
|
||||
unsigned int imgfmt;
|
||||
int width,height; // stored dimensions
|
||||
int width,height; // internal to vf.c, do not use (stored dimensions)
|
||||
int w,h; // visible dimensions
|
||||
int display_w,display_h; // if set (!= 0), anamorphic size
|
||||
uint8_t *planes[MP_MAX_PLANES];
|
||||
int stride[MP_MAX_PLANES];
|
||||
char * qscale;
|
||||
|
@ -537,6 +537,8 @@ void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
|
||||
if (dst->width == src->width && dst->height == src->height) {
|
||||
dst->qstride = src->qstride;
|
||||
dst->qscale = src->qscale;
|
||||
dst->display_w = src->display_w;
|
||||
dst->display_h = src->display_h;
|
||||
}
|
||||
if ((dst->flags & MP_IMGFLAG_YUV) == (src->flags & MP_IMGFLAG_YUV)) {
|
||||
dst->colorspace = src->colorspace;
|
||||
|
@ -375,11 +375,8 @@ static mp_image_t *get_screenshot(struct vo *vo)
|
||||
memcpy(image->planes[0], base, image_size);
|
||||
image->stride[0] = stride;
|
||||
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
|
||||
image->w = vo->aspdat.prew;
|
||||
image->h = vo->aspdat.preh;
|
||||
image->display_w = vo->aspdat.prew;
|
||||
image->display_h = vo->aspdat.preh;
|
||||
|
||||
mp_image_set_colorspace_details(image, &p->colorspace);
|
||||
|
||||
|
@ -1801,8 +1801,8 @@ static mp_image_t *get_screenshot(d3d_priv *priv)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image->w = priv->vo->aspdat.prew;
|
||||
image->h = priv->vo->aspdat.preh;
|
||||
image->display_w = priv->vo->aspdat.prew;
|
||||
image->display_h = priv->vo->aspdat.preh;
|
||||
|
||||
mp_image_set_colorspace_details(image, &priv->colorspace);
|
||||
|
||||
|
@ -1394,11 +1394,10 @@ static mp_image_t *get_screenshot(struct gl_priv *p)
|
||||
}
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
|
||||
image->width = p->image_width;
|
||||
image->height = p->image_height;
|
||||
|
||||
image->w = p->vo->aspdat.prew;
|
||||
image->h = p->vo->aspdat.preh;
|
||||
image->w = p->image_width;
|
||||
image->h = p->image_height;
|
||||
image->display_w = p->vo->aspdat.prew;
|
||||
image->display_h = p->vo->aspdat.preh;
|
||||
|
||||
mp_image_set_colorspace_details(image, &p->colorspace);
|
||||
|
||||
|
@ -822,11 +822,10 @@ static mp_image_t *get_screenshot(struct vo *vo)
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
image->width = p->image_width;
|
||||
image->height = p->image_height;
|
||||
|
||||
image->w = vo->aspdat.prew;
|
||||
image->h = vo->aspdat.preh;
|
||||
image->w = p->image_width;
|
||||
image->h = p->image_height;
|
||||
image->display_w = vo->aspdat.prew;
|
||||
image->display_h = vo->aspdat.preh;
|
||||
|
||||
mp_image_set_colorspace_details(image, &p->colorspace);
|
||||
|
||||
|
@ -1397,10 +1397,8 @@ static struct mp_image *get_screenshot(struct vo *vo)
|
||||
struct mp_image *image = read_output_surface(vc, vc->screenshot_surface,
|
||||
vc->vid_width, vc->vid_height);
|
||||
|
||||
image->width = vc->vid_width;
|
||||
image->height = vc->vid_height;
|
||||
image->w = vo->aspdat.prew;
|
||||
image->h = vo->aspdat.preh;
|
||||
image->display_w = vo->aspdat.prew;
|
||||
image->display_h = vo->aspdat.preh;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -423,8 +423,8 @@ static mp_image_t *get_screenshot(struct vo *vo)
|
||||
// try to get an image without OSD
|
||||
int id = ctx->have_image_copy ? ctx->num_buffers : ctx->visible_buf;
|
||||
struct mp_image img = get_xv_buffer(vo, id);
|
||||
img.w = vo->aspdat.prew;
|
||||
img.h = vo->aspdat.preh;
|
||||
img.display_w = vo->aspdat.prew;
|
||||
img.display_h = vo->aspdat.preh;
|
||||
|
||||
return talloc_memdup(NULL, &img, sizeof(img));
|
||||
}
|
||||
|
18
screenshot.c
18
screenshot.c
@ -242,25 +242,23 @@ static struct mp_image *add_subs(struct MPContext *mpctx,
|
||||
image->imgfmt);
|
||||
copy_mpi(new_image, image);
|
||||
vf_clone_mpi_attributes(new_image, image);
|
||||
new_image->w = image->w;
|
||||
new_image->h = image->h;
|
||||
image = new_image;
|
||||
}
|
||||
|
||||
int d_w = image->display_w ? image->display_w : image->w;
|
||||
int d_h = image->display_h ? image->display_h : image->h;
|
||||
|
||||
double sar = (double)image->width / image->height;
|
||||
double dar = (double)image->w / image->h;
|
||||
double dar = (double)d_w / d_h;
|
||||
struct mp_osd_res res = {
|
||||
.w = image->width,
|
||||
.h = image->height,
|
||||
.w = image->w,
|
||||
.h = image->h,
|
||||
.display_par = sar / dar,
|
||||
.video_par = dar / sar,
|
||||
};
|
||||
// It's not really clear what's the difference between w and width
|
||||
struct mp_image hack = *image;
|
||||
hack.w = hack.width;
|
||||
hack.h = hack.height;
|
||||
|
||||
osd_draw_on_image(mpctx->osd, res, mpctx->osd->vo_pts,
|
||||
OSD_DRAW_SUB_ONLY, &hack);
|
||||
OSD_DRAW_SUB_ONLY, image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user