[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