summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-12 18:01:22 +0100
committerwm4 <wm4@nowhere>2020-02-12 18:01:22 +0100
commit7c8b40c38a9858166d804c362aa03119073ed947 (patch)
treeaff1b7b204dc19f5f78ca6548c0e832275d832ac
parent0848f3f8325e10690d08c436fe71603a2cca0699 (diff)
downloadmpv-7c8b40c38a9858166d804c362aa03119073ed947.tar.bz2
mpv-7c8b40c38a9858166d804c362aa03119073ed947.tar.xz
zimg: correct output to odd (chroma un-aligned) sizes
As suggested by the zimg author: active_region is not supported on outputs (and the API returns an error), so instead scale to the "full" surface, but adjust the source rectangle such that the cropped output image happens to cover the correct region. Does this even work? Since Balmer Peak doesn't work, I can't really say, but it seems to look correct.
-rw-r--r--video/zimg.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/video/zimg.c b/video/zimg.c
index 145cd55a51..f902374b14 100644
--- a/video/zimg.c
+++ b/video/zimg.c
@@ -102,6 +102,8 @@ struct mp_zimg_repack {
// Also temporary, per-call. use_buf[n] == plane n uses tmp (and not mpi).
bool use_buf[4];
+
+ int real_w, real_h; // aligned size
};
static void mp_zimg_update_from_cmdline(struct mp_zimg_context *ctx)
@@ -742,15 +744,20 @@ static bool setup_format(zimg_image_format *zfmt, struct mp_zimg_repack *r,
r->num_planes = desc.num_planes;
- // Note: formats with subsampled chroma may have odd width or height in mpv
- // and FFmpeg. This is because the width/height is actually a cropping
+ // Note: formats with subsampled chroma may have odd width or height in
+ // mpv and FFmpeg. This is because the width/height is actually a cropping
// rectangle. Reconstruct the image allocation size and set the cropping.
- zfmt->width = MP_ALIGN_UP(fmt.w, desc.chroma_w);
- zfmt->height = MP_ALIGN_UP(fmt.h, desc.chroma_h);
- if (zfmt->width != fmt.w)
- zfmt->active_region.width = fmt.w;
- if (zfmt->height != fmt.h)
- zfmt->active_region.height = fmt.h;
+ zfmt->width = r->real_w = MP_ALIGN_UP(fmt.w, desc.chroma_w);
+ zfmt->height = r->real_h = MP_ALIGN_UP(fmt.h, desc.chroma_h);
+ if (!r->pack && ctx) {
+ // Relies on ctx->zimg_dst being initialized first.
+ struct mp_zimg_repack *dst = ctx->zimg_dst;
+ if (r->real_w != fmt.w || dst->real_w != dst->fmt.w)
+ zfmt->active_region.width = dst->real_w * (uint64_t)fmt.w / dst->fmt.w;
+ if (r->real_h != fmt.h || dst->real_h != dst->fmt.h)
+ zfmt->active_region.height = dst->real_h * (uint64_t)fmt.h / dst->fmt.h;
+
+ }
zfmt->subsample_w = mp_log2(desc.chroma_w);
zfmt->subsample_h = mp_log2(desc.chroma_h);
@@ -861,8 +868,9 @@ bool mp_zimg_config(struct mp_zimg_context *ctx)
zimg_image_format src_fmt, dst_fmt;
- if (!setup_format(&src_fmt, ctx->zimg_src, ctx) ||
- !setup_format(&dst_fmt, ctx->zimg_dst, ctx))
+ // Note: do zimg_dst first, because zimg_src uses fields from zimg_dst.
+ if (!setup_format(&dst_fmt, ctx->zimg_dst, ctx) ||
+ !setup_format(&src_fmt, ctx->zimg_src, ctx))
goto fail;
zimg_graph_builder_params params;