diff mbox

[FFmpeg-devel,1/2] lavfi: add FFFrameQueue API.

Message ID 20161127160852.5460-1-george@nsup.org
State Accepted
Headers show

Commit Message

Nicolas George Nov. 27, 2016, 4:08 p.m. UTC
Signed-off-by: Nicolas George <george@nsup.org>
---
 libavfilter/Makefile     |   1 +
 libavfilter/framequeue.c | 123 +++++++++++++++++++++++++++++++++
 libavfilter/framequeue.h | 173 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 297 insertions(+)
 create mode 100644 libavfilter/framequeue.c
 create mode 100644 libavfilter/framequeue.h


Unchanged.

Comments

James Almer Dec. 21, 2016, 8:43 p.m. UTC | #1
On 11/27/2016 1:08 PM, Nicolas George wrote:
> Signed-off-by: Nicolas George <george@nsup.org>
> ---
>  libavfilter/Makefile     |   1 +
>  libavfilter/framequeue.c | 123 +++++++++++++++++++++++++++++++++
>  libavfilter/framequeue.h | 173 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 297 insertions(+)
>  create mode 100644 libavfilter/framequeue.c
>  create mode 100644 libavfilter/framequeue.h
> 
> 
> Unchanged.
> 
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile

This patchset broke 83 fate tests using valgrind. Looks like memleaks.

http://fate.ffmpeg.org/report.cgi?time=20161221122451&slot=x86_64-archlinux-gcc-valgrindundef
http://fate.ffmpeg.org/report.cgi?time=20161221133057&slot=x86_64-archlinux-gcc-valgrind
Nicolas George Dec. 21, 2016, 8:58 p.m. UTC | #2
Le primidi 1er nivôse, an CCXXV, James Almer a écrit :
> This patchset broke 83 fate tests using valgrind. Looks like memleaks.
> 
> http://fate.ffmpeg.org/report.cgi?time=20161221122451&slot=x86_64-archlinux-gcc-valgrindundef
> http://fate.ffmpeg.org/report.cgi?time=20161221133057&slot=x86_64-archlinux-gcc-valgrind

I thought I had got them all :( I will look into it.

Regards,
Nicolas George Dec. 22, 2016, 9:46 a.m. UTC | #3
Le primidi 1er nivôse, an CCXXV, Nicolas George a écrit :
> I thought I had got them all :( I will look into it.

That was silly. Fixed.

Regards,
wm4 Dec. 22, 2016, 12:12 p.m. UTC | #4
On Sun, 27 Nov 2016 17:08:51 +0100
Nicolas George <george@nsup.org> wrote:

> Signed-off-by: Nicolas George <george@nsup.org>
> ---

So this was pushed without addressing any of my concerns?
Nicolas George Dec. 22, 2016, 12:33 p.m. UTC | #5
Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> So this was pushed without addressing any of my concerns?

Indeed, and you were warned.

For reference for other readers, "my concerns" were matter of personal
taste formulated as nonconstructive passive-aggressive questions, and my
warning was:
http://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html

Regards,
wm4 Dec. 22, 2016, 1:47 p.m. UTC | #6
On Thu, 22 Dec 2016 13:33:20 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> > So this was pushed without addressing any of my concerns?  
> 
> Indeed, and you were warned.
> 
> For reference for other readers, "my concerns" were matter of personal
> taste formulated as nonconstructive passive-aggressive questions, and my
> warning was:
> http://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html
> 
> Regards,
> 

That is not true. They were all technical and concerns and I was polite
enough.

I will consider ignoring feature patch reviews from you as well, then.
Nicolas George Dec. 22, 2016, 1:52 p.m. UTC | #7
Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> That is not true. They were all technical and concerns and I was polite
> enough.

No. And you had ample time to make your point between 2016-11-14 and
2016-12-18.

> I will consider ignoring feature patch reviews from you as well, then.

Do not start a war.

Regards,
wm4 Dec. 22, 2016, 2:23 p.m. UTC | #8
On Thu, 22 Dec 2016 14:52:23 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> > That is not true. They were all technical and concerns and I was polite
> > enough.  
> 
> No. And you had ample time to make your point between 2016-11-14 and
> 2016-12-18.

You didn't respond to my concerns. There was no indication that
repeating my concerns would have changed anything. It was up to you.

It's funny how your accusations reflect on yourself, though.

> > I will consider ignoring feature patch reviews from you as well, then.  
> 
> Do not start a war.

If I do the same thing as you do, it's me who starts a war?

This is not my problem, but yours.
Nicolas George Dec. 22, 2016, 2:28 p.m. UTC | #9
Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> You didn't respond to my concerns. There was no indication that
> repeating my concerns would have changed anything. It was up to you.

Repeating them would have changed noting indeed: still rude and
nonconstructive.

Rewording them would have been the right thing to do.

You opted to wait a month and pretend you were surprised.

I think this discussion has already gone long enough. 

> If I do the same thing as you do, it's me who starts a war?

You are not doing the same thing, since I replied and you only waited.
If you really think I did more wrong than you in this instance, find
someone neutral who agree and with whom I can discuss.

In the meantime, ignoring reviews as you threaten to do is not ok.

Regards,
wm4 Dec. 22, 2016, 2:46 p.m. UTC | #10
On Thu, 22 Dec 2016 15:28:53 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> > You didn't respond to my concerns. There was no indication that
> > repeating my concerns would have changed anything. It was up to you.  
> 
> Repeating them would have changed noting indeed: still rude and
> nonconstructive.

Suggesting that my comments were rude is rude in itself. I did not
treat you in a rude way, especially not in my original comment.

And that's not for me to prove. In fact, your behavior right now is
incredibly rude.

> Rewording them would have been the right thing to do.

Oh, so I should just have reworded what I said after 1 month of no
reaction. That's ridiculous. How often does one have to reword a post
after no reply until you grace yourself to bother to accept it? You
know I can do the same to you. Do you want that? Do you want that sort
of development culture?

> You opted to wait a month and pretend you were surprised.

Again, you better not want to argue this way.

> I think this discussion has already gone long enough. 

Me too.

> > If I do the same thing as you do, it's me who starts a war?  
> 
> You are not doing the same thing, since I replied and you only waited.
> If you really think I did more wrong than you in this instance, find
> someone neutral who agree and with whom I can discuss.
> 
> In the meantime, ignoring reviews as you threaten to do is not ok.

You ignored my review as well, for "a month" as you admit yourself
above. This is not ok. Now you get the consequences.

It's always the same with you. It's either your way, or sitting it out
until others lose interest and give up. Or just pushing your changes,
knowingly ignoring review comments.

This is so not OK.

I'll leave it to others to waste their time trying to argue with you.
Nicolas George Dec. 22, 2016, 2:59 p.m. UTC | #11
Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> You ignored my review as well, for "a month" as you admit yourself
> above.

This is a lie. The last message in the discussion before the month gap
was mine, not yours. You neglected to reply and waited, not me.

If you ever ignore a review from me on purpose, I will be entitled to
revert your commits. You are warned.

EOT for me.

Regards,
wm4 Dec. 22, 2016, 3:05 p.m. UTC | #12
On Thu, 22 Dec 2016 15:59:19 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
> > You ignored my review as well, for "a month" as you admit yourself
> > above.  
> 
> This is a lie. The last message in the discussion before the month gap
> was mine, not yours. You neglected to reply and waited, not me.

I see no reply from you. The first was in November, at least 3 weeks
later.

> If you ever ignore a review from me on purpose, I will be entitled to
> revert your commits. You are warned.

Are you seriously threatening an edit war after all the bullshit you
gave me? How about I revert your commits?

But, you know, I'm not really interested in your bullshit game, so it's
your win - as usual. You keep the bullshit coming until the other side
gives up. Nobody will care anyway because you know why.
James Almer Dec. 22, 2016, 3:14 p.m. UTC | #13
On 12/22/2016 11:59 AM, Nicolas George wrote:
> Le duodi 2 nivôse, an CCXXV, wm4 a écrit :
>> You ignored my review as well, for "a month" as you admit yourself
>> above.
> 
> This is a lie. The last message in the discussion before the month gap
> was mine, not yours. You neglected to reply and waited, not me.
> 
> If you ever ignore a review from me on purpose, I will be entitled to
> revert your commits. You are warned.

And you ignored his. You're basically telling him he can revert this patch
of yours unless you address his concerns soon.

Here: https://ffmpeg.org/pipermail/ffmpeg-devel/2016-October/201657.html
He's been waiting for a reply for two months now.
Nicolas George Dec. 22, 2016, 3:16 p.m. UTC | #14
Thanks for stepping in.

Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> And you ignored his.

No, the reply was there:
http://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html

Not directly connected in the thread, but still a reply. No news from
wm4 since, until after the fact.

Regards,
James Almer Dec. 22, 2016, 3:23 p.m. UTC | #15
On 12/22/2016 12:16 PM, Nicolas George wrote:
> Thanks for stepping in.
> 
> Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
>> And you ignored his.
> 
> No, the reply was there:
> http://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html
> 
> Not directly connected in the thread, but still a reply. No news from
> wm4 since, until after the fact.

How's that addressing his concerns? I see no technical argument in there.
You're telling him "I'm willingly ignoring your review". That's absolutely
unacceptable.

You have always put technical arguments above everything else and used
that to force your way and your patches on this list. Address or challenge
his technical arguments right now, or let this thread be the evidence of
your double standards and hypocrisy in front of the eyes of everyone on
this list.
Nicolas George Dec. 22, 2016, 3:51 p.m. UTC | #16
Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> How's that addressing his concerns?

The answer I would have posted directly to his remarks would have been:

# > Is all this complexity really justified?
# 
# Yes, all this complexity is really justified, including the "leaky
# abstraction", and you would know it if you deigned look at the 45k patch
# that comes next and spare to the question one thousandth of the time I
# spent on it. Furthermore, making it even more complex by having it
# generic would be incredibly stupid. Unless you have precise and/or
# constructive remarks, the file stays as is.

I consider extremely rude from wm4 to have asked such naive, or rather
passive-aggressive ("Is all this complexity really justified?" actually
means "your crap is too complex") questions without taking the minimum
time to observe the use of the code in the next patch. Especially since
we had our differences in the past.

Ignoring wm4's comments that I consider rude instead of escalating on
the mailing list was specifically asked to me, and I did just that.

Now, maybe I was too curt in this mail:
https://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html
Maybe; I do often do not try to rein my temper. Productive answers were
still possible. For example:

# I did not intend to be rude, and I do not consider I was. Please
# explain your problem.

Or even, to somebody neutral in private:

# Please ask this asshole to give a proper reply to my review.

That would have been the smart thing to do. Even just an insult would
have been something. But instead, wm4 elected to let the situation rot
for a month while the discussion continued. Why? Certainly because it is
easier to complain after the fact than to be constructive before.

Now, if wm4 has constructive remarks about the framequeue design or
implementation, they can be posted and discussed. Otherwise, there is no
reason to change anything. The code is complex and not entirely elegant,
but all this is necessary.

Regards,
wm4 Dec. 22, 2016, 4:21 p.m. UTC | #17
On Thu, 22 Dec 2016 16:51:10 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> > How's that addressing his concerns?  
> 
> The answer I would have posted directly to his remarks would have been:
> 
> # > Is all this complexity really justified?
> # 
> # Yes, all this complexity is really justified, including the "leaky
> # abstraction", and you would know it if you deigned look at the 45k patch
> # that comes next and spare to the question one thousandth of the time I
> # spent on it. Furthermore, making it even more complex by having it
> # generic would be incredibly stupid. Unless you have precise and/or
> # constructive remarks, the file stays as is.

That comes a bit late. We're way beyond technical issues now.

It can be noted that this reply isn't without rudeness and some fine
arrogance and boasting ("45k patch"), including calling any alternative
(i.e. whatever I _would_ have suggested) as "stupid". I suppose
everything Nicolas George does is right and perfect? It's already
thought through thoroughly, why do we even need reviews?

You ignore the finer points of my original reply too. You're replying
to one sentence only. Maybe leaving away all the other things serves
to make me look worse here? Nah, surely you would never do this.

I think I don't even want to review your patches anymore because all of
this bullshit flying into my direction. Probably what you want, we both
can be happy.

> I consider extremely rude from wm4 to have asked such naive, or rather
> passive-aggressive ("Is all this complexity really justified?" actually
> means "your crap is too complex") questions without taking the minimum
> time to observe the use of the code in the next patch. Especially since
> we had our differences in the past.

"Is all this complexity really justified?" is far from passive-aggressive.
However, it seems you have taken this comment very personally and
interpreted it straight as insult.

Asking such questions (including asking whether simpler solutions are
possible) are the whole point of patch reviews. Patch reviews are about
finding faults in patches, or finding better solutions. If not we
could just commit straight to git.

If you interpret each of those comments as personal attacks on your
honor, you might not be cut for open source development, or team work
in general.

> Ignoring wm4's comments that I consider rude instead of escalating on
> the mailing list was specifically asked to me, and I did just that.
> 
> Now, maybe I was too curt in this mail:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2016-November/202768.html
> Maybe; I do often do not try to rein my temper. Productive answers were
> still possible. For example:

Or you could just have replied in a civilized manner.

But I'm sure your rage seems justified to you, so your reply was ok in
your book.

> # I did not intend to be rude, and I do not consider I was. Please
> # explain your problem.
> 
> Or even, to somebody neutral in private:
> 
> # Please ask this asshole to give a proper reply to my review.
> 
> That would have been the smart thing to do. Even just an insult would
> have been something. But instead, wm4 elected to let the situation rot
> for a month while the discussion continued. Why? Certainly because it is
> easier to complain after the fact than to be constructive before.

Oh, I did remind you. Don't try to distort the facts. According to the
ML archive, you didn't reply to my very first post. Then, over 3 weeks
later, you posted another iteration of your patch set, to which I
replied with a complaint that my comments were ignored. To that in
turn, you replied with some bullshit (not sure what else to call it).

Meanwhile I was patiently waiting for a reply responding to my
technical arguments. After all, a reply doesn't have to come
immediately. On the other hand, asking again would probably have been
replied with more bullshit. So I left it sitting.

In conclusion, you've committed the following wrongdoings:

- not initially replying
- replying with bullshit after I asked again 3 weeks later
- pushing your patch while not having replied to the review comments

So there are 3 things you did wrong. Do you deny this?

It appears you are being dishonest. This "discussion" here wasn't much
better.

Oh yeah, maybe I should have replied to your newest patch series. What
would have happened? Maybe some more rudeness from your side?

> Now, if wm4 has constructive remarks about the framequeue design or
> implementation, they can be posted and discussed. Otherwise, there is no
> reason to change anything. The code is complex and not entirely elegant,
> but all this is necessary.

Well at least you acknowledge these two points about the code.
Nicolas George Dec. 22, 2016, 4:44 p.m. UTC | #18
wm4:
> <snip>

I will not waste my and everybody's time answering these half-truths
directly.

I will, of course, continue to answer to people of good will.

Regards,
James Almer Dec. 22, 2016, 5:07 p.m. UTC | #19
On 12/22/2016 1:44 PM, Nicolas George wrote:
> wm4:
>> <snip>
> 
> I will not waste my and everybody's time answering these half-truths
> directly.
> 
> I will, of course, continue to answer to people of good will.

You still have time to address the arguments from wm4's review you
skipped in your previous reply. You only sort-of answered to the "Is
all this complexity really justified?" question.

"i found it rude" is not a justification to ignore a technical
review. What you do in that case is point out the rudeness then
proceed to address the review.
I'm sure you know that unaddressed reviews are considered blockers,
yet you just went and pushed this patch regardless of that against
all netiquette and respect for a project's workflow.
Nicolas George Dec. 22, 2016, 5:16 p.m. UTC | #20
Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> You still have time to address the arguments from wm4's review you
> skipped in your previous reply. You only sort-of answered to the "Is
> all this complexity really justified?" question.

All the rest was only sub-questions to the big one: details about the
complexity. My answer stands: yes, all this complexity is justified,
every bit of it.

If you, or anybody else, want explanations on a certain detail, you can
ask, and I will answer.

If wm4 wants explanations, "get used to disappointment".

Or, to state it a different way: I consider "yes, all this complexity is
justified" to be the definite answer to all of wm4's remarks in this
discussion. If anybody else thinks some of wm4's remarks need
addressing, make them your own. From my point of view, wm4 no longer
exists in this discussion.

Regards,
wm4 Dec. 22, 2016, 5:35 p.m. UTC | #21
On Thu, 22 Dec 2016 18:16:49 +0100
Nicolas George <george@nsup.org> wrote:

> Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> > You still have time to address the arguments from wm4's review you
> > skipped in your previous reply. You only sort-of answered to the "Is
> > all this complexity really justified?" question.  
> 
> All the rest was only sub-questions to the big one: details about the
> complexity. My answer stands: yes, all this complexity is justified,
> every bit of it.

Again, if all your patches were perfect, we wouldn't need to review
your patches. Do you want exemption from patch review?

> If you, or anybody else, want explanations on a certain detail, you can
> ask, and I will answer.
> 
> If wm4 wants explanations, "get used to disappointment".
> 
> Or, to state it a different way: I consider "yes, all this complexity is
> justified" to be the definite answer to all of wm4's remarks in this
> discussion. If anybody else thinks some of wm4's remarks need
> addressing, make them your own. From my point of view, wm4 no longer
> exists in this discussion.

Your going as far as denying my existence?
James Almer Dec. 22, 2016, 10:10 p.m. UTC | #22
On 12/22/2016 2:16 PM, Nicolas George wrote:
> Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
>> You still have time to address the arguments from wm4's review you
>> skipped in your previous reply. You only sort-of answered to the "Is
>> all this complexity really justified?" question.
> 
> All the rest was only sub-questions to the big one: details about the
> complexity. My answer stands: yes, all this complexity is justified,
> every bit of it.
> 
> If you, or anybody else, want explanations on a certain detail, you can
> ask, and I will answer.
> 
> If wm4 wants explanations, "get used to disappointment".
> 
> Or, to state it a different way: I consider "yes, all this complexity is
> justified" to be the definite answer to all of wm4's remarks in this
> discussion. If anybody else thinks some of wm4's remarks need
> addressing, make them your own. From my point of view, wm4 no longer
> exists in this discussion.

Then you're not addressing them, and this patch was pushed while a blocking
review remained unaddressed.
The proper course of action now would be to revert this commit. Unless of
course you decide to finally addressed his review. And I'm not saying you
have to unconditionally change your code, simply addressing his arguments
and explaining why the code is ok as is would be enough, assuming your reply
and arguments remain unchallenged.
Basically, the usual stuff when dealing with a review, something you have
done plenty of times before but seem determined not to this time.

You need to learn how to work in an collaborative project, and general
environments where you have to interact with people. You have no right to
ignore another dev's review and even go as far as state you'd consider his
arguments if they were made by someone else.
Your behavior is simply unacceptable and should be grounds for removing
your pushing rights at the very least.
Nicolas George Dec. 22, 2016, 10:39 p.m. UTC | #23
Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> Then you're not addressing them

I have: the complexity, in all its details, is necessary because of the
next patch. Including the "leaky abstraction", including the O(1)
implementation, including the lack of genericness.

This is the short and long technical answer of the only person who knows
how this code works. Sorry if that last sentence comes awfully
pretentious, but I am quite fed up with that discussion. Hopefully, once
all this is settled the code will be clear enough and I will no longer
be the only one knowing it.

And I have a perfect right of giving a half-line answer to a question
that, technically, was almost worthless, on top of being stated in a
rude way. If the objections raised has any technical merit, I would have
addressed them in my code, however rude the formulation.

Regards,
Michael Niedermayer Dec. 23, 2016, 12:12 a.m. UTC | #24
On Thu, Dec 22, 2016 at 07:10:39PM -0300, James Almer wrote:
> On 12/22/2016 2:16 PM, Nicolas George wrote:
> > Le duodi 2 nivôse, an CCXXV, James Almer a écrit :
> >> You still have time to address the arguments from wm4's review you
> >> skipped in your previous reply. You only sort-of answered to the "Is
> >> all this complexity really justified?" question.
> > 
> > All the rest was only sub-questions to the big one: details about the
> > complexity. My answer stands: yes, all this complexity is justified,
> > every bit of it.
> > 
> > If you, or anybody else, want explanations on a certain detail, you can
> > ask, and I will answer.
> > 
> > If wm4 wants explanations, "get used to disappointment".
> > 
> > Or, to state it a different way: I consider "yes, all this complexity is
> > justified" to be the definite answer to all of wm4's remarks in this
> > discussion. If anybody else thinks some of wm4's remarks need
> > addressing, make them your own. From my point of view, wm4 no longer
> > exists in this discussion.
> 
> Then you're not addressing them, and this patch was pushed while a blocking
> review remained unaddressed.
> The proper course of action now would be to revert this commit. Unless of
> course you decide to finally addressed his review. And I'm not saying you
> have to unconditionally change your code, simply addressing his arguments
> and explaining why the code is ok as is would be enough, assuming your reply
> and arguments remain unchallenged.
> Basically, the usual stuff when dealing with a review, something you have
> done plenty of times before but seem determined not to this time.
> 
> You need to learn how to work in an collaborative project, and general
> environments where you have to interact with people. You have no right to
> ignore another dev's review and even go as far as state you'd consider his
> arguments if they were made by someone else.
> Your behavior is simply unacceptable and should be grounds for removing
> your pushing rights at the very least.

I wish everyone would work together, its christmess

also 2 things here
1. Is there a technical problem in the code in git ?
2. Is there a non technical problem ?

both should be solved somehow! People should work together to solve
all issues!


3. Is there a disagreement on how to do something technical ?

If so i belive that the people activly working on the code in
question (called the maintainers) should make a decission


4. If people belive we need rules to ban developers, then they should
   start a discussion and vote about such rules when everyone is calm
   and rational (not now and never about individuals but a rule that
   everyone is equally subject to).


everyone, Love more, hate less, please!
diff mbox

Patch

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index cdddb1b..35bf11b 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -18,6 +18,7 @@  OBJS = allfilters.o                                                     \
        fifo.o                                                           \
        formats.o                                                        \
        framepool.o                                                      \
+       framequeue.o                                                     \
        graphdump.o                                                      \
        graphparser.o                                                    \
        opencl_allkernels.o                                              \
diff --git a/libavfilter/framequeue.c b/libavfilter/framequeue.c
new file mode 100644
index 0000000..debeab2
--- /dev/null
+++ b/libavfilter/framequeue.c
@@ -0,0 +1,123 @@ 
+/*
+ * Generic frame queue
+ * Copyright (c) 2016 Nicolas George
+ *
+ * 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 "libavutil/avassert.h"
+#include "framequeue.h"
+
+static inline FFFrameBucket *bucket(FFFrameQueue *fq, size_t idx)
+{
+    return &fq->queue[(fq->tail + idx) & (fq->allocated - 1)];
+}
+
+void ff_framequeue_global_init(FFFrameQueueGlobal *fqg)
+{
+}
+
+static void check_consistency(FFFrameQueue *fq)
+{
+#if ASSERT_LEVEL >= 2
+    uint64_t nb_samples = 0;
+    size_t i;
+
+    av_assert0(fq->queued == fq->total_frames_head - fq->total_frames_tail);
+    for (i = 0; i < fq->queued; i++)
+        nb_samples += bucket(fq, i)->frame->nb_samples;
+    av_assert0(nb_samples == fq->total_samples_head - fq->total_samples_tail);
+#endif
+}
+
+void ff_framequeue_init(FFFrameQueue *fq, FFFrameQueueGlobal *fqg)
+{
+    fq->queue = &fq->first_bucket;
+    fq->allocated = 1;
+}
+
+void ff_framequeue_free(FFFrameQueue *fq)
+{
+    while (fq->queued) {
+        AVFrame *frame = ff_framequeue_take(fq);
+        av_frame_free(&frame);
+    }
+    if (fq->queue != &fq->first_bucket)
+        av_freep(&fq->queue);
+}
+
+int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame)
+{
+    FFFrameBucket *b;
+
+    check_consistency(fq);
+    if (fq->queued == fq->allocated) {
+        if (fq->allocated == 1) {
+            size_t na = 8;
+            FFFrameBucket *nq = av_realloc_array(NULL, na, sizeof(*nq));
+            if (!nq)
+                return AVERROR(ENOMEM);
+            nq[0] = fq->queue[0];
+            fq->queue = nq;
+            fq->allocated = na;
+        } else {
+            size_t na = fq->allocated << 1;
+            FFFrameBucket *nq = av_realloc_array(fq->queue, na, sizeof(*nq));
+            if (!nq)
+                return AVERROR(ENOMEM);
+            if (fq->tail + fq->queued > fq->allocated)
+                memmove(nq + fq->allocated, nq,
+                        (fq->tail + fq->queued - fq->allocated) * sizeof(*nq));
+            fq->queue = nq;
+            fq->allocated = na;
+        }
+    }
+    b = bucket(fq, fq->queued);
+    b->frame = frame;
+    fq->queued++;
+    fq->total_frames_head++;
+    fq->total_samples_head += frame->nb_samples;
+    check_consistency(fq);
+    return 0;
+}
+
+AVFrame *ff_framequeue_take(FFFrameQueue *fq)
+{
+    FFFrameBucket *b;
+
+    check_consistency(fq);
+    av_assert1(fq->queued);
+    b = bucket(fq, 0);
+    fq->queued--;
+    fq->tail++;
+    fq->tail &= fq->allocated - 1;
+    fq->total_frames_tail++;
+    fq->total_samples_tail += b->frame->nb_samples;
+    check_consistency(fq);
+    return b->frame;
+}
+
+AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx)
+{
+    FFFrameBucket *b;
+
+    check_consistency(fq);
+    av_assert1(idx < fq->queued);
+    b = bucket(fq, idx);
+    check_consistency(fq);
+    return b->frame;
+}
diff --git a/libavfilter/framequeue.h b/libavfilter/framequeue.h
new file mode 100644
index 0000000..558ea22
--- /dev/null
+++ b/libavfilter/framequeue.h
@@ -0,0 +1,173 @@ 
+/*
+ * Generic frame queue
+ * Copyright (c) 2016 Nicolas George
+ *
+ * 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
+ */
+
+#ifndef AVFILTER_FRAMEQUEUE_H
+#define AVFILTER_FRAMEQUEUE_H
+
+/**
+ * FFFrameQueue: simple AVFrame queue API
+ *
+ * Note: this API is not thread-safe. Concurrent access to the same queue
+ * must be protected by a mutex or any synchronization mechanism.
+ */
+
+#include "libavutil/frame.h"
+
+typedef struct FFFrameBucket {
+    AVFrame *frame;
+} FFFrameBucket;
+
+/**
+ * Structure to hold global options and statistics for frame queues.
+ *
+ * This structure is intended to allow implementing global control of the
+ * frame queues, including memory consumption caps.
+ *
+ * It is currently empty.
+ */
+typedef struct FFFrameQueueGlobal {
+} FFFrameQueueGlobal;
+
+/**
+ * Queue of AVFrame pointers.
+ */
+typedef struct FFFrameQueue {
+
+    /**
+     * Array of allocated buckets, used as a circular buffer.
+     */
+    FFFrameBucket *queue;
+
+    /**
+     * Size of the array of buckets.
+     */
+    size_t allocated;
+
+    /**
+     * Tail of the queue.
+     * It is the index in the array of the next frame to take.
+     */
+    size_t tail;
+
+    /**
+     * Number of currently queued frames.
+     */
+    size_t queued;
+
+    /**
+     * Pre-allocated bucket for queues of size 1.
+     */
+    FFFrameBucket first_bucket;
+
+    /**
+     * Total number of frames entered in the queue.
+     */
+    uint64_t total_frames_head;
+
+    /**
+     * Total number of frames dequeued from the queue.
+     * queued = total_frames_head - total_frames_tail
+     */
+    uint64_t total_frames_tail;
+
+    /**
+     * Total number of samples entered in the queue.
+     */
+    uint64_t total_samples_head;
+
+    /**
+     * Total number of samples dequeued from the queue.
+     * queued_samples = total_samples_head - total_samples_tail
+     */
+    uint64_t total_samples_tail;
+
+} FFFrameQueue;
+
+/**
+ * Init a global structure.
+ */
+void ff_framequeue_global_init(FFFrameQueueGlobal *fqg);
+
+/**
+ * Init a frame queue and attach it to a global structure.
+ */
+void ff_framequeue_init(FFFrameQueue *fq, FFFrameQueueGlobal *fqg);
+
+/**
+ * Free the queue and all queued frames.
+ */
+void ff_framequeue_free(FFFrameQueue *fq);
+
+/**
+ * Add a frame.
+ * @return  >=0 or an AVERROR code.
+ */
+int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame);
+
+/**
+ * Take the first frame in the queue.
+ * Must not be used with empty queues.
+ */
+AVFrame *ff_framequeue_take(FFFrameQueue *fq);
+
+/**
+ * Access a frame in the queue, without removing it.
+ * The first frame is numbered 0; the designated frame must exist.
+ */
+AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx);
+
+/**
+ * Get the number of queued frames.
+ */
+static inline size_t ff_framequeue_queued_frames(const FFFrameQueue *fq)
+{
+    return fq->queued;
+}
+
+/**
+ * Get the number of queued samples.
+ */
+static inline uint64_t ff_framequeue_queued_samples(const FFFrameQueue *fq)
+{
+    return fq->total_samples_head - fq->total_samples_tail;
+}
+
+/**
+ * Update the statistics after a frame accessed using ff_framequeue_peek()
+ * was modified.
+ * Currently used only as a marker.
+ */
+static inline void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx)
+{
+}
+
+/**
+ * Update the sample count in the queue.
+ *
+ * This function must be used when the first frame was accessed using
+ * ff_framequeue_peek() and samples were removed from it.
+ */
+static inline void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t n)
+{
+    fq->total_samples_tail += n;
+}
+
+#endif /* AVFILTER_FRAMEQUEUE_H */