[FFmpeg-devel] [PATCH] [2/??] [3/3] Filter graphs - Parser for a graph description

Vitor Sessak vitor1001
Sun Mar 16 17:09:37 CET 2008


Michael Niedermayer wrote:
> On Sat, Mar 15, 2008 at 09:29:03PM +0100, Vitor Sessak wrote:
>> Hi
>>
>> Michael Niedermayer wrote:
>>> On Mon, Feb 25, 2008 at 06:36:40PM +0100, Vitor Sessak wrote:
>>> [...]
>>>>>> And for
>>>>>>
>>>>>>   in --> crop --> rotate --> vflip --> out
>>>>>>
>>>>>> crop=400:300,rotate=1,vflip,split
>>>>> yes (in) (out) should be default at the ends
>>>>>
>>>>>
>>>>>> meaning that when there is no semicolon, the (in) in the beginning and 
>>>>>> the (out) in the end can be omitted. Also, I don't understand the point 
>>>>>> of explicitly putting a "+" in new vertexes...
>>>>> filter1(abc),(def)filter2
>>>>>
>>>>> filter1->(abc)
>>>>> (def)->filter2
>>>>>
>>>>> filter1(+abc),(+def)filter2
>>>>>
>>>>> filter1->filter2
>>>>>   |         ^
>>>>>   v         |
>>>>> (abc)     (def)
>>>>>
>>>>> again, this was all just an idea ...
>>>>> your ';' achives the same, though it adds an additional char to the ones
>>>>> needing escaping if used in filters. Iam not even sure if we shoud use 
>>>>> ',' as
>>>>> filter seperator ...
>>>>> '|' would be an alternative but it would need filter chains to be under 
>>>>> ""
>>>>> though that applies to ; () [] as well
>>>> I prefer the comma. I like the syntax
>>>>
>>>> ffmpeg -i in.avi -vfilters vflip,scale=300:400 out.avi
>>>>
>>>> so as for filter graphs that are just a chain we have a simple, unescaped 
>>>> command line. If for more complex graphs "" are needed, it bother me 
>>>> less.
>>>>
>>>>> other random ideas ...
>>>>>
>>>>> crop=400:300|[tmp1]picInPic=50:50|rotate=1|split[tmp2]|vflip[out];[tmp2]hflip|delay[tmp1]
>>>>>
>>>>> crop=400:300 | [tmp1]picInPic=50:50 | rotate=1 | split[tmp2] | 
>>>>> vflip[out] ; [tmp2]hflip | delay[tmp1]
>>>>>
>>>>> crop=400:300 | [tmp1] picInPic=50:50 | rotate=1 | split [tmp2] | vflip 
>>>>> [out] ; [tmp2] hflip | delay [tmp1]
>>>> Wouldn't it be a good idea to ignore whitespace and newlines completely?
>>> That was the idea, sorry ive just been testing how different whitespace
>>> placements would look ...
>>>>> crop=400:300 | [tmp1] picInPic=50:50 | rotate=1 | split {hflip | 
>>>>> delay[tmp1];} | vflip
>>>>>
>>>>>
>>>>>
>>>>>> Finally, I prefer parenthesis instead of brackets... What do you think?
>>>>> Passing eval.c equation like sin(5)*eq(a,b) might get trickier escaping
>>>>> wise and parsing wise with (), besides this iam fine with () as well, 
>>>>> that
>>>>> is if you provide a solution to passing equations to eval based filters
>>>>> without requireing each () to be escaped individually.
>>>> I agree. But I'll have to add quotes to the syntax anyway for thing like
>>>>
>>>> vflip,drawtext='text, a   =)   :-]':arial:10:10,hflip
>>> well mplayer survivied without proper quote handling, and that results in
>>> eval stuff looking really nasty ...
>> Well, this is more of a RFC than a patch, since parsers are not my strong 
>> point. The file was rewritten almost from scratch. Now the it accepts 
>> things like
>>
>>  (  in  )   split(i1),fifo,(i2)overlay=0:240(out);(i1)vflip(i2)
>>
>> or
>>
>> vflip,scale=10:30
> 
> 
> [...]
> 
>> typedef struct Parser
>> {
>>     char next_chr;
>>     char *buf;
>> } Parser;
> 
> Could you explain what this next_chr thing is good for?
> Iam no string parser expert but my gut feeling says char *buf would be enough
> and if so we could avoid the struct.

buf =  'test,blah\0'

To read the 'test' part in consume_string() without any memcpy, I put a 
\0 after 'test' in the buffer and return a pointer to the start of the 
string. But to do that, I have to overwrite the comma. So I put the 
comma in the next_chr var.


> 
> 
>> static void consume_whitespace(Parser *p)
>> {
>>     while (p->next_chr == ' ' || p->next_chr == '\n' || p->next_chr == '\t')
>>         p->next_chr = *(++p->buf);
>> }
> 
> id replace all consume_whitespace() by
> ptr += strspn(ptr, " \n\t");

Looks a good idea, I'll look into it.

> 
> 
> [...]
> 
> 
>> static char *consume_string(Parser *p, int escaped)
>> {
> 
> What does the "escaped" do? Document or remove it please!

buf = "'bbb;ccc)ddd'"

consume_string(p, 1) == "bbb;ccc)ddd"
consume_string(p, 0) == "'bbb"

But I agree it should be documented.

> 
> 
> [...]
>> static int parse_link_name(Parser *p, char **name)
>> {
>>     if (consume_char(p) != '(')
>>         goto fail;
>>
>>     *name = consume_string(p,0);
>>
>>     if (!*name[0])
>>         goto fail;
>>
>>     if (consume_char(p) != ')')
>>         goto fail;
>>
>>     return 0;
>>
>>  fail:
>>     *name = NULL;
>>     return AVERROR_INVALIDDATA;
>> }
> 
> We need some clear error messages for the various failures. Not only here
> of course ...

What should I do? av_log(NULL, AV_LOG_ERROR, "...")? Is in those cases 
ok to have no context?

> 
> 
> [...]
>>     single_chain = (strchr(filters, '(') == NULL);
> 
> why the special case?

To make

(in) vflip, hflip (out)

the same as

flip, hflip

without erroneously adding a '(in)' in the beginning of the following:

movie_src=test.avi, vflip, (in)overlay(out)

The syntax is that adding explicitly '(in)' and '(out)' is mandated for 
anything more complicated than a single chain.

-Vitor




More information about the ffmpeg-devel mailing list