[FFmpeg-trac] #8445(avcodec:open): memory leak using h264_qsv to encode under certain resolutions
FFmpeg
trac at avcodec.org
Mon Jun 15 23:08:49 EEST 2020
#8445: memory leak using h264_qsv to encode under certain resolutions
-------------------------------------+-----------------------------------
Reporter: carlchen | Owner:
Type: defect | Status: open
Priority: normal | Component: avcodec
Version: unspecified | Resolution:
Keywords: qsv leak | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-----------------------------------
Changes (by lveilleux):
* status: new => open
Comment:
This leak is very real and reproducible when using the APIs
programmatically, although it may be difficult to detect using the one-
pass cli.
Using version 4.2.3 LGPL build from Zeranoe on Windows 64-bit. Below is a
snippet of code. If you wrap this into a function and call it a few times,
you will find there are references to the frame that are not released by
the codec and memory usage keeps increasing. This does not happen with
other codecs I tried (h264_nvenc, h264_amf and mpeg4), and it does not
happen with h264_qsv when resolution is 1920x1080 or 1280x720.
// Find encoder and allocate context
AVCodecContext *m_c =
avcodec_alloc_context3(avcodec_find_encoder_by_name("h264_qsv"));
// Setup basic parameters
m_c->width = 1280;
m_c->height = 1024;
m_c->gop_size = 200;
m_c->bit_rate = 1000000;
m_c->time_base.den = 90000;
m_c->time_base.num = 3000;
m_c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
m_c->pix_fmt = AV_PIX_FMT_NV12;
av_opt_set(m_c->priv_data, "preset", "faster", 0);
av_opt_set_int(m_c->priv_data, "forced_idr", 1, 0);
av_opt_set_int(m_c->priv_data, "look_ahead", 1, 0);
m_c->global_quality = 30;
// In case of failure to open, close codec and free memory
if (avcodec_open2(m_c, m_c->codec, NULL) < 0)
{
avcodec_close(m_c);
av_free(m_c);
m_c = NULL;
return;
}
AVFrame *m_frame = av_frame_alloc();
// Initialize the frame basic parameters and allocate image buffers
m_frame->format = m_c->pix_fmt;
m_frame->width = m_c->width;
m_frame->height = m_c->height;
AVBufferRef* m_buffer =
av_buffer_alloc(av_image_get_buffer_size(m_c->pix_fmt, m_c->width,
m_c->height, 1) + AV_INPUT_BUFFER_PADDING_SIZE);
m_frame->buf[0] = m_buffer;
av_image_fill_linesizes(m_frame->linesize, (AVPixelFormat)m_frame->format,
m_frame->width);
av_image_fill_pointers(m_frame->data, (AVPixelFormat)m_frame->format,
m_frame->height, m_buffer->data, m_frame->linesize);
for (int i=0; i<1000; i++)
{
m_frame->pts = i * m_c->time_base.num;
avcodec_send_frame(m_c, m_frame);
AVPacket pkt = { NULL };
avcodec_receive_packet(m_c, pkt);
}
avcodec_close(m_c);
av_free(m_c);
m_frame->buf[0] = NULL; // freed as m_buffer below
av_frame_unref(m_frame);
av_frame_free(&m_frame);
av_buffer_unref(&m_buffer);
--
Ticket URL: <https://trac.ffmpeg.org/ticket/8445#comment:4>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list