[Libav-user] How to free an AVBuffer?

Wladislav Artsimovich ffmpeg at frost.kiwi
Thu Mar 2 06:06:02 EET 2023


Dear Yurii,

thx for elaborating. Indeed reassigning the pointer was a logical error, 
thx for pointing (hah) it out. I tried using `av_buffer_create()` 
originally, but couldn't find a way of using that function pointer 
callback `av_buffer_default_free()` in C#.
 From C# pMessageData cannot be freed, but is discarded automatically 
when the fixed{} block ends. I managed to free that MetaDatabuffer and 
the associated memory leak is gone! But not via `av_free()` (which 
didn't work, no error, no freeing), but via `av_buffer_unref()`. 
However, there still remains another memory leak caused by 
`av_frame_new_side_data_from_buf()`

How can I solve that? I tried following 
https://chromium.googlesource.com/chromium/third_party/ffmpeg/+/refs/heads/master/libavutil/frame.c#66 
and inserting `ffmpeg.av_buffer_unref(&sideData->buf); 
ffmpeg.av_dict_free(&sideData->metadata); ffmpeg.av_freep(sideData);` at 
different positions and `av_frame_remove_side_data()` at different 
positions, eg. before or after `ffmpeg.av_packet_free(&pPacket);`. The 
Encoder just gracefully stops without error, not processing any further 
frames.

What would be the proper procedure to free that AVFrameSideData?

Here is the full breakdown:

0 MB memory leaked per 100000 frames:
fixed (byte* pMessageData = message)
{
     //AVBufferRef* MetaDataBuffer = 
ffmpeg.av_buffer_alloc((ulong)message.Length);
     //System.Buffer.MemoryCopy(pMessageData, MetaDataBuffer->data, 
(ulong)message.Length, (ulong)message.Length);
     //AVFrameSideData* sideData = 
ffmpeg.av_frame_new_side_data_from_buf(&frame, 
AVFrameSideDataType.AV_FRAME_DATA_SEI_UNREGISTERED, MetaDataBuffer);
     ffmpeg.avcodec_send_frame(_pCodecContext, 
&frame).ThrowExceptionIfError();
     //ffmpeg.av_buffer_unref(&MetaDataBuffer);
}

62 MB leaked per 100000 frames:
fixed (byte* pMessageData = message)
{
     AVBufferRef* MetaDataBuffer = 
ffmpeg.av_buffer_alloc((ulong)message.Length);
     System.Buffer.MemoryCopy(pMessageData, MetaDataBuffer->data, 
(ulong)message.Length, (ulong)message.Length);
     //AVFrameSideData* sideData = 
ffmpeg.av_frame_new_side_data_from_buf(&frame, 
AVFrameSideDataType.AV_FRAME_DATA_SEI_UNREGISTERED, MetaDataBuffer);
     ffmpeg.avcodec_send_frame(_pCodecContext, 
&frame).ThrowExceptionIfError();
     //ffmpeg.av_buffer_unref(&MetaDataBuffer);
}

0 MB memory leaked per 100000 frames:
fixed (byte* pMessageData = message)
{
     AVBufferRef* MetaDataBuffer = 
ffmpeg.av_buffer_alloc((ulong)message.Length);
     System.Buffer.MemoryCopy(pMessageData, MetaDataBuffer->data, 
(ulong)message.Length, (ulong)message.Length);
     //AVFrameSideData* sideData = 
ffmpeg.av_frame_new_side_data_from_buf(&frame, 
AVFrameSideDataType.AV_FRAME_DATA_SEI_UNREGISTERED, MetaDataBuffer);
     ffmpeg.avcodec_send_frame(_pCodecContext, 
&frame).ThrowExceptionIfError();
     ffmpeg.av_buffer_unref(&MetaDataBuffer);
}

24.5 MB leaked per 100000 frames:
fixed (byte* pMessageData = message)
{
     AVBufferRef* MetaDataBuffer = 
ffmpeg.av_buffer_alloc((ulong)message.Length);
     System.Buffer.MemoryCopy(pMessageData, MetaDataBuffer->data, 
(ulong)message.Length, (ulong)message.Length);
     AVFrameSideData* sideData = 
ffmpeg.av_frame_new_side_data_from_buf(&frame, 
AVFrameSideDataType.AV_FRAME_DATA_SEI_UNREGISTERED, MetaDataBuffer);
     ffmpeg.avcodec_send_frame(_pCodecContext, 
&frame).ThrowExceptionIfError();
     ffmpeg.av_buffer_unref(&MetaDataBuffer);
}

Best regards,

Vlad

On 3/2/2023 09:35, Yurii Monakov wrote:
> av_buffer_alloc allocates buffer of given length (it’s data pointer is 
> not null). And after that you replace that pointer to with your own 
> pointer. So, the first allocation get definitely lost.
> You should copy pMessageData to MetaDataBuffer->data (and free 
> pMessageData manually) or use av_buffer_create function.
>
> Yurii
>
> Ср, 1 марта 2023 г. в 06:55, Wladislav Artsimovich <ffmpeg at frost.kiwi>:
>
>     Dear FFmpeg and libav users,
>
>     I am using FFmpeg.AutoGen in my C# Program to write out frames
>     encoded
>     as a h.264 stream and inject per-frame metadata with an
>     unregistered SEI
>     Message. It works great, but I have a memory leak, which I don't know
>     how to address. Source file attached.
>
>     Culprit is
>     ```C#
>     fixed (byte* pMessageData = message)
>     {
>          AVBufferRef* MetaDataBuffer =
>     ffmpeg.av_buffer_alloc((ulong)message.Length);
>          MetaDataBuffer->data = pMessageData;
>          AVFrameSideData* sideData =
>     ffmpeg.av_frame_new_side_data_from_buf(&frame,
>     AVFrameSideDataType.AV_FRAME_DATA_SEI_UNREGISTERED, MetaDataBuffer);
>     }
>     ```
>     I create an AVBuffer, as required by
>     av_frame_new_side_data_from_buf().
>     But I cannot free it, resulting in a memory leak. I went through
>     all of
>     https://ffmpeg.org/doxygen/trunk/group__lavu__buffer.html and
>     tried out
>     different av_freep() av_free(), av_buffer_unref() functions, changing
>     when to free etc. When I think I perform the free correctly, nothing
>     happens. No error, no freeing just nothing. Clearly I misunderstand
>     something.
>     To add insult to injury, the Visual Studio profiler cannot look
>     inside
>     the unmanaged memory of libav and reports, that the heap is fine
>     and not
>     growing, see attached screenshot.
>
>     How and when can I free this memory created allocated by
>     av_buffer_alloc() in the attached source file?
>
>     I asked the same question in the FFmpeg.AutoGen Questions Repo. Some
>     more context there:
>     https://github.com/Ruslan-B/FFmpeg.AutoGen.Questions/issues/36
>
>     Best regards,
>
>     Vlad
>     _______________________________________________
>     Libav-user mailing list
>     Libav-user at ffmpeg.org
>     https://ffmpeg.org/mailman/listinfo/libav-user
>
>     To unsubscribe, visit link above, or email
>     libav-user-request at ffmpeg.org with subject "unsubscribe".
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> libav-user-request at ffmpeg.org with subject "unsubscribe".


More information about the Libav-user mailing list