From 4b91861b6710e9f82618b58841e08986e965eb43 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 21 Nov 2012 19:40:33 +0100 Subject: [PATCH] video: fix bogus uses of mp_image.w/width mp_image has this confusing distinction between the w/h and width/height fields. w/h are the actual width and height, while width/height have a very special meaning inside the video filter code: it's the actually allocated width, which is also used for stride padding. Screenshot related code abused the w/h fields to store the aspect corrected size. Some code confused the role of w/h and width/height. Fix these issues. For aspect corrected size, display_w/h are used, while width/height should never be used outside vf.c internals and related code. This also fixes an actual bug when taking screenshots of anamorphic video with vf_screenshot, as well as using vo_image with such videos. --- core/screenshot.c | 4 ++-- video/filter/vf_screenshot.c | 6 ++++-- video/image_writer.c | 17 +++++++---------- video/out/vo_image.c | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/core/screenshot.c b/core/screenshot.c index e2d237010c..09f1aa7ee6 100644 --- a/core/screenshot.c +++ b/core/screenshot.c @@ -238,7 +238,7 @@ static struct mp_image *add_subs(struct MPContext *mpctx, struct mp_image *image) { if (!(image->flags & MP_IMGFLAG_ALLOCATED)) { - struct mp_image *new_image = alloc_mpi(image->width, image->height, + struct mp_image *new_image = alloc_mpi(image->w, image->h, image->imgfmt); copy_mpi(new_image, image); vf_clone_mpi_attributes(new_image, image); @@ -248,7 +248,7 @@ static struct mp_image *add_subs(struct MPContext *mpctx, 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 sar = (double)image->w / image->h; double dar = (double)d_w / d_h; struct mp_osd_res res = { .w = image->w, diff --git a/video/filter/vf_screenshot.c b/video/filter/vf_screenshot.c index 8b937b0648..e4ba696f69 100644 --- a/video/filter/vf_screenshot.c +++ b/video/filter/vf_screenshot.c @@ -49,8 +49,8 @@ static int config(struct vf_instance *vf, free_mp_image(vf->priv->image); vf->priv->image = new_mp_image(width, height); mp_image_setfmt(vf->priv->image, outfmt); - vf->priv->image->w = d_width; - vf->priv->image->h = d_height; + vf->priv->image->display_w = d_width; + vf->priv->image->display_h = d_height; return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } @@ -142,6 +142,8 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) image.w = vf->priv->image->w; image.h = vf->priv->image->h; vf_clone_mpi_attributes(&image, mpi); + image.display_w = vf->priv->image->display_w; + image.display_h = vf->priv->image->display_h; vf->priv->image_callback(vf->priv->image_callback_ctx, &image); vf->priv->store_slices = 0; } diff --git a/video/image_writer.c b/video/image_writer.c index 810c1598b6..570db961ca 100644 --- a/video/image_writer.c +++ b/video/image_writer.c @@ -102,8 +102,8 @@ static int write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) goto print_open_fail; avctx->time_base = AV_TIME_BASE_Q; - avctx->width = image->width; - avctx->height = image->height; + avctx->width = image->w; + avctx->height = image->h; avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt); if (ctx->writer->lavc_codec == CODEC_ID_PNG) avctx->compression_level = ctx->opts->png_compression; @@ -115,7 +115,7 @@ static int write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) goto error_exit; } - size_t outbuffer_size = image->width * image->height * 3 * 2; + size_t outbuffer_size = image->w * image->h * 3 * 2; outbuffer = malloc(outbuffer_size); if (!outbuffer) goto error_exit; @@ -173,8 +173,8 @@ static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); - cinfo.image_width = image->width; - cinfo.image_height = image->height; + cinfo.image_width = image->w; + cinfo.image_height = image->h; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; @@ -182,11 +182,8 @@ static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) cinfo.JFIF_major_version = 1; cinfo.JFIF_minor_version = 2; cinfo.density_unit = 1; /* 0=unknown, 1=dpi, 2=dpcm */ - /* Image DPI is determined by Y_density, so we leave that at - jpeg_dpi if possible and crunch X_density instead (PAR > 1) */ - // NOTE: write_image never passes anamorphic images currently - cinfo.X_density = ctx->opts->jpeg_dpi*image->width/image->w; - cinfo.Y_density = ctx->opts->jpeg_dpi*image->height/image->h; + cinfo.X_density = ctx->opts->jpeg_dpi; + cinfo.Y_density = ctx->opts->jpeg_dpi; cinfo.write_Adobe_marker = TRUE; jpeg_set_defaults(&cinfo); diff --git a/video/out/vo_image.c b/video/out/vo_image.c index 76adf5a665..e4d8636038 100644 --- a/video/out/vo_image.c +++ b/video/out/vo_image.c @@ -101,8 +101,8 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) struct priv *p = vo->priv; mp_image_t img = *mpi; - img.width = p->d_width; - img.height = p->d_height; + img.display_w = p->d_width; + img.display_h = p->d_height; mp_image_set_colorspace_details(&img, &p->colorspace); void *t = talloc_new(NULL);