From c62efc52c6c5f9dc9cf8e335f6e934e69a721331 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 26 Oct 2012 20:19:06 +0200 Subject: 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. --- image_writer.c | 12 +++++------- libmpcodecs/mp_image.h | 3 ++- libmpcodecs/vf.c | 2 ++ libvo/vo_corevideo.m | 7 ++----- libvo/vo_direct3d.c | 4 ++-- libvo/vo_opengl.c | 9 ++++----- libvo/vo_opengl_old.c | 9 ++++----- libvo/vo_vdpau.c | 6 ++---- libvo/vo_xv.c | 4 ++-- screenshot.c | 18 ++++++++---------- 10 files changed, 33 insertions(+), 41 deletions(-) diff --git a/image_writer.c b/image_writer.c index f449b5c617..2ac2c223a1 100644 --- a/image_writer.c +++ b/image_writer.c @@ -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; diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index fa5e7032f9..84a6f3260d 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -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; diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index 5f4da28dee..fbaa1cf2a7 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -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; diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index 0fd8510f39..5116ab653c 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -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); diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index 773cd5fb76..5fc2a64893 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -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); diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c index cc7b7bde40..bcbff61244 100644 --- a/libvo/vo_opengl.c +++ b/libvo/vo_opengl.c @@ -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); diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c index 4823576290..d68ea3c5d5 100644 --- a/libvo/vo_opengl_old.c +++ b/libvo/vo_opengl_old.c @@ -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); diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 3f5b7bc660..9f72249c4b 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -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; } diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index 82469e491f..90eda230b8 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -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)); } diff --git a/screenshot.c b/screenshot.c index f69bba9b76..87de5c2d37 100644 --- a/screenshot.c +++ b/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; } -- cgit v1.2.3