[FFmpeg-devel] [PATCH] lavu/buffer: add release function

Lukasz Marek lukasz.m.luki at gmail.com
Tue Feb 25 01:46:21 CET 2014


On 25.02.2014 01:19, Michael Niedermayer wrote:
> On Tue, Feb 25, 2014 at 12:58:12AM +0100, Lukasz Marek wrote:
>> On 24.02.2014 02:18, Michael Niedermayer wrote:
>>> On Sun, Feb 23, 2014 at 11:19:23PM +0100, Lukasz Marek wrote:
>>>> new function allows to unref buffer and obtain its data.
>>>>
>>>> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
>>>> ---
>>>>   libavutil/buffer.c | 26 ++++++++++++++++++++++++++
>>>>   libavutil/buffer.h | 12 ++++++++++++
>>>>   2 files changed, 38 insertions(+)
>>>>
>>>> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
>>>> index e9bf54b..a68b0be 100644
>>>> --- a/libavutil/buffer.c
>>>> +++ b/libavutil/buffer.c
>>>> @@ -117,6 +117,32 @@ void av_buffer_unref(AVBufferRef **buf)
>>>>       }
>>>>   }
>>>>
>>>> +int av_buffer_release(AVBufferRef **buf, uint8_t **data)
>>>> +{
>>>> +    AVBuffer *b;
>>>> +
>>>> +    if (!buf || !*buf) {
>>>> +        if (data)
>>>> +            *data = NULL;
>>>> +        return 0;
>>>> +    }
>>>> +    b = (*buf)->buffer;
>>>> +    av_freep(buf);
>>>> +
>>>> +    if (!avpriv_atomic_int_add_and_fetch(&b->refcount, -1)) {
>>>> +        if (data)
>>>> +            *data = b->data;
>>>> +        else
>>>> +            b->free(b->opaque, b->data);
>>>> +        av_freep(&b);
>>>
>>>> +    } else if (data) {
>>>> +        *data = av_memdup(b->data, b->size);
>>>> +        if (!*data)
>>>> +            return AVERROR(ENOMEM);
>>>
>>> this is not safe
>>>
>>> you decreased the ref count and afterwards copy
>>> but between the 2 the memory could have been deallocated
>>
>> Yep,
>> I attached updated patach - hopely better, and one more which is not
>> relevant to the first one, but kinda trivial, so don't want to spam
>> too much.
>>
>> I assumed you talked about unref from other thread while memory is
>> being copied. It is true it is not safe, but I think there are
>> already rece condition in buffer.c.
>>
>> For example there is AVBufferRef pointer shared across 2 threads
>> Thread A has reference and calls unref
>
>
>> Thread B has no reference and calls ref
>
> Thread B cannot call ref if it has no reference, thats violating
> the API

If so then OK, just haven't found it in docs (I did not read all tho)


>>   buffer.c |    2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>> 802258605a7bfb649be51b57b10830b2c7b35bda  0002-lavu-buffer-do-not-touch-refcount-directly.patch
>>  From 220010aa7b2971f33346fdb0a78bd95b5f91be25 Mon Sep 17 00:00:00 2001
>> From: Lukasz Marek <lukasz.m.luki at gmail.com>
>> Date: Tue, 25 Feb 2014 00:38:20 +0100
>> Subject: [PATCH 2/2] lavu/buffer: do not touch refcount directly
>>
>> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
>> ---
>>   libavutil/buffer.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
>> index 76582f2..2a41150 100644
>> --- a/libavutil/buffer.c
>> +++ b/libavutil/buffer.c
>> @@ -161,7 +161,7 @@ void *av_buffer_get_opaque(const AVBufferRef *buf)
>>
>>   int av_buffer_get_ref_count(const AVBufferRef *buf)
>>   {
>> -    return buf->buffer->refcount;
>> +    return avpriv_atomic_int_get(&buf->buffer->refcount);
>
> do you know of a case where this needs to be atomic ?

OK, but why it is used in other places? If no use case in here than 
what's the use case in av_buffer_is_writable for example? If you are 
sure it is not required then feel free to ignore this patch. Probably 
OK, I haven't investigate it before, just guessed from other uses of 
this function.


-- 
Best Regards,
Lukasz Marek

Royale with Cheese.


More information about the ffmpeg-devel mailing list