diff mbox

[FFmpeg-devel] avfilter/vf_pad: add aspect option

Message ID 20170402200946.26238-1-onemda@gmail.com
State Accepted
Headers show

Commit Message

Paul B Mahol April 2, 2017, 8:09 p.m. UTC
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 doc/filters.texi     |  3 +++
 libavfilter/vf_pad.c | 14 ++++++++++++++
 2 files changed, 17 insertions(+)

Comments

Paul B Mahol April 2, 2017, 9:13 p.m. UTC | #1
On 4/2/17, Paul B Mahol <onemda@gmail.com> wrote:
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  doc/filters.texi     |  3 +++
>  libavfilter/vf_pad.c | 14 ++++++++++++++
>  2 files changed, 17 insertions(+)
>
> +    if (adjusted_aspect.num && adjusted_aspect.den) {
> +        adjusted_aspect = av_mul_q(adjusted_aspect, av_make_q(s->w,
                                                       ^ changed to
sample aspect ratio locally.

> s->h));
> +        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);
> +        }
> +    }
> +
Ricardo Constantino April 3, 2017, 6:07 p.m. UTC | #2
On 2 April 2017 at 22:13, Paul B Mahol <onemda@gmail.com> wrote:

> On 4/2/17, Paul B Mahol <onemda@gmail.com> wrote:
> > Signed-off-by: Paul B Mahol <onemda@gmail.com>
> > ---
> >  doc/filters.texi     |  3 +++
> >  libavfilter/vf_pad.c | 14 ++++++++++++++
> >  2 files changed, 17 insertions(+)
> >
> > +    if (adjusted_aspect.num && adjusted_aspect.den) {
> > +        adjusted_aspect = av_mul_q(adjusted_aspect, av_make_q(s->w,
>                                                        ^ changed to
> sample aspect ratio locally.
>
Shouldn't this av_mul_q be a
av_div_q(adjusted_aspect, inlink->sample_aspect_ratio) instead?

That way it won't try to expand 40/33 SAR 704x480 to 1034x480 but
instead leave it as 704x480.


>
> > s->h));
> > +        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);
> > +        }
> > +    }
> > +
Paul B Mahol April 3, 2017, 6:18 p.m. UTC | #3
On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> On 2 April 2017 at 22:13, Paul B Mahol <onemda@gmail.com> wrote:
>
>> On 4/2/17, Paul B Mahol <onemda@gmail.com> wrote:
>> > Signed-off-by: Paul B Mahol <onemda@gmail.com>
>> > ---
>> >  doc/filters.texi     |  3 +++
>> >  libavfilter/vf_pad.c | 14 ++++++++++++++
>> >  2 files changed, 17 insertions(+)
>> >
>> > +    if (adjusted_aspect.num && adjusted_aspect.den) {
>> > +        adjusted_aspect = av_mul_q(adjusted_aspect, av_make_q(s->w,
>>                                                        ^ changed to
>> sample aspect ratio locally.
>>

Have you missed what I wrote above?

> Shouldn't this av_mul_q be a
> av_div_q(adjusted_aspect, inlink->sample_aspect_ratio) instead?
>
> That way it won't try to expand 40/33 SAR 704x480 to 1034x480 but
> instead leave it as 704x480.

Why div_q ?

>
>
>>
>> > s->h));
>> > +        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);
>> > +        }
>> > +    }
>> > +
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Ricardo Constantino April 3, 2017, 6:43 p.m. UTC | #4
On 3 April 2017 at 19:18, Paul B Mahol <onemda@gmail.com> wrote:

> On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> > On 2 April 2017 at 22:13, Paul B Mahol <onemda@gmail.com> wrote:
> >
> >> On 4/2/17, Paul B Mahol <onemda@gmail.com> wrote:
> >> > Signed-off-by: Paul B Mahol <onemda@gmail.com>
> >> > ---
> >> >  doc/filters.texi     |  3 +++
> >> >  libavfilter/vf_pad.c | 14 ++++++++++++++
> >> >  2 files changed, 17 insertions(+)
> >> >
> >> > +    if (adjusted_aspect.num && adjusted_aspect.den) {
> >> > +        adjusted_aspect = av_mul_q(adjusted_aspect, av_make_q(s->w,
> >>                                                        ^ changed to
> >> sample aspect ratio locally.
> >>
>
> Have you missed what I wrote above?
>
> > Shouldn't this av_mul_q be a
> > av_div_q(adjusted_aspect, inlink->sample_aspect_ratio) instead?
> >
> > That way it won't try to expand 40/33 SAR 704x480 to 1034x480 but
> > instead leave it as 704x480.
>
> Why div_q ?
>

with av_mul_q(adjusted_aspect, inlink->sample_aspect_ratio):

$ ffmpeg -f lavfi -i "color=s=704x480,setsar=40/33" -vf
pad=aspect=16/9,scale=iw*sar:ih -vframes 1 -f null - -v verbose 2>&1 | grep
-E "(Parsed_pad|Parsed_scale)"
[Parsed_scale_1 @ 000001e46c6c60a0] w:iw*sar h:ih flags:'bicubic' interl:0
[Parsed_pad_0 @ 000001e46c6c5bc0] w:704 h:480 -> w:1034 h:480 x:0 y:0
color:0x000000FF
[Parsed_scale_1 @ 000001e46c6c60a0] w:1034 h:480 fmt:yuv420p sar:40/33 ->
w:1253 h:480 fmt:yuv420p sar:3760/3759 flags:0x4

with av_div_q(adjusted_aspect, inlink->sample_aspect_ratio):

$ ffmpeg -f lavfi -i "color=s=704x480,setsar=40/33" -vf
pad=aspect=16/9,scale=iw*sar:ih -vframes 1 -f null - -v verbose 2>&1 | grep
-E "(Parsed_pad|Parsed_scale)"
[Parsed_scale_1 @ 000001522e496720] w:iw*sar h:ih flags:'bicubic' interl:0
[Parsed_pad_0 @ 000002b8a29c8260] w:704 h:480 -> w:704 h:480 x:0 y:0
color:0x000000FF
[Parsed_scale_1 @ 000001522e496720] w:704 h:480 fmt:yuv420p sar:40/33 ->
w:853 h:480 fmt:yuv420p sar:2560/2559 flags:0x4
Paul B Mahol April 3, 2017, 6:58 p.m. UTC | #5
On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> On 3 April 2017 at 19:18, Paul B Mahol <onemda@gmail.com> wrote:
>
>> On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
>> > On 2 April 2017 at 22:13, Paul B Mahol <onemda@gmail.com> wrote:
>> >
>> >> On 4/2/17, Paul B Mahol <onemda@gmail.com> wrote:
>> >> > Signed-off-by: Paul B Mahol <onemda@gmail.com>
>> >> > ---
>> >> >  doc/filters.texi     |  3 +++
>> >> >  libavfilter/vf_pad.c | 14 ++++++++++++++
>> >> >  2 files changed, 17 insertions(+)
>> >> >
>> >> > +    if (adjusted_aspect.num && adjusted_aspect.den) {
>> >> > +        adjusted_aspect = av_mul_q(adjusted_aspect, av_make_q(s->w,
>> >>                                                        ^ changed to
>> >> sample aspect ratio locally.
>> >>
>>
>> Have you missed what I wrote above?
>>
>> > Shouldn't this av_mul_q be a
>> > av_div_q(adjusted_aspect, inlink->sample_aspect_ratio) instead?
>> >
>> > That way it won't try to expand 40/33 SAR 704x480 to 1034x480 but
>> > instead leave it as 704x480.
>>
>> Why div_q ?
>>
>
> with av_mul_q(adjusted_aspect, inlink->sample_aspect_ratio):
>
> $ ffmpeg -f lavfi -i "color=s=704x480,setsar=40/33" -vf
> pad=aspect=16/9,scale=iw*sar:ih -vframes 1 -f null - -v verbose 2>&1 | grep
> -E "(Parsed_pad|Parsed_scale)"
> [Parsed_scale_1 @ 000001e46c6c60a0] w:iw*sar h:ih flags:'bicubic' interl:0
> [Parsed_pad_0 @ 000001e46c6c5bc0] w:704 h:480 -> w:1034 h:480 x:0 y:0
> color:0x000000FF
> [Parsed_scale_1 @ 000001e46c6c60a0] w:1034 h:480 fmt:yuv420p sar:40/33 ->
> w:1253 h:480 fmt:yuv420p sar:3760/3759 flags:0x4
>
> with av_div_q(adjusted_aspect, inlink->sample_aspect_ratio):
>
> $ ffmpeg -f lavfi -i "color=s=704x480,setsar=40/33" -vf
> pad=aspect=16/9,scale=iw*sar:ih -vframes 1 -f null - -v verbose 2>&1 | grep
> -E "(Parsed_pad|Parsed_scale)"
> [Parsed_scale_1 @ 000001522e496720] w:iw*sar h:ih flags:'bicubic' interl:0
> [Parsed_pad_0 @ 000002b8a29c8260] w:704 h:480 -> w:704 h:480 x:0 y:0
> color:0x000000FF
> [Parsed_scale_1 @ 000001522e496720] w:704 h:480 fmt:yuv420p sar:40/33 ->
> w:853 h:480 fmt:yuv420p sar:2560/2559 flags:0x4

Yes, but that conflict with expand behaviour.
Ricardo Constantino April 3, 2017, 7:01 p.m. UTC | #6
On 3 April 2017 at 19:58, Paul B Mahol <onemda@gmail.com> wrote:

>
> Yes, but that conflict with expand behaviour.
>
>
How so? Still works fine with squared pixels:
$ ffmpeg -f lavfi -i "color=s=hd720" -vf pad=aspect=4/3 -vframes 1 -f null
- -v verbose 2>&1 | grep Parsed_pad
[Parsed_pad_0 @ 000001c953343940] w:1280 h:720 -> w:1280 h:960 x:0 y:0
color:0x000000FF
Paul B Mahol April 3, 2017, 7:04 p.m. UTC | #7
On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> On 3 April 2017 at 19:58, Paul B Mahol <onemda@gmail.com> wrote:
>
>>
>> Yes, but that conflict with expand behaviour.
>>
>>
> How so? Still works fine with squared pixels:
> $ ffmpeg -f lavfi -i "color=s=hd720" -vf pad=aspect=4/3 -vframes 1 -f null
> - -v verbose 2>&1 | grep Parsed_pad
> [Parsed_pad_0 @ 000001c953343940] w:1280 h:720 -> w:1280 h:960 x:0 y:0
> color:0x000000FF

I mean this:

mpv ~/Videos/derf/akiyo_cif.y4m -vf lavfi="[setsar=40/33],expand=aspect=16/9"

mpv ~/Videos/derf/akiyo_cif.y4m -vf
lavfi="[setsar=40/33,pad=x=(ow-iw)/2:y=(oh-ih)/2:aspect=16/9]"

Gives different padding when using div instead of mul.
Ricardo Constantino April 3, 2017, 7:23 p.m. UTC | #8
On 3 April 2017 at 20:04, Paul B Mahol <onemda@gmail.com> wrote:

> On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> > On 3 April 2017 at 19:58, Paul B Mahol <onemda@gmail.com> wrote:
> >
> >>
> >> Yes, but that conflict with expand behaviour.
> >>
> >>
> > How so? Still works fine with squared pixels:
> > $ ffmpeg -f lavfi -i "color=s=hd720" -vf pad=aspect=4/3 -vframes 1 -f
> null
> > - -v verbose 2>&1 | grep Parsed_pad
> > [Parsed_pad_0 @ 000001c953343940] w:1280 h:720 -> w:1280 h:960 x:0 y:0
> > color:0x000000FF
>
> I mean this:
>
> mpv ~/Videos/derf/akiyo_cif.y4m -vf lavfi="[setsar=40/33],expand=
> aspect=16/9"
>
> mpv ~/Videos/derf/akiyo_cif.y4m -vf
> lavfi="[setsar=40/33,pad=x=(ow-iw)/2:y=(oh-ih)/2:aspect=16/9]"
>
> Gives different padding when using div instead of mul.
>
>
Oh, correct. mpv's expand also worked wrong with non-square pixels.
That's exactly why I had the idea to experiment with div instead of mul and
that did the proper expand/pad.
Paul B Mahol April 3, 2017, 8:38 p.m. UTC | #9
On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
> On 3 April 2017 at 20:04, Paul B Mahol <onemda@gmail.com> wrote:
>
>> On 4/3/17, Ricardo Constantino <wiiaboo@gmail.com> wrote:
>> > On 3 April 2017 at 19:58, Paul B Mahol <onemda@gmail.com> wrote:
>> >
>> >>
>> >> Yes, but that conflict with expand behaviour.
>> >>
>> >>
>> > How so? Still works fine with squared pixels:
>> > $ ffmpeg -f lavfi -i "color=s=hd720" -vf pad=aspect=4/3 -vframes 1 -f
>> null
>> > - -v verbose 2>&1 | grep Parsed_pad
>> > [Parsed_pad_0 @ 000001c953343940] w:1280 h:720 -> w:1280 h:960 x:0 y:0
>> > color:0x000000FF
>>
>> I mean this:
>>
>> mpv ~/Videos/derf/akiyo_cif.y4m -vf lavfi="[setsar=40/33],expand=
>> aspect=16/9"
>>
>> mpv ~/Videos/derf/akiyo_cif.y4m -vf
>> lavfi="[setsar=40/33,pad=x=(ow-iw)/2:y=(oh-ih)/2:aspect=16/9]"
>>
>> Gives different padding when using div instead of mul.
>>
>>
> Oh, correct. mpv's expand also worked wrong with non-square pixels.
> That's exactly why I had the idea to experiment with div instead of mul and
> that did the proper expand/pad.

Applied with div instead. It can be improved later anyway.
diff mbox

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 8e5e21f..bc37e66 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -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}
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 61927b6..5b81379 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -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_mul_q(adjusted_aspect, av_make_q(s->w, s->h));
+        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 }
 };