Message ID | 0c94949d-ef2e-5dee-0cf0-939a936014ce@gyani.pro |
---|---|
State | Accepted |
Headers | show |
On Sat, Dec 07, 2019 at 12:08:53PM +0530, Gyan wrote: > > > On 07-12-2019 12:36 am, Michael Niedermayer wrote: > >On Wed, Dec 04, 2019 at 02:14:35PM +0530, Gyan wrote: > >>Will help reduce code duplication when adding animation support to vf_scale. > >>See Michael's last comment in https://patchwork.ffmpeg.org/patch/16272/ > >> > >>Gyan > >> doc/filters.texi | 40 +++++++++++++++++++++++++++++ > >> libavfilter/scale.c | 59 ++++++++++++++++++++++++++++++++++--------- > >> libavfilter/scale.h | 4 ++ > >> libavfilter/vf_scale.c | 28 ++------------------ > >> libavfilter/vf_scale_cuda.c | 11 ++++++++ > >> libavfilter/vf_scale_npp.c | 11 ++++++++ > >> libavfilter/vf_scale_vaapi.c | 11 ++++++++ > >> 7 files changed, 128 insertions(+), 36 deletions(-) > >>380bf799c14d6286cc625afe019aa553614a7d53 0001-avfilter-scale.c-factorize-ff_scale_eval_dimensions.patch > >> From 138a8dba766674a1b017614c58fa99aeca98e9e5 Mon Sep 17 00:00:00 2001 > >>From: Gyan Doshi <ffmpeg@gyani.pro> > >>Date: Mon, 2 Dec 2019 21:11:21 +0530 > >>Subject: [PATCH] avfilter/scale.c: factorize ff_scale_eval_dimensions > >> > >>Adjustment of evaluated values shifted to ff_adjust_scale_dimensions > >>Shifted code for force_original_aspect_ratio and force_divisble_by from > >>vf_scale so it is now available for scale_cuda, scale_npp and > >>scale_vaapi as well. > >>--- > >> doc/filters.texi | 40 ++++++++++++++++++++++++ > >> libavfilter/scale.c | 59 +++++++++++++++++++++++++++++------- > >> libavfilter/scale.h | 4 +++ > >> libavfilter/vf_scale.c | 28 ++--------------- > >> libavfilter/vf_scale_cuda.c | 11 +++++++ > >> libavfilter/vf_scale_npp.c | 11 +++++++ > >> libavfilter/vf_scale_vaapi.c | 11 +++++++ > >> 7 files changed, 128 insertions(+), 36 deletions(-) > >> > >>diff --git a/doc/filters.texi b/doc/filters.texi > >>index 5fdec6f015..9129f7e3a5 100644 > >>--- a/doc/filters.texi > >>+++ b/doc/filters.texi > >>@@ -16210,6 +16210,46 @@ Supersampling > >> @item lanczos > >> @end table > >>+@item force_original_aspect_ratio > >>+Enable decreasing or increasing output video width or height if necessary to > >>+keep the original aspect ratio. Possible values: > >>+ > >>+@table @samp > >>+@item disable > >>+Scale the video as specified and disable this feature. > >>+ > >>+@item decrease > >>+The output video dimensions will automatically be decreased if needed. > >>+ > >>+@item increase > >>+The output video dimensions will automatically be increased if needed. > >>+ > >>+@end table > >>+ > >>+One useful instance of this option is that when you know a specific device's > >>+maximum allowed resolution, you can use this to limit the output video to > >>+that, while retaining the aspect ratio. For example, device A allows > >>+1280x720 playback, and your video is 1920x800. Using this option (set it to > >>+decrease) and specifying 1280x720 to the command line makes the output > >>+1280x533. > >>+ > >>+Please note that this is a different thing than specifying -1 for @option{w} > >>+or @option{h}, you still need to specify the output resolution for this option > >>+to work. > >>+ > >>+@item force_divisible_by > >>+Ensures that both the output dimensions, width and height, are divisible by the > >>+given integer when used together with @option{force_original_aspect_ratio}. This > >>+works similar to using @code{-n} in the @option{w} and @option{h} options. > >>+ > >>+This option respects the value set for @option{force_original_aspect_ratio}, > >>+increasing or decreasing the resolution accordingly. The video's aspect ratio > >>+may be slightly modified. > >>+ > >>+This option can be handy if you need to have a video fit within or exceed > >>+a defined resolution using @option{force_original_aspect_ratio} but also have > >>+encoder restrictions on width or height divisibility. > >>+ > >> @end table > >> @section scale2ref > >>diff --git a/libavfilter/scale.c b/libavfilter/scale.c > >>index eaee95fac6..5e9f97230c 100644 > >>--- a/libavfilter/scale.c > >>+++ b/libavfilter/scale.c > >>@@ -111,8 +111,6 @@ int ff_scale_eval_dimensions(void *log_ctx, > >> const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); > >> const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format); > >> const char *expr; > >>- int w, h; > >>- int factor_w, factor_h; > >> int eval_w, eval_h; > >> int ret; > >> const char scale2ref = outlink->src->nb_inputs == 2 && outlink->src->inputs[1] == inlink; > >>@@ -172,8 +170,28 @@ int ff_scale_eval_dimensions(void *log_ctx, > >> goto fail; > >> eval_w = (int) res == 0 ? inlink->w : (int) res; > >>- w = eval_w; > >>- h = eval_h; > >>+ *ret_w = eval_w; > >>+ *ret_h = eval_h; > >>+ > >>+ return 0; > >>+ > >>+fail: > >>+ av_log(log_ctx, AV_LOG_ERROR, > >>+ "Error when evaluating the expression '%s'.\n" > >>+ "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", > >>+ expr, w_expr, h_expr); > >>+ return ret; > >>+} > >>+ > >>+int ff_scale_adjust_dimensions(AVFilterLink *inlink, > >>+ int *ret_w, int *ret_h, > >>+ int force_original_aspect_ratio, int force_divisible_by) > >>+{ > >>+ int w, h; > >>+ int factor_w, factor_h; > >>+ > >>+ w = *ret_w; > >>+ h = *ret_h; > >> /* Check if it is requested that the result has to be divisible by a some > >> * factor (w or h = -n with n being the factor). */ > >>@@ -199,15 +217,34 @@ int ff_scale_eval_dimensions(void *log_ctx, > >> if (h < 0) > >> h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h; > >>+ /* Note that force_original_aspect_ratio may overwrite the previous set > >>+ * dimensions so that it is not divisible by the set factors anymore > >>+ * unless force_divisible_by is defined as well */ > >>+ if (force_original_aspect_ratio) { > >>+ int tmp_w = av_rescale(h, inlink->w, inlink->h); > >>+ int tmp_h = av_rescale(w, inlink->h, inlink->w); > >>+ > >>+ if (force_original_aspect_ratio == 1) { > >>+ w = FFMIN(tmp_w, w); > >>+ h = FFMIN(tmp_h, h); > >>+ if (force_divisible_by > 1) { > >>+ // round down > >>+ w = w / force_divisible_by * force_divisible_by; > >>+ h = h / force_divisible_by * force_divisible_by; > >>+ } > >>+ } else { > >>+ w = FFMAX(tmp_w, w); > >>+ h = FFMAX(tmp_h, h); > >>+ if (force_divisible_by > 1) { > >>+ // round up > >>+ w = (w + force_divisible_by - 1) / force_divisible_by * force_divisible_by; > >>+ h = (h + force_divisible_by - 1) / force_divisible_by * force_divisible_by; > >>+ } > >>+ } > >>+ } > >>+ > >> *ret_w = w; > >> *ret_h = h; > >> return 0; > >>- > >>-fail: > >>- av_log(log_ctx, AV_LOG_ERROR, > >>- "Error when evaluating the expression '%s'.\n" > >>- "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", > >>- expr, w_expr, h_expr); > >>- return ret; > >> } > >>diff --git a/libavfilter/scale.h b/libavfilter/scale.h > >>index dfe67d0be0..fa480d727a 100644 > >>--- a/libavfilter/scale.h > >>+++ b/libavfilter/scale.h > >>@@ -25,4 +25,8 @@ int ff_scale_eval_dimensions(void *ctx, > >> const char *w_expr, const char *h_expr, > >> AVFilterLink *inlink, AVFilterLink *outlink, > >> int *ret_w, int *ret_h); > >>+ > >>+int ff_scale_adjust_dimensions(AVFilterLink *inlink, > >>+ int *ret_w, int *ret_h, > >>+ int force_original_aspect_ratio, int force_divisible_by); > >> #endif > >This should be documented so developers know what it is, how to use it > >and what changes can be done to it without breaking code using it. > > > >That would make it easier to future contributors to work on this > >function and the code calling this function > > Docs added. > > Gyan > doc/filters.texi | 40 +++++++++++++++++++++++++++++ > libavfilter/scale.c | 59 ++++++++++++++++++++++++++++++++++--------- > libavfilter/scale.h | 20 ++++++++++++++ > libavfilter/vf_scale.c | 28 ++------------------ > libavfilter/vf_scale_cuda.c | 11 ++++++++ > libavfilter/vf_scale_npp.c | 11 ++++++++ > libavfilter/vf_scale_vaapi.c | 11 ++++++++ > 7 files changed, 144 insertions(+), 36 deletions(-) > f0a65d11857e709ee7cdf862ba108c765c4f5a2f v2-0001-avfilter-scale.c-factorize-ff_scale_eval_dimensio.patch > From 863c6feac1790560f7bdc29358cfcd0e5ee370f6 Mon Sep 17 00:00:00 2001 > From: Gyan Doshi <ffmpeg@gyani.pro> > Date: Mon, 2 Dec 2019 21:11:21 +0530 > Subject: [PATCH v2] avfilter/scale.c: factorize ff_scale_eval_dimensions > > Adjustment of evaluated values shifted to ff_adjust_scale_dimensions > Shifted code for force_original_aspect_ratio and force_divisble_by from > vf_scale so it is now available for scale_cuda, scale_npp and > scale_vaapi as well. > --- > doc/filters.texi | 40 ++++++++++++++++++++++++ > libavfilter/scale.c | 59 +++++++++++++++++++++++++++++------- > libavfilter/scale.h | 20 ++++++++++++ > libavfilter/vf_scale.c | 28 ++--------------- > libavfilter/vf_scale_cuda.c | 11 +++++++ > libavfilter/vf_scale_npp.c | 11 +++++++ > libavfilter/vf_scale_vaapi.c | 11 +++++++ > 7 files changed, 144 insertions(+), 36 deletions(-) The changes should be ok i think. Thanks [...]
On 07-12-2019 11:47 pm, Michael Niedermayer wrote: > On Sat, Dec 07, 2019 at 12:08:53PM +0530, Gyan wrote: > >> doc/filters.texi | 40 +++++++++++++++++++++++++++++ >> libavfilter/scale.c | 59 ++++++++++++++++++++++++++++++++++--------- >> libavfilter/scale.h | 20 ++++++++++++++ >> libavfilter/vf_scale.c | 28 ++------------------ >> libavfilter/vf_scale_cuda.c | 11 ++++++++ >> libavfilter/vf_scale_npp.c | 11 ++++++++ >> libavfilter/vf_scale_vaapi.c | 11 ++++++++ >> 7 files changed, 144 insertions(+), 36 deletions(-) >> f0a65d11857e709ee7cdf862ba108c765c4f5a2f v2-0001-avfilter-scale.c-factorize-ff_scale_eval_dimensio.patch >> From 863c6feac1790560f7bdc29358cfcd0e5ee370f6 Mon Sep 17 00:00:00 2001 >> From: Gyan Doshi <ffmpeg@gyani.pro> >> Date: Mon, 2 Dec 2019 21:11:21 +0530 >> Subject: [PATCH v2] avfilter/scale.c: factorize ff_scale_eval_dimensions >> >> Adjustment of evaluated values shifted to ff_adjust_scale_dimensions >> Shifted code for force_original_aspect_ratio and force_divisble_by from >> vf_scale so it is now available for scale_cuda, scale_npp and >> scale_vaapi as well. >> --- >> doc/filters.texi | 40 ++++++++++++++++++++++++ >> libavfilter/scale.c | 59 +++++++++++++++++++++++++++++------- >> libavfilter/scale.h | 20 ++++++++++++ >> libavfilter/vf_scale.c | 28 ++--------------- >> libavfilter/vf_scale_cuda.c | 11 +++++++ >> libavfilter/vf_scale_npp.c | 11 +++++++ >> libavfilter/vf_scale_vaapi.c | 11 +++++++ >> 7 files changed, 144 insertions(+), 36 deletions(-) > The changes should be ok i think. Will push in a few hours. Thanks, Gyan
On 08-12-2019 10:03 am, Gyan wrote: > > > On 07-12-2019 11:47 pm, Michael Niedermayer wrote: >> On Sat, Dec 07, 2019 at 12:08:53PM +0530, Gyan wrote: >> >>> doc/filters.texi | 40 +++++++++++++++++++++++++++++ >>> libavfilter/scale.c | 59 >>> ++++++++++++++++++++++++++++++++++--------- >>> libavfilter/scale.h | 20 ++++++++++++++ >>> libavfilter/vf_scale.c | 28 ++------------------ >>> libavfilter/vf_scale_cuda.c | 11 ++++++++ >>> libavfilter/vf_scale_npp.c | 11 ++++++++ >>> libavfilter/vf_scale_vaapi.c | 11 ++++++++ >>> 7 files changed, 144 insertions(+), 36 deletions(-) >>> f0a65d11857e709ee7cdf862ba108c765c4f5a2f >>> v2-0001-avfilter-scale.c-factorize-ff_scale_eval_dimensio.patch >>> From 863c6feac1790560f7bdc29358cfcd0e5ee370f6 Mon Sep 17 00:00:00 2001 >>> From: Gyan Doshi <ffmpeg@gyani.pro> >>> Date: Mon, 2 Dec 2019 21:11:21 +0530 >>> Subject: [PATCH v2] avfilter/scale.c: factorize >>> ff_scale_eval_dimensions >>> >>> Adjustment of evaluated values shifted to ff_adjust_scale_dimensions >>> Shifted code for force_original_aspect_ratio and force_divisble_by from >>> vf_scale so it is now available for scale_cuda, scale_npp and >>> scale_vaapi as well. >>> --- >>> doc/filters.texi | 40 ++++++++++++++++++++++++ >>> libavfilter/scale.c | 59 >>> +++++++++++++++++++++++++++++------- >>> libavfilter/scale.h | 20 ++++++++++++ >>> libavfilter/vf_scale.c | 28 ++--------------- >>> libavfilter/vf_scale_cuda.c | 11 +++++++ >>> libavfilter/vf_scale_npp.c | 11 +++++++ >>> libavfilter/vf_scale_vaapi.c | 11 +++++++ >>> 7 files changed, 144 insertions(+), 36 deletions(-) >> The changes should be ok i think. > > Will push in a few hours. Pushed with a couple of doc typos also corrected as 1b4f473d181abaa0ff4e2d63862f61763a5a6860 Gyan
diff --git a/doc/filters.texi b/doc/filters.texi index 5fdec6f015..9129f7e3a5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -16210,6 +16210,46 @@ Supersampling @item lanczos @end table +@item force_original_aspect_ratio +Enable decreasing or increasing output video width or height if necessary to +keep the original aspect ratio. Possible values: + +@table @samp +@item disable +Scale the video as specified and disable this feature. + +@item decrease +The output video dimensions will automatically be decreased if needed. + +@item increase +The output video dimensions will automatically be increased if needed. + +@end table + +One useful instance of this option is that when you know a specific device's +maximum allowed resolution, you can use this to limit the output video to +that, while retaining the aspect ratio. For example, device A allows +1280x720 playback, and your video is 1920x800. Using this option (set it to +decrease) and specifying 1280x720 to the command line makes the output +1280x533. + +Please note that this is a different thing than specifying -1 for @option{w} +or @option{h}, you still need to specify the output resolution for this option +to work. + +@item force_divisible_by +Ensures that both the output dimensions, width and height, are divisible by the +given integer when used together with @option{force_original_aspect_ratio}. This +works similar to using @code{-n} in the @option{w} and @option{h} options. + +This option respects the value set for @option{force_original_aspect_ratio}, +increasing or decreasing the resolution accordingly. The video's aspect ratio +may be slightly modified. + +This option can be handy if you need to have a video fit within or exceed +a defined resolution using @option{force_original_aspect_ratio} but also have +encoder restrictions on width or height divisibility. + @end table @section scale2ref diff --git a/libavfilter/scale.c b/libavfilter/scale.c index eaee95fac6..5e9f97230c 100644 --- a/libavfilter/scale.c +++ b/libavfilter/scale.c @@ -111,8 +111,6 @@ int ff_scale_eval_dimensions(void *log_ctx, const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format); const char *expr; - int w, h; - int factor_w, factor_h; int eval_w, eval_h; int ret; const char scale2ref = outlink->src->nb_inputs == 2 && outlink->src->inputs[1] == inlink; @@ -172,8 +170,28 @@ int ff_scale_eval_dimensions(void *log_ctx, goto fail; eval_w = (int) res == 0 ? inlink->w : (int) res; - w = eval_w; - h = eval_h; + *ret_w = eval_w; + *ret_h = eval_h; + + return 0; + +fail: + av_log(log_ctx, AV_LOG_ERROR, + "Error when evaluating the expression '%s'.\n" + "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", + expr, w_expr, h_expr); + return ret; +} + +int ff_scale_adjust_dimensions(AVFilterLink *inlink, + int *ret_w, int *ret_h, + int force_original_aspect_ratio, int force_divisible_by) +{ + int w, h; + int factor_w, factor_h; + + w = *ret_w; + h = *ret_h; /* Check if it is requested that the result has to be divisible by a some * factor (w or h = -n with n being the factor). */ @@ -199,15 +217,34 @@ int ff_scale_eval_dimensions(void *log_ctx, if (h < 0) h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h; + /* Note that force_original_aspect_ratio may overwrite the previous set + * dimensions so that it is not divisible by the set factors anymore + * unless force_divisible_by is defined as well */ + if (force_original_aspect_ratio) { + int tmp_w = av_rescale(h, inlink->w, inlink->h); + int tmp_h = av_rescale(w, inlink->h, inlink->w); + + if (force_original_aspect_ratio == 1) { + w = FFMIN(tmp_w, w); + h = FFMIN(tmp_h, h); + if (force_divisible_by > 1) { + // round down + w = w / force_divisible_by * force_divisible_by; + h = h / force_divisible_by * force_divisible_by; + } + } else { + w = FFMAX(tmp_w, w); + h = FFMAX(tmp_h, h); + if (force_divisible_by > 1) { + // round up + w = (w + force_divisible_by - 1) / force_divisible_by * force_divisible_by; + h = (h + force_divisible_by - 1) / force_divisible_by * force_divisible_by; + } + } + } + *ret_w = w; *ret_h = h; return 0; - -fail: - av_log(log_ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s'.\n" - "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", - expr, w_expr, h_expr); - return ret; } diff --git a/libavfilter/scale.h b/libavfilter/scale.h index dfe67d0be0..6e1c8a1f4c 100644 --- a/libavfilter/scale.h +++ b/libavfilter/scale.h @@ -21,8 +21,28 @@ #include "avfilter.h" +/** + * Parse and evaluate string expressions for width and height. Upon success, + * ff_scale_adjust_dimensions must be called with evaluated width and height + * to obtain actual target dimensions. + * + * Returns 0 upon success, negative value if one of the expressions could + * not be parsed or if NaN was the result of their evaluation. + */ int ff_scale_eval_dimensions(void *ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h); + +/** + * Transform evaluated width and height obtained from ff_scale_eval_dimensions + * into actual target width and height for scaling. Adjustment can occur if one + * or both of the evaluated values are of the form '-n' or if + * force_original_aspect_ratio is set. + * + * Returns 0. + */ +int ff_scale_adjust_dimensions(AVFilterLink *inlink, + int *ret_w, int *ret_h, + int force_original_aspect_ratio, int force_divisible_by); #endif diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 41ddec7661..b7f541be1f 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -237,31 +237,9 @@ static int config_props(AVFilterLink *outlink) &w, &h)) < 0) goto fail; - /* Note that force_original_aspect_ratio may overwrite the previous set - * dimensions so that it is not divisible by the set factors anymore - * unless force_divisible_by is defined as well */ - if (scale->force_original_aspect_ratio) { - int tmp_w = av_rescale(h, inlink->w, inlink->h); - int tmp_h = av_rescale(w, inlink->h, inlink->w); - - if (scale->force_original_aspect_ratio == 1) { - w = FFMIN(tmp_w, w); - h = FFMIN(tmp_h, h); - if (scale->force_divisible_by > 1) { - // round down - w = w / scale->force_divisible_by * scale->force_divisible_by; - h = h / scale->force_divisible_by * scale->force_divisible_by; - } - } else { - w = FFMAX(tmp_w, w); - h = FFMAX(tmp_h, h); - if (scale->force_divisible_by > 1) { - // round up - w = (w + scale->force_divisible_by - 1) / scale->force_divisible_by * scale->force_divisible_by; - h = (h + scale->force_divisible_by - 1) / scale->force_divisible_by * scale->force_divisible_by; - } - } - } + ff_scale_adjust_dimensions(inlink, &w, &h, + scale->force_original_aspect_ratio, + scale->force_divisible_by); if (w > INT_MAX || h > INT_MAX || (h * inlink->w) > INT_MAX || diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index 0a73ea1422..cca68dd835 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -82,6 +82,9 @@ typedef struct CUDAScaleContext { char *w_expr; ///< width expression string char *h_expr; ///< height expression string + int force_original_aspect_ratio; + int force_divisible_by; + CUcontext cu_ctx; CUmodule cu_module; CUfunction cu_func_uchar; @@ -305,6 +308,9 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) &w, &h)) < 0) goto fail; + ff_scale_adjust_dimensions(inlink, &w, &h, + s->force_original_aspect_ratio, s->force_divisible_by); + if (((int64_t)h * inlink->w) > INT_MAX || ((int64_t)w * inlink->h) > INT_MAX) av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); @@ -536,6 +542,11 @@ fail: static const AVOption options[] = { { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, + { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, + { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, + { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, + { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, + { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, { NULL }, }; diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index a3e085764a..09c3d51727 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -98,6 +98,9 @@ typedef struct NPPScaleContext { char *h_expr; ///< height expression string char *format_str; + int force_original_aspect_ratio; + int force_divisible_by; + int interp_algo; } NPPScaleContext; @@ -347,6 +350,9 @@ static int nppscale_config_props(AVFilterLink *outlink) &w, &h)) < 0) goto fail; + ff_scale_adjust_dimensions(inlink, &w, &h, + s->force_original_aspect_ratio, s->force_divisible_by); + if (((int64_t)h * inlink->w) > INT_MAX || ((int64_t)w * inlink->h) > INT_MAX) av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); @@ -552,6 +558,11 @@ static const AVOption options[] = { { "cubic2p_b05c03", "2-parameter cubic (B=1/2, C=3/10)", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_CUBIC2P_B05C03 }, 0, 0, FLAGS, "interp_algo" }, { "super", "supersampling", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_SUPER }, 0, 0, FLAGS, "interp_algo" }, { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_LANCZOS }, 0, 0, FLAGS, "interp_algo" }, + { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, + { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, + { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, + { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, + { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, { NULL }, }; diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index c32395ac09..88642cbe73 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -40,6 +40,9 @@ typedef struct ScaleVAAPIContext { char *w_expr; // width expression string char *h_expr; // height expression string + int force_original_aspect_ratio; + int force_divisible_by; + char *colour_primaries_string; char *colour_transfer_string; char *colour_matrix_string; @@ -81,6 +84,9 @@ static int scale_vaapi_config_output(AVFilterLink *outlink) &vpp_ctx->output_width, &vpp_ctx->output_height)) < 0) return err; + ff_scale_adjust_dimensions(inlink, &vpp_ctx->output_width, &vpp_ctx->output_height, + ctx->force_original_aspect_ratio, ctx->force_divisible_by); + err = ff_vaapi_vpp_config_output(outlink); if (err < 0) return err; @@ -247,6 +253,11 @@ static const AVOption scale_vaapi_options[] = { { "out_chroma_location", "Output chroma sample location", OFFSET(chroma_location_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, + { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, + { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, + { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, + { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, + { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, { NULL }, };