[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