[FFmpeg-devel] [RFC] AVFilter Parser

vmrsss vmrsss
Fri Mar 28 00:54:30 CET 2008

On 26 Mar 2008, at 18:55, Vitor Sessak wrote:
> I really can't see what is so special about feedback. It could be
> written like
> (tmp  in1 tmp4) filter0 (tmp  out1 tmp2);
> (tmp2 in2 tmp5) filter1 (tmp4 out2 tmp5);
> or using your syntax
> (a b), (<tmp  a tmp4>, filter0, (tmp  out1 tmp2)) *
>        		(<tmp2 b tmp5>, filter1, (tmp4 out2 tmp5)), <out1 out2>
> Why is the extra complexity of the '[]' needed?

Very good, thanks for this question, in fact that is where I started  
from. I then arrived to [ ... ] for the following reasons:

The construct (x) is a binder (that is, a scoping construct like a  
function definition in C), so that in (x)F the name x is invisible  
outside F. (This is important, so other occurrences of x are not mixed- 
up accidentally.) But then, (tmp ... ) would make tmp invisible to the  
<tmp ... > construct outside its scope... In other words, (tmp ...)  
binds to the right, while we'd rather need it to bind to the left.

Since I am unhappy about using the same symbol with two diametrically  
different meanings (it will always lead to confusion -- if you can't  
unify the notions (concepts), then keep the notations  separated too),  
I conceived [ ... ], which is similar to ( ... ), but binds in the  
other direction. (In this sense, it is similar to the T>1 and T<1  
proposed by Michael.) So I started to play with forms like:

  (filter0 * filter1)[1 _ 4 3 _ 6]

meaning: feed the 1st output back to the 1st input, let the 2nd pass  
through, feed the 3rd back to the 4th input, then the 4th back to the  
3rd, let the 5th output pass through, and finally the 6th back to the  
6th input. I find this quite readable, compositional and flexible; it  
doesn't need to be postfix -- of course! -- but that's not necessarily  
a bad choice, because it acts on the outputs to twist them backwards.  
I really like this: neat, simple, quick, essential, irredundant.

But then, since the discussion on the list had manifested a clear  
preference for (explicit) names over (implicit) numbering, I  
translated the [ ... ] above into a named form of the exact same  
intended meaning (though necessarily more verbose and not as crisp):

	( < a x b > filter0 * < c y d > filter1 ) [ a _ c b _ d ]

this has two outputs (corresponding to the two _) and two free  
variables (x and y), because a, b, c and d are bound (from the right)  
by the [ ... ] construct. Finally, by pre-pending ( x y ) I bind the  
variables x and y to be respectively the 1st and 2nd input to the  
entire filter.

Now, frankly, the only reason to say that this is more complex or  
confusing than your proposed form at the start of this message is that  
you're used to yours. What my proposal does is mainly to give  
different notations to different concepts (input ( ... ), output   
< ... > and feeback [ ... ]), in a way that is full compositional (ie  
it doesn't run into syntactic non-sense nor unexpected ambiguities)  
under very simple formal rules.

On 26 Mar 2008, at 19:44, Michael Niedermayer wrote:
> seconded, i like vitors syntax a lot more than this artificial  
> seperation
> into forward and feedback.

Well, it was actually you who introduced forward/backwards (you called  
left and right then); I thought it was quite a good idea and took it  
up. Anyway, I think the separation of inputs/outputs/feedback is not  
artificial, is there also in Vitor's proposal (in for inputs, out for  
outputs, ...) for a good reason. Vitor prefers a in/out "reserved-id  
rule"; I don't care very much for it (among other things, it reminds  
of old times Fortran IV 50 years back :-) and prefer explicit import/ 
export lists -- ie ( x y ) / < u v >.

> the main difference between
> the syntax and mine is that yours is stream based (and you link  
> streams)
> and mine is filter based (and I define links between the filters).  
> In my
> syntax "(in1),(out1)" or "(in1) (out1)" is a syntax error, filter  
> missing.

No, hopefully I have clarified that in my previous email. I think the  
proposals are very similar. The main difference is ( ... ) and its  
interplay with < ... > that cannot be mimicked easily with only one  
operator -- viz. "< u >, F" can be seen as "naming" u the input of F,  
which is emphatically *not* the same as "(x)F" (a legal term with  
different semantics). Dually, "F, (x)..." can as "naming" x the output  
of F, not the same as "F, <x>" (which most of the times will be an  
illegal term).

Summing up, my objective in this discussion is to make sure one can  
capture (I mean "get a handle to") inputs and outputs in any given  
filter (whether an atomic filter from avfilter, or a user-defined  
filter) in order to rearrange them when composing filters in complex  
graphs (using semicolon/star, comma and feedback, and no specific  
knowledge of the inner working of the filter). I think this is the one  
point that can be perfected in your current proposal, and there is a  
good case to experiment in your syntax with forms analogous to < ... >  
and ( ... ).

Anyway, I think I have given this my best shot, which sadly appears  
not to be good enough for ffmpeg. So perhaps I should stop holding you  
people up, and try to find other ways to help the project.


PS. When I say the proposal are similar, that is modulo my current  
understanding --which I am aware might not be full-- of the follow  
issue: the scope of the intermediate labels tmp... in terms like:

> 	(tmp  in1 tmp4) filter0 (tmp  out1 tmp2);
> 	(tmp2 in2 tmp5) filter1 (tmp4 out2 tmp5);

My understanding is that they are confined to the term they appear in.  
That is, if I have

	F1 = (in1 tmp) filter2 (tmp out1) and F2 = (in1 tmp) filter2 (tmp out1)

then by writing F1 ; F2 I am not mixing up the two different loops  
represented by the same variable tmp. Right?

More information about the ffmpeg-devel mailing list