title: ffmpeg memory leak in the avcodec_open2 method
body: <p>I've developed an application which handles live video stream. The problem is that it should run as a service and over time I am noticing some memory increase. When I check the application with valgrind - it did not find any leak related issues.
  So I've check it with google profile tools. This is a result(substracting the one of the first dumps from the latest) after approximately 6 hour run:</p>
  
  <pre><code>   30.0  35.7%  35.7%     30.0  35.7% av_malloc
      28.9  34.4%  70.2%     28.9  34.4% av_reallocp
      24.5  29.2%  99.4%     24.5  29.2% x264_malloc
  </code></pre>
  
  <p>When I check the memory on the graph I see, that these allocations are related to avcodec_open2. The client code is:</p>
  
  <pre><code>`           g_EncoderMutex.lock();
              ffmpeg_encoder_start(OutFileName.c_str(), AV_CODEC_ID_H264, m_FPS, width, height);
              for (pts = 0; pts &lt; VideoImages.size(); pts++) {                
                  m_frame-&gt;pts = pts;
                  ffmpeg_encoder_encode_frame(VideoImages[pts].RGBimage[0]);
              }
              ffmpeg_encoder_finish();
              g_EncoderMutex.unlock()
  </code></pre>
  
  <p>The ffmpeg_encoder_start method is:</p>
  
  <pre><code> void VideoEncoder::ffmpeg_encoder_start(const char *filename, int codec_id, int fps, int width, int height)
          {
              int ret;
              m_FPS=fps;
              AVOutputFormat * fmt = av_guess_format(filename, NULL, NULL);
              m_oc = NULL;
              avformat_alloc_output_context2(&amp;m_oc, NULL, NULL, filename);
  
              m_stream = avformat_new_stream(m_oc, 0);
              AVCodec *codec=NULL;
  
              codec =  avcodec_find_encoder(codec_id);    
              if (!codec) 
              {
                  fprintf(stderr, "Codec not found\n");
                  return; //-1
              }
  
              m_c=m_stream-&gt;codec;
  
              avcodec_get_context_defaults3(m_c, codec);
  
              m_c-&gt;bit_rate = 400000;
              m_c-&gt;width = width;
              m_c-&gt;height = height;
              m_c-&gt;time_base.num = 1;
              m_c-&gt;time_base.den = m_FPS;
              m_c-&gt;gop_size = 10;
              m_c-&gt;max_b_frames = 1;
              m_c-&gt;pix_fmt = AV_PIX_FMT_YUV420P;
              if (codec_id == AV_CODEC_ID_H264)
                  av_opt_set(m_c-&gt;priv_data, "preset", "ultrafast", 0);
  
              if (m_oc-&gt;oformat-&gt;flags &amp; AVFMT_GLOBALHEADER) 
                  m_c-&gt;flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
              avcodec_open2( m_c, codec, NULL );
  
              m_stream-&gt;time_base=(AVRational){1, m_FPS};
  
              if (avio_open(&amp;m_oc-&gt;pb, filename, AVIO_FLAG_WRITE) &lt; 0)
              {
                  printf( "Could not open '%s'\n", filename);
                  exit(1);
              }            
  
              avformat_write_header(m_oc, NULL);
              m_frame = av_frame_alloc();
              if (!m_frame) {
                  printf( "Could not allocate video frame\n");
                  exit(1);
              }
              m_frame-&gt;format = m_c-&gt;pix_fmt;
              m_frame-&gt;width  = m_c-&gt;width;
              m_frame-&gt;height = m_c-&gt;height;
              ret = av_image_alloc(m_frame-&gt;data, m_frame-&gt;linesize, m_c-&gt;width, m_c-&gt;height, m_c-&gt;pix_fmt, 32);
              if (ret &lt; 0) {
                  printf("Could not allocate raw picture buffer\n");
                  exit(1);
              }
          }
  </code></pre>
  
  <p>The ffmpeg_encoder_encode_frame is:</p>
  
  <pre><code>void VideoEncoder::ffmpeg_encoder_encode_frame(uint8_t *rgb) 
  {
      int ret, got_output;
      ffmpeg_encoder_set_frame_yuv_from_rgb(rgb);
      av_init_packet(&amp;m_pkt);
      m_pkt.data = NULL;
      m_pkt.size = 0;
  
      ret = avcodec_encode_video2(m_c, &amp;m_pkt, m_frame, &amp;got_output);
      if (ret &lt; 0) {
          printf("Error encoding frame\n");
          exit(1);
      }
      if (got_output) 
      {
  
           av_packet_rescale_ts(&amp;m_pkt,
                          (AVRational){1, m_FPS}, m_stream-&gt;time_base);
          m_pkt.stream_index = m_stream-&gt;index;
          int ret = av_interleaved_write_frame(m_oc, &amp;m_pkt);
  
          av_packet_unref(&amp;m_pkt);
  
      }
  
  }
  </code></pre>
  
  <p>ffmpeg_encoder_finish code is:</p>
  
  <pre><code>void VideoEncoder::ffmpeg_encoder_finish(void) 
          {
              int got_output, ret;
  
              do {
  
                  ret = avcodec_encode_video2(m_c, &amp;m_pkt, NULL, &amp;got_output);
                  if (ret &lt; 0) {
                      printf( "Error encoding frame\n");
                      exit(1);
                  }
                  if (got_output) {
  
                      av_packet_rescale_ts(&amp;m_pkt,
                                  (AVRational){1, m_FPS}, m_stream-&gt;time_base);
                      m_pkt.stream_index = m_stream-&gt;index;
                      int ret = av_interleaved_write_frame(m_oc, &amp;m_pkt);
  
                      av_packet_unref(&amp;m_pkt);
                  }
              } while (got_output);
  
              av_write_trailer(m_oc);
              avio_closep(&amp;m_oc-&gt;pb);
  
              avformat_free_context(m_oc);
  
              av_freep(&amp;m_frame-&gt;data[0]);
              av_frame_free(&amp;m_frame);
  
              av_packet_unref(&amp;m_pkt);
              sws_freeContext(m_sws_context);
          }
  </code></pre>
  
  <p>This code runs multiple times in the loop.
  So my question is - what am I doing wrong? maybe ffmpeg is using some kind of internal buffering? If so, how to disable it? Because such an increase in memory usage is unacceptable at all.</p>