diff mbox series

[FFmpeg-devel] avfilter/pad: round output width/height up instead of down. Fixes bugs #1618 and #8475.

Message ID 20200127035318.qjbykxzoqgzsgsvl@debian
State New
Headers show
Series [FFmpeg-devel] avfilter/pad: round output width/height up instead of down. Fixes bugs #1618 and #8475. | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Ivan Middleton Jan. 27, 2020, 3:53 a.m. UTC
The pad filter is currently broken for cases where all of the following hold:

(1) chroma subsampling exists (very common),

(2) an input dimension is odd (uncommon), and

(3) the corresponding output dimension is either the same as the input,
or an expression like "ow-iw" or "oh-ih" is used to place the image at
the right/bottom edge and the extra padding is even in size.

The cause of the breakage is essentially that the output width and
height are being rounded downward, causing the image to exceed the
padded area slightly.

It seems best to me to simply round the output width/height up instead 
of down, so I've attached a patch to do that. This fixes bugs #1618 and
#8475.

Commands to reproduce the bug:

# create 15x15 test jpeg with 4:2:0 subsampling
ffmpeg -f lavfi -i color=red:15x15,format=rgb24 -vframes 1 -vf format=yuvj420p red.jpg

# output size = input size. fails
ffmpeg -i red.jpg -vf pad=iw:ih:0:0 pad1.png

# input at bottom right of output. fails
ffmpeg -i red.jpg -vf pad=iw+16:ih+16:ow-iw:oh-ih pad2.png

Ivan

Comments

Ivan Middleton Feb. 5, 2020, 11:28 p.m. UTC | #1
Hoping someone can review this and apply it if it looks good.

> The pad filter is currently broken for cases where all of the following hold:
> 
> (1) chroma subsampling exists (very common),
> 
> (2) an input dimension is odd (uncommon), and
> 
> (3) the corresponding output dimension is either the same as the input,
> or an expression like "ow-iw" or "oh-ih" is used to place the image at
> the right/bottom edge and the extra padding is even in size.
> 
> The cause of the breakage is essentially that the output width and
> height are being rounded downward, causing the image to exceed the
> padded area slightly.
> 
> It seems best to me to simply round the output width/height up instead 
> of down, so I've attached a patch to do that. This fixes bugs #1618 and
> #8475.
> 
> Commands to reproduce the bug:
> 
> # create 15x15 test jpeg with 4:2:0 subsampling
> ffmpeg -f lavfi -i color=red:15x15,format=rgb24 -vframes 1 -vf format=yuvj420p red.jpg
> 
> # output size = input size. fails
> ffmpeg -i red.jpg -vf pad=iw:ih:0:0 pad1.png
> 
> # input at bottom right of output. fails
> ffmpeg -i red.jpg -vf pad=iw+16:ih+16:ow-iw:oh-ih pad2.png
> 
> Ivan
> 
> ---
>  libavfilter/vf_pad.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
> index e86292e..493e342 100644
> --- a/libavfilter/vf_pad.c
> +++ b/libavfilter/vf_pad.c
> @@ -178,8 +178,8 @@ static int config_input(AVFilterLink *inlink)
>      if (s->y < 0 || s->y + inlink->h > s->h)
>          s->y = var_values[VAR_Y] = (s->h - inlink->h) / 2;
>  
> -    s->w    = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
> -    s->h    = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
> +    s->w    = ff_draw_round_to_sub(&s->draw, 0, +1, s->w);
> +    s->h    = ff_draw_round_to_sub(&s->draw, 1, +1, s->h);
>      /* sanity check params */
>      if (s->w < inlink->w || s->h < inlink->h) {
>          av_log(ctx, AV_LOG_ERROR, "Padded dimensions cannot be smaller than input dimensions.\n");
> -- 
> 2.20.1
diff mbox series

Patch

From 52030219e09b5f9611ca6232b1f24197363fc23b Mon Sep 17 00:00:00 2001
From: Ivan Middleton <ivan.middleton@gmail.com>
Date: Sun, 26 Jan 2020 20:25:59 -0700
Subject: [PATCH] avfilter/pad: round output width/height up instead of down.
 Fixes bugs #1618 and #8475.

---
 libavfilter/vf_pad.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index e86292e..493e342 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -178,8 +178,8 @@  static int config_input(AVFilterLink *inlink)
     if (s->y < 0 || s->y + inlink->h > s->h)
         s->y = var_values[VAR_Y] = (s->h - inlink->h) / 2;
 
-    s->w    = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
-    s->h    = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
+    s->w    = ff_draw_round_to_sub(&s->draw, 0, +1, s->w);
+    s->h    = ff_draw_round_to_sub(&s->draw, 1, +1, s->h);
     /* sanity check params */
     if (s->w < inlink->w || s->h < inlink->h) {
         av_log(ctx, AV_LOG_ERROR, "Padded dimensions cannot be smaller than input dimensions.\n");
-- 
2.20.1