avfilter/vf_pad: add aspect option
authorPaul B Mahol <onemda@gmail.com>
Sun, 2 Apr 2017 20:07:04 +0000 (22:07 +0200)
committerPaul B Mahol <onemda@gmail.com>
Mon, 3 Apr 2017 20:35:34 +0000 (22:35 +0200)
Signed-off-by: Paul B Mahol <onemda@gmail.com>
doc/filters.texi
libavfilter/vf_pad.c

index 8e5e21f..bc37e66 100644 (file)
@@ -10453,6 +10453,9 @@ Evaluate expressions for each incoming frame.
 
 Default value is @samp{init}.
 
+@item aspect
+Pad to aspect instead to a resolution.
+
 @end table
 
 The value for the @var{width}, @var{height}, @var{x}, and @var{y}
index 61927b6..44a8fec 100644 (file)
@@ -24,6 +24,8 @@
  * video padding filter
  */
 
+#include <float.h>  /* DBL_MAX */
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
@@ -87,6 +89,7 @@ typedef struct PadContext {
     int x, y;               ///< offsets of the input area with respect to the padded area
     int in_w, in_h;         ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues
     int inlink_w, inlink_h;
+    AVRational aspect;
 
     char *w_expr;           ///< width  expression string
     char *h_expr;           ///< height expression string
@@ -103,6 +106,7 @@ static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
     PadContext *s = ctx->priv;
+    AVRational adjusted_aspect = s->aspect;
     int ret;
     double var_values[VARS_NB], res;
     char *expr;
@@ -143,6 +147,15 @@ static int config_input(AVFilterLink *inlink)
     if (!s->w)
         var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w = inlink->w;
 
+    if (adjusted_aspect.num && adjusted_aspect.den) {
+        adjusted_aspect = av_div_q(adjusted_aspect, inlink->sample_aspect_ratio);
+        if (s->h < av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num)) {
+            s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num);
+        } else {
+            s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = av_rescale(s->h, adjusted_aspect.num, adjusted_aspect.den);
+        }
+    }
+
     /* evaluate x and y */
     av_expr_parse_and_eval(&res, (expr = s->x_expr),
                            var_names, var_values,
@@ -409,6 +422,7 @@ static const AVOption pad_options[] = {
     { "eval",   "specify when to evaluate expressions",    OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
          { "init",  "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT},  .flags = FLAGS, .unit = "eval" },
          { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
+    { "aspect",  "pad to fit an aspect instead of a resolution", OFFSET(aspect), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, DBL_MAX, FLAGS },
     { NULL }
 };