[FFmpeg-soc] expand filter (alternative to pad syntax)
Vitor Sessak
vitor1001 at gmail.com
Fri May 30 18:30:21 CEST 2008
Hi
vmrsss wrote:
> Hi everybody
>
> I attach an improved version of vf_pad.c, thoroughly tested, with a
> few questions for you.
>
> (1)
> On 15 May 2008, at 10:30, Víctor Paesa wrote:
>> Try sscanf(arg,"%d:%d:%d:%d:%255[^:]:%255[^:]:%d",&a,&b,&c,&d,e,f,&g);
>
> I am having a problem with inputs like
>
> pad=::::16/9:16
>
> (which should mean "expand to a 16/9 frame mod 16"), because sscanf
> can't find the %d in between the ::, and so the conversion stops.
> Ideally the form above should be allowed, lest one needs to ask users to
> type in clumsy forms with default values as in:
>
> pad=-1:-1:-1:-1:16/9:16
>
> (which is what the code currently requires). Is there to get sscanf do
> it? I don't think so. One alternative is to use sscanf to read args one
> ":" at a time, as I currently do for two of the parameters which can
> take different forms (aspect and color).
I don't know very well sscanf, so I can't help you much with it...
> (2) Following up on the above, would a form like
>
> pad=w=...:h=...:x=...:y=...:a=...:r=...:c=....
>
> be desirable?
It depends if things like
pad=-10:-10:c=4
will be allowed. If we could maintain some compatibility with the
mplayer vf_expand filter syntax, it'll make it easier to make the
mplayer filter deprecated one day...
> It'd allow to omit parameters and list them in any order,
> but for filters with few parameters might be a cumbersome overkill. Eg
>
> scale=624:368 against scale=w=624:h=368
>
> (3) I have added the possibility of specifying a color for the padding.
> The structure which lists the colors is taken from vf_drawbox.c. If
> people like the idea, that can easily be factored out in some
> avfilter_common file.
Looks nice to me, but I think that before it is ok to be factored in a
common file (libavfilter/filter_parse_utils.c?), it should accept colors
in RGB format and have boxcolor.{r,g,b} values.
> (4) The aspect parameter doesn't work as it should for files with SAR
> different from 1. It's easy to fix, only that the sar information seems
> unavailable at the filter configuration stage (see the code); I expect
> Vitor wll be able to help on this one.
I agree that you could just add (move?) the pixel_format variable to
AVFilterLink struct. It should be pretty simple to make a patch to do it.
> (5) I have not resolved the issue of removing memcpy. There is only one
> call to memcpy in the code; to get rid of it is likely to require some
> significant change to the avfilter API, that will have to involve Vitor.
> In these circumstances, I wonder whether it would make sense to commit
> the code to SOC anyway, and then remove the one call to memcpy when
> we'll know how. (Observe that this situation is common to several filters.)
I've discussed it a little with vmrsss in pvt and I think the solution
to it would be to negotiate the link dimensions during graph creation as
we do for pix_fmt. But after this is done, the changes to make vf_pad.c
memcpy-less would be rather minor, so I think this filter is better
commited to the soc tree (after review) instead of bitrotting as a patch
in the mailing list.
> /*
> * Video pad filter
> * copyright (c) 2008 vmrsss
> *
> * This file is part of FFmpeg.
> *
> * FFmpeg is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> * License as published by the Free Software Foundation; either
> * version 2.1 of the License, or (at your option) any later version.
> *
> * FFmpeg is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> * Lesser General Public License for more details.
> *
> * You should have received a copy of the GNU Lesser General Public
> * License along with FFmpeg; if not, write to the Free Software
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> #include <string.h>
> #include <stdio.h>
>
> #include "avfilter.h"
>
> typedef struct
> {
> const char *name;
> unsigned char y;
> unsigned char cb;
> unsigned char cr;
> } box_color;
>
> #define NUM_COLORS 8
> static box_color colors[] =
> {
> {.name = "blue", .y = 40, .cr = 109, .cb = 240},
> {.name = "red", .y = 81, .cr = 240, .cb = 90},
> {.name = "black", .y = 16, .cr = 128, .cb = 128},
> {.name = "white", .y = 255, .cr = 128, .cb = 128},
> {.name = "green", .y = 144, .cr = 34, .cb = 53},
> {.name = "yellow", .y = 210, .cr = 146, .cb = 16},
> {.name = "gray", .y = 128, .cr = 128, .cb = 128},
> {.name = "grey", .y = 128, .cr = 128, .cb = 128},
> {.name = "yuv" , .y = 0, .cr = 0, .cb = 0}
> };
as I said, this is RGB unfriendly.
> typedef struct
> {
> /* required size */
> int dim[2], off[2];
> /* round to mod r */
> int r;
> /* expand to aspect a */
> double a;
I'd prefer if you use AVRation for the aspect, at least for consistency
with the rest of FFmpeg.
> /* padding color */
> int c;
> /* chroma subsampling */
> int sub[2];
> } PadContext;
This comments could be doxygen compatible...
> static int init(AVFilterContext *ctx, const char *args, void *opaque)
> {
> PadContext *pad = ctx->priv;
> char s[255];
> int n, m, r, b;
>
> /* default parameters */
> pad->dim[0] = pad->dim[1] = -1;
> pad->off[0] = pad->off[1] = -1;
> pad->r = 1;
> pad->a = 0.;
> pad->c = 2;
>
> if( !args ){
> av_log(NULL, AV_LOG_ERROR, "usage: pad=w:h:x:y:r:a:c , where\n\t\
> w,h (width, height): -1 use current size [default]; -N enlarge by N pixels\n\t\
> x,y (offsets): -N center [default]\n\t\
> r: round to mod_r [1]\n\t\
> a: expand to fit aspect [don't]\n\t\
> c (color): blue|red|black|white|green|yellow|gray|grey|yuv/Y/CR/CB [black]\n");
I think that
av_log(NULL, AV_LOG_ERROR, "\
usage: pad=w:h:x:y:r:a:c , where\n
w,h (width, height): -1 use current size [default]; -N enlarge by N
pixels\n\
x,y (offsets): -N center [default]\n\
r: round to mod_r [1]\n\
a: expand to fit aspect [don't]\n\
c (color): blue|red|black|white|green|yellow|gray|grey|yuv/Y/CR/CB
[black]\n");
Is more readable. Actually I'm thinking if the right solution wouldn't
be to add a *AVFilter.show_help field, but it is unrelated with this
review...
> sscanf(args, "%d:%d:%d:%d:%d%n",
> &pad->dim[0], &pad->dim[1], &pad->off[0], &pad->off[1], &pad->r, &n);
>
> while(*(args += n) != '\0'){
> sscanf(args, ":%[^:]%n", s, &n);
>
> if( sscanf(s,"yuv/%u/%u/%u", &m, &r, &b) == 3 ){
> colors[NUM_COLORS].y = (unsigned char)m;
> colors[NUM_COLORS].cr = (unsigned char)r;
> colors[NUM_COLORS].cb = (unsigned char)b;
This is not thread safe. It is better to have a PadContext.color[3]
field and make the colors[] array const.
[...]
>
> static void draw_padding(AVFilterLink *link)
> {
> PadContext *pad = link->dst->priv;
> AVFilterPicRef *in = link->cur_pic;
> AVFilterPicRef *out = link->dst->outputs[0]->outpic;
> int i, j, plane, vsub, hsub;
Well, it would be nice to support more pixel formats (including RGB and
YUVA). You could maybe use some of Ryo's code (having two people
contribute code for the same thing _have_ to have some advantage), but
before please try to simplify the cases with pix_fmt_info.
-Vitor
More information about the FFmpeg-soc
mailing list