summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/filters.texi12
-rw-r--r--libavfilter/vf_scale.c15
2 files changed, 26 insertions, 1 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index e081cdc7bc..01262d845e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -15369,6 +15369,18 @@ 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 the output resolution is divisible by the
+given integer when used together with @option{force_original_aspect_ratio}. This
+works similar to using -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. This may slightly modify
+the video's aspect ration.
+
+This can be handy, for example, if you want to have a video fit within a defined
+resolution using the @option{force_original_aspect_ratio} option but have
+encoder restrictions when it comes to width or height.
+
@end table
The values of the @option{w} and @option{h} options are expressions
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 7aebf56ad8..bf340b8e7b 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -86,6 +86,7 @@ typedef struct ScaleContext {
int in_v_chr_pos;
int force_original_aspect_ratio;
+ int force_divisible_by;
int nb_slices;
@@ -237,7 +238,8 @@ static int config_props(AVFilterLink *outlink)
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. */
+ * 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);
@@ -245,9 +247,19 @@ static int config_props(AVFilterLink *outlink)
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;
+ }
}
}
@@ -600,6 +612,7 @@ static const AVOption scale_options[] = {
{ "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 },
{ "param0", "Scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS },
{ "param1", "Scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS },
{ "nb_slices", "set the number of slices (debug purpose only)", OFFSET(nb_slices), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },