[FFmpeg-devel] [PATCH] libavfilter-soc: implement pad filter

Stefano Sabatini stefano.sabatini-lala
Sat Oct 3 01:38:59 CEST 2009


On date Thursday 2009-10-01 02:28:37 +0200, Michael Niedermayer encoded:
> On Thu, Oct 01, 2009 at 01:00:16AM +0200, Stefano Sabatini wrote:
> > Sorry for the slow reply.
> [...]
> > 2) the buffer obtained by the pad filter with get_video_buffer() is
> > inverted and passed to the previous filter, as Vitor and IIUC Michael
> > proposed (check the patch: fix-vflip-logic+vitor.patch).
> >
> > Consider the filterchain: "crop=0:0:WIDTH:100, vflip"
> >
> > In this scenario the crop filter will take the top 100 lines of the
> > image in input.
> >
> >
> > This is the picref received in input by vflip.c:get_video_buffer():
> >
> >   [fig. 4]
> >
> >  O----------+
> >  | crop     |
> >  |  area    |
> >  |          |
> >  v          |
> >  +----------+
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  +----------+
> >
> > The vflip filter moves the origin to the bottom left corner of the
> > input area, and inverts the linesizes, so this is what
> > vf_crop.c:get_video_buffer() obtains:
> >
> >    [fig. 5]
> >
> >  .
> >  .
> >  .
> >  +----------+
> >  ^ crop     |
> >  |  area    |
> >  |          |
> >  |          |
> >  O----------+
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  +----------+
>
>
> i would have expected:
>
> >  +----------+
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  |          |
> >  O----------+

So the correct solution would be to invert the reference of the
*whole* allocated buffer.

The problem is that the vflip filter, as well as all the other ones,
has no idea of the bottom left corner of the allocated buffer. Maybe
if the position of the returned buffer in the allocated buffer would
be known (for example it could be stored in the picref itself) than it
would be possible to perform the correct inversion.

I'll try to give a try at this approach tomorrow.

> about the crop area shown in your figs, i dont understand how the
> get_video_buffer() code could even know about croping that is done
> at later stages. As an example assume a cropdetect filter that analzes
> the picture content and then crops the black borders, it could in no way
> know about where and what to crop when allocating the buffers

Michael, with the actual architecture that wouldn't be even possible.

The whole recursive get_video_buffer()+pad filter thing may work only
if a filter can specify to the next filter *the exact area of the
buffer it will use*, which is specified by the x, y, w, and h
parameters which are passed to the get_video_buffer() function.

Indeed when the filter writes to the buffer, it has been already
allocated, the best you can do in your scenario would be a 2-pass
processing e.g.:

* to have a cropdetect filter which writes to a log file the detected
  crop area for each frame

* to run a new filterchain, applying for each frame the crop values in
  the log file: the crop size will affect the size of each allocated
  frame.

I want to clarify this point, as this is actually one of the tricky
points of the pad filter.

The geometry of the area of buffer used by a filter needs to be
conveied to the pad filter, because on that depends how the pad filter
will request a new area.

Consider this:

                    x1        x1+w      exp_w      x1+w+padright
O--->---------------.-----------.---------+ - - - - - - . - - - -
|                   .           .         |             .
|                   .           .         |             .
|                   .           .         |             .
v            +------.-----------.---------+-------------+
|            |      x,y         .         |             |
|            |      +-----------+         |             |
|            |      | previous  |         |             |
|            |      |  filter   |         |             |
|            |      |   area    |         |             |
|            |      |           |         |             |
|            |      +-----------+         |             |
|            |                            |             |
|            +----------------------------+-------------+
|                                         |
+-----------------------------------------+
| exp_h

|

|

The x, y, h, w informations are used to detect the dimension of the
buffer to request to the next filter.

Check vf_pad.c:get_video_buffer():

static AVFilterPicRef *get_video_buffer(AVFilterLink *link, int perms,
                                        int x, int y, int w, int h, int exp_w, int exp_h)
{
    PadContext *pad = link->dst->priv;

    int padright  = pad->out_w - pad->x - w;
    int padbottom = pad->out_h - pad->y - h;
    int x1 = FFMAX(pad->x, x);
    int y1 = FFMAX(pad->y, y);

    AVFilterPicRef *picref = avfilter_get_video_buffer(link->dst->outputs[0], perms,
                                                       x = x1 - pad->x,
                                                       y = y1 - pad->y,
                                                       pad->out_w,
                                                       pad->out_h,
                                                       x1 + w + FFMAX(padright,  exp_w - x - w),
                                                       y1 + h + FFMAX(padbottom, exp_h - y - h));
...

> [...]
> > Maybe there is some way to avoid this constraint, but my question is
> > if this is really worth to strive for such a solution which adds
> > complexity to the system, especially considering that the only case
> > where it seems to make sense to invert a picref is with the vflip
> > filter.
>
> i still dont see where the problem comes from, i dont end up with the
> issue in my thought experiment ...

Regards.
--
FFmpeg = Forgiving Frenzy Mind-dumbing Philosofic Enlightened Game



More information about the ffmpeg-devel mailing list