The original interpolation algorithm behaved poorly on the borders and
did not even guarantee continuity at the borders. For this reason, a
second interpolation/blending pass was required on the borders to make
them seamless.
However, since the interpolation algorithm was improved in June 2013,
the border issues no longer exist. The new algorithm does guarantee
continuity at the borders, making the second pass useless. A larger
band always increases the cumulated interpolation error. In most cases
it also increases the average interpolation error, even though the
samples in the band are only partially interpolated.
For this reason I would like to get rid of the "band" parameter. As a
first step, let's change its default value from 4 to 1 and document it
as deprecated.
I have benchmarked this change on a combination of input sources and
realistic logo areas. Lowering the band value from 4 to 1 resulted in
8 to 39 % less interpolation error per frame (or 1 to 34 % less
interpolation error per luma sample.)
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
The code assumed that the outermost interpolated pixels were always in
the fuzzy area defined by the band option. However if the band value
is small, there may be no fuzzy area on a given plane. In that case,
option show did not work, no rectangle was drawn (or only on the luma
plane, depending on the band value and chroma plane subsampling
factors.)
Fix the problem by not making any assumption on where the outermost
interpolated pixels will be.
The new code was verified to produce the same result as the original
code when the band value is not small.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Coverity complains about a possible sign extension issue in
apply_delogo(). While it is extremely unlikely to happen, it is easy
to fix so let's just do that. Using unsigned variables even makes the
binary code smaller.
Fixes Coverity CID 1046439.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
We need at least one pixel around the logo to use as known points to
interpolate from. So properly declare the band/t attribute has having
a minimum value of 1.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Options "show" and "band" are unrelated and should thus be
independent. However, setting "show" to 1 currently resets "band" to
its default value of 4. While this is documented, this still
surprising and confusing IMHO.
Change this behavior and make "show" and "band" independent from each
other. Update the documentation accordingly.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
The left and right samples are the same for the whole line, so store
their values and don't recompute them for every iteration of "y".
This simple optimization results in a speed improvement between 15%
and 20% in my tests (depending on the logo geometry.)
Result is obviously the same.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Reviewed-by: Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
The top left hand corner pixel coordinates are already stored in
logo_x1 and logo_y1 so don't recompute each of them 6 times for every
iteration.
This is a simple code optimization, result is obviously the same. The
performance gain is small (about 2% in my tests) but still good to
have, and the new code is clearer.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Reviewed-by; Stefano Sabatini <stefasab@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
When operating on subsampled chroma planes, some rounding is taking
place. The left and top borders are rounded down while the width and
height are rounded up, so all rounding is done outward to guarantee the
logo area is fully covered.
The problem is that the width and height are counted from the
unrounded left and top borders, respectively. So if the left or top
border position has indeed been rounded down, and the width or height
needs no rounding (up), the position of the the right or bottom border
will be effectively rounded down, i.e. inward.
The issue can easily be seen with a yuv240p input and
-vf delogo=45:45:60:40:show=1 -vframes 1 delogo-bug.png
(or virtually any logo area with odd x and y and even width and
height.) The right and bottom chroma borders (in green) are clearly
off.
In order to fix this, the width and height must be adjusted to include
the bits lost in the rounding of the left and top border positions,
respectively, prior to being themselves rounded up.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
When interpolating, weights are based on relative distances, which
assume square pixels. If a non-1:1 sample aspect ratio is used, it
should be taken into account when comparing distances, because the
human eye and brain care about the picture as it is displayed, not
stored.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
The original delogo algorithm interpolates both horizontally and
vertically and uses the average to compute the resulting sample. This
works reasonably well when the logo area is almost square. However
when the logo area is significantly larger than high or higher than
large, the result is largely suboptimal.
The issue can be clearly seen by testing the delogo filter with a fake
logo area that is 200 pixels large and 2 pixels high. Vertical
interpolation gives a very good result in that case, horizontal
interpolation gives a very bad result, and the overall result is poor,
because both are given the same weight.
Even when the logo is roughly square, the current algorithm gives poor
results on the borders of the logo area, because it always gives
horizontal and vertical interpolations an equal weight, and this is
suboptimal on borders. For example, in the middle of the left hand
side border of the logo, you want to trust the left known point much
more than the right known point (which the current algorithm already
does) but also much more than the top and bottom known points (which
the current algorithm doesn't do.)
By properly weighting each known point when computing the value of
each interpolated pixel, the visual result is much better, especially
on borders and/or for high or large logo areas.
The algorithm I implemented guarantees that the weight of each of the
4 known points directly depends on its distance to the interpolated
point. It is largely inspired from the original algorithm, the key
difference being that it computes the relative weights globally
instead of separating the vertical and horizontal interpolations and
combining them afterward.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
The algorithm works on src and writes to dst, not the other way
around.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
* commit 'ba09675f44612fad9f7169f71b8276beb50a0dcd':
vf_delogo: use the name 's' for the pointer to the private context
vf_cropdetect: use the name 's' for the pointer to the private context
vf_crop: cosmetics, break lines
Conflicts:
libavfilter/vf_delogo.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
With the introduction of AVFilterContext->is_disabled, we can simplify
the custom passthrough mode in filters.
This commit is technically a small compat break, but the timeline was
introduced very recently.
Doxy by Stefano Sabatini.
This should fix several issues with odd dimensions inputs.
lut, vflip, pad and crop video filters also need to be checked for such
issues. It's possible sws is also affected.
* commit '63e58c55c17d7f8b5eec9c082fe0f8edc305a24e':
vf_delogo: switch to an AVOptions-based system.
Conflicts:
libavfilter/vf_delogo.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
video->[wh] will be set with the same values as the input after
avfilter_copy_buffer_ref_props. These filters don't change the size of
the input so there is no need for this code.
A number of compilers, for example those from TI and IBM, choke on
these initialisers. The current style is also quite ugly.
Signed-off-by: Mans Rullgard <mans@mansr.com>