[FFmpeg-devel] AVBufferRef from AVBuffer
Soft Works
softworkz at hotmail.com
Sat May 21 12:58:32 EEST 2022
Hi,
I have a question. I wonder whether it would be acceptable to add the following
function to buffer.c?
-----------------------------------------------------------------------
AVBufferRef *av_buffer_ref(AVBuffer *buf)
{
AVBufferRef *ref = av_mallocz(sizeof(*ref));
if (!ref)
return NULL;
ref->buffer = buf;
ref->data = buf->data;
ref->size = buf->size;
atomic_fetch_add_explicit(&buf->refcount, 1, memory_order_relaxed);
return ref;
}
-----------------------------------------------------------------------
Probably some will immediately say that this would be wrong and not the way
it's meant to be used, that AVBuffer needs to be treated as an opaque data
structure and similar.
After thinking about this for a while, I tend to think that it still fits
into the picture of the AVBuffer API. The only "risk" when dealing with
AVBuffer without an AVBufferRef is that the AVBuffer can get freed at any
time. But "any time" doesn't mean that there's no control over it; with
a custom "free" function, it is easy possible to know about the lifetime
of those buffers, and thus still allowing a safe implementation.
Why would I want that?
I need some kind of "weak reference" mechanism, and of course not something
totally new but something in the context of the AVBufferRef mechanism.
The use case in brief: there's a need to have bidirectional references
(some 1:1, some 1:n) between hardware device contexts and when using AVBufferRef
for all of them, it would lead to circular references and device contexts
wouldn't get released anymore.
All this should be done in a clean and clear way and avoid having references
hanging around where you might not now whether still valid or already
freed and invalid. To overcome that I started with a very simple concept:
- When a device context is created it is registered in a global array
(with thread-safe access) and gets a reg number (1, 2, 3, ...)
- When a device context is freed, it gets unregistered
(removed from the array)
- Now, a device context can reference other device contexts just
through that number (of course not knowing whether the corresponding
device is still "alive"
- But this can easily be queried from the array which can return an
AVBufferRef to that device on success.
But here comes the problem: how to store references to the device contexts
in that array?
- When creating new AVBufferRefs for the device contexts, none of them
would get freed anymore due to the additional reference
- Storing the first AVBufferRef which is available during device creation
doesn't work either, because that one could get freed while other
references still exist, and the reference would be invalid then
- Storing a plain pointer in the array doesn't work out either, because
in that case it wouldn't be possible to return an AVBufferRef with
reference counting.
None of that can work, but one way that does work would be to store
AVBuffer (not ..Ref) in that array. With the function above, it's
possible to create AVBufferRef from AVBuffer without needing another
AVBufferRef. As the registration will be unregistered when freed,
there's no concern about invalid AVBuffer references.
Please let me know what you think and whether that would be acceptable.
Of course, other ideas are welcome as well!
Thanks,
softworks
More information about the ffmpeg-devel
mailing list