From 2c43d2b75a88b8e0e8f0a715f993ffc1c8977d13 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 31 Oct 2019 15:44:09 +0100 Subject: [PATCH] screenshot, vo_image: use global swscale/zimg parameters Lots of dumb crap to do... something. Instead of adding yet another dumb helper, just use the main" sws_utils API in both callers. (Which, unfortunately, has been duplicated for glorious webp screenshots, despite the fact that webp is crap.) Good part: can enable zimg for screenshots (as far as needed). Bad part: uses "default" swscale parameters instead of HQ now. --- player/screenshot.c | 17 +++++++++++++---- player/screenshot.h | 4 +++- video/image_loader.c | 2 +- video/image_writer.c | 17 +++++++++++++---- video/image_writer.h | 5 ++++- video/out/vo_image.c | 2 +- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/player/screenshot.c b/player/screenshot.c index af06701bbb..eccce16dd6 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -83,7 +83,8 @@ static bool write_screenshot(struct mp_cmd_ctx *cmd, struct mp_image *img, mp_core_unlock(mpctx); - bool ok = img && write_image(img, &opts_copy, filename, mpctx->log); + bool ok = img && write_image(img, &opts_copy, filename, mpctx->global, + mpctx->log); mp_core_lock(mpctx); @@ -370,7 +371,7 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode, } struct mp_image *convert_image(struct mp_image *image, int destfmt, - struct mp_log *log) + struct mpv_global *global, struct mp_log *log) { int d_w, d_h; mp_image_params_get_dsize(&image->params, &d_w, &d_h); @@ -396,7 +397,14 @@ struct mp_image *convert_image(struct mp_image *image, int destfmt, dst->params = p; - if (mp_image_swscale(dst, image, mp_sws_hq_flags) < 0) { + struct mp_sws_context *sws = mp_sws_alloc(NULL); + sws->log = log; + if (global) + mp_sws_enable_cmdline_opts(sws, global); + bool ok = mp_sws_scale(sws, dst, image) >= 0; + talloc_free(sws); + + if (!ok) { mp_err(log, "Error when converting image.\n"); talloc_free(dst); return NULL; @@ -411,7 +419,8 @@ static struct mp_image *screenshot_get_rgb(struct MPContext *mpctx, int mode) struct mp_image *mpi = screenshot_get(mpctx, mode, false); if (!mpi) return NULL; - struct mp_image *res = convert_image(mpi, IMGFMT_BGR0, mpctx->log); + struct mp_image *res = convert_image(mpi, IMGFMT_BGR0, mpctx->global, + mpctx->log); talloc_free(mpi); return res; } diff --git a/player/screenshot.h b/player/screenshot.h index 1ccee790d6..990cb9503b 100644 --- a/player/screenshot.h +++ b/player/screenshot.h @@ -23,6 +23,7 @@ struct MPContext; struct mp_image; struct mp_log; +struct mpv_global; // One time initialization at program start. void screenshot_init(struct MPContext *mpctx); @@ -32,9 +33,10 @@ void screenshot_flip(struct MPContext *mpctx); /* Return the image converted to the given format. If the pixel aspect ratio is * not 1:1, the image is scaled as well. Returns NULL on failure. + * If global!=NULL, use command line scaler options etc. */ struct mp_image *convert_image(struct mp_image *image, int destfmt, - struct mp_log *log); + struct mpv_global *global, struct mp_log *log); // Handlers for the user-facing commands. void cmd_screenshot(void *p); diff --git a/video/image_loader.c b/video/image_loader.c index 77deea0f8d..ba4d62acab 100644 --- a/video/image_loader.c +++ b/video/image_loader.c @@ -38,7 +38,7 @@ struct mp_image *load_image_png_buf(void *buffer, size_t buffer_size, int imgfmt if (frame && avcodec_receive_frame(avctx, frame) >= 0) { struct mp_image *r = mp_image_from_av_frame(frame); if (r) - res = convert_image(r, imgfmt, mp_null_log); + res = convert_image(r, imgfmt, NULL, mp_null_log); talloc_free(r); } av_frame_free(&frame); diff --git a/video/image_writer.c b/video/image_writer.c index e66543a772..5438249c42 100644 --- a/video/image_writer.c +++ b/video/image_writer.c @@ -314,6 +314,7 @@ int image_writer_format_from_ext(const char *ext) static struct mp_image *convert_image(struct mp_image *image, int destfmt, enum mp_csp_levels yuv_levels, + struct mpv_global *global, struct mp_log *log) { int d_w, d_h; @@ -350,7 +351,14 @@ static struct mp_image *convert_image(struct mp_image *image, int destfmt, dst->params = p; - if (mp_image_swscale(dst, image, mp_sws_hq_flags) < 0) { + struct mp_sws_context *sws = mp_sws_alloc(NULL); + sws->log = log; + if (global) + mp_sws_enable_cmdline_opts(sws, global); + bool ok = mp_sws_scale(sws, dst, image) >= 0; + talloc_free(sws); + + if (!ok) { mp_err(log, "Error when converting image.\n"); talloc_free(dst); return NULL; @@ -360,7 +368,8 @@ static struct mp_image *convert_image(struct mp_image *image, int destfmt, } bool write_image(struct mp_image *image, const struct image_writer_opts *opts, - const char *filename, struct mp_log *log) + const char *filename, struct mpv_global *global, + struct mp_log *log) { struct image_writer_opts defs = image_writer_opts_defaults; if (!opts) @@ -393,7 +402,7 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, levels = MP_CSP_LEVELS_PC; } - struct mp_image *dst = convert_image(image, destfmt, levels, log); + struct mp_image *dst = convert_image(image, destfmt, levels, global, log); if (!dst) return false; @@ -416,5 +425,5 @@ void dump_png(struct mp_image *image, const char *filename, struct mp_log *log) { struct image_writer_opts opts = image_writer_opts_defaults; opts.format = AV_CODEC_ID_PNG; - write_image(image, &opts, filename, log); + write_image(image, &opts, filename, NULL, log); } diff --git a/video/image_writer.h b/video/image_writer.h index d178d7398b..f6d3b58f87 100644 --- a/video/image_writer.h +++ b/video/image_writer.h @@ -57,12 +57,15 @@ int image_writer_format_from_ext(const char *ext); * * File format and compression settings are controlled via the opts parameter. * + * If global!=NULL, use command line scaler options etc. + * * NOTE: The fields w/h/width/height of the passed mp_image must be all set * accordingly. Setting w and width or h and height to different values * can be used to store snapshots of anamorphic video. */ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, - const char *filename, struct mp_log *log); + const char *filename, struct mpv_global *global, + struct mp_log *log); // Debugging helper. void dump_png(struct mp_image *image, const char *filename, struct mp_log *log); diff --git a/video/out/vo_image.c b/video/out/vo_image.c index 9d30d5b6d2..2a3b8fae87 100644 --- a/video/out/vo_image.c +++ b/video/out/vo_image.c @@ -120,7 +120,7 @@ static void flip_page(struct vo *vo) filename = mp_path_join(t, p->opts->outdir, filename); MP_INFO(vo, "Saving %s\n", filename); - write_image(p->current, p->opts->opts, filename, vo->log); + write_image(p->current, p->opts->opts, filename, vo->global, vo->log); talloc_free(t); mp_image_unrefp(&p->current);