Hi,
I hereby present my Evil Plan(tm) on which I've been working recently,
which is intended to resolve the largest patchset contest once and for
all.
=====================
What is the evil plan
=====================
The central idea is introducing a unified reference counted buffer
struct (AVBuffer), which should then be used for all large buffers
throughout Libav.
In the current stage of the plan, it is used in AVPacket and AVFrame,
but can be conceivably useful in other places, e.g. in lavr or lavs if
it ever happens.
Current get_buffer()/reget_buffer()/release_buffer() API is replaced by
get_buffer2(), which sets up a reference counted AVFrame. Every video
decoder and aacdec need to be changed to this new API.
Furthermore, AVFrame is moved to lavu so it can be used in lavfi and
AVFilterBuffer is replaced by it.
============================
Motivation for the evil plan
============================
The changes are really huge, so why is it worth it?
1) With current lavc get_buffer() API, the decoded frame are valid until
the next decode call. If the caller needs them to live longer and wants
to avoid memcpy, he is forced to reimplement get_buffer() in his own
code, even though he does not need a custom get_buffer() at all, he just
needs reference counted frames. If the AVFrames exported by lavc are
already reference counted, this problem just goes away. Only people who
actually need real direct rendering will then have to reimplement
get_buffer().
A nice side effect is also simplifying the buffer management in most
decoders, removing about 1000 lines of boilerplate.
2) Using AVFrame in lavc and AVFilterTotallyNotAVFrame in lavfi for
basically the same struct is utterly and completely insane. But before
we can use AVFrame in lavfi, it needs to be a) refcounted b) moved to
lavu.
3) Some obscure and/or undocumented parts of the lavc API --
FF_BUFFER_*, CODEC_FLAG_INPUT_PRESERVED -- can now be removed.
Similarly the overcomplicated horror that is lavfi permissions goes down
the drain.
4) libavcodec/rawdec.c is a horrible horrible hack. It setups the output
AVFrame.data to point to the input AVPacket.data to avoid memory copy.
This depends on a unique for this decoder and completely undocumented
assumption that the packet is valid long enough. Refcounted AVPacket and
AVFrame allow us to do this properly.
5) Several other minor things, like avoiding copying packets with frame
threading, muxing the same packet with several muxers etc.
=======================
Status of the evil plan
=======================
All the main parts are there, most decoders and filters are converted.
A lot of polishing is still needed.
Open questions:
- thread safety of AVBuffer:
Do we want it and if so, how should we do
it. Basically what's needed is atomic ref/unref.
- cleaning up AVFrame:
AVFrame currently contains a lot of crap I'd rather not have in lavu,
mainly mpeg-specific tables. One other thing is owner, which is also
lavc-specific.
* one possible solution is to just remove the crap (which most
probably has vanishingly small usefulness) and require frame
threaded decoders to use a lavc specific frame struct which would
contain AVFrame+owner.
This is probably the simplest solution, but quite ugly IMO.
* another one is to add some kind of side data/metadata to AVFrame.
The question is how specifically should it look. I'm currently
thinking about making it basically identical to the AVPacket side
data. Better suggestions welcome.
The patchset contains the preparatory patches and a few example
decoder/filter conversions.
Comments on the general design/API are very much welcome.
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel