[Libav-user] Possible memory leak in avformat_find_stream_info, how to deal with it?

Wodzu brucedickinson at wp.pl
Tue Feb 26 11:57:34 EET 2019



I am trying to transmux (remux?) from raw h264 to mp4. My input is in a
stream, output goes to a file. Everything works, but I've noticed that if I
repeat my function multiple times, allocation of memory grows and it is not
entirely released back.

I was able to find first function which is causing me this problems and it
is avformat_find_stream_info. I looked for it in Internet and I saw that
there is a one expected leak of size 24 bytes, but in my tests it goes way
over it. 


Here is an example code, stripped to reproduce the leak:


extern "C" {

#include <libavutil/timestamp.h>

#include <libavformat/avformat.h>



#include <iostream>

#include <fstream>


int ReadFunction(void* opaque, uint8_t* buf, int buf_size) noexcept


  auto& input_stream = *reinterpret_cast<std::istream*>(opaque);

  input_stream.read(reinterpret_cast<char*>(buf), buf_size);

  if (input_stream.good())

       return (int)input_stream.gcount();



       if (input_stream.eof())

         return AVERROR_EOF;


         return AVERROR_EXTERNAL;




int64_t SeekFunction(void* opaque, int64_t offset, int whence) noexcept


  auto& me = *reinterpret_cast<std::istream*>(opaque);

  switch (whence)



       return AVERROR_EXTERNAL;

  case SEEK_SET:

       me.seekg(offset, std::ios_base::beg);

       return me.good() ? (int64_t)me.tellg() : AVERROR_EXTERNAL;

  case SEEK_CUR:

       me.seekg(offset, std::ios_base::cur);

       return me.good() ? (int64_t)me.tellg() : AVERROR_EXTERNAL;

  case SEEK_END:

       me.seekg(offset, std::ios_base::end);

       return me.good() ? (int64_t)me.tellg() : AVERROR_EXTERNAL;


       return AVERROR_EXTERNAL;




void Transmux(std::istream& input, const std::string& output_file_path)


  AVFormatContext* input_context = avformat_alloc_context();


  if (!input_context)

       std::cout << "Could not allocate input context.\n";

  input_context->flags = AVFMT_FLAG_CUSTOM_IO;


  unsigned char* buffer = reinterpret_cast<unsigned char*>(av_malloc(8192));

  if (!buffer)

       std::cout << "Could not allocate buffer.\n";


  AVIOContext* io_context = avio_alloc_context(buffer, 8192, 0,
reinterpret_cast<void*>(static_cast<std::istream*>(&input)), &ReadFunction,
nullptr, &SeekFunction);

  if (!io_context)

       std::cout << "Could not allocate io context.\n";


  input_context->pb = io_context;


  if (avformat_open_input(&input_context, "", NULL, NULL) < 0)

       std::cout << "Could not open input.\n ";


  if (avformat_find_stream_info(input_context, NULL) < 0) // Comment out
this and there is no leak.

       std::cout << "Could not find stream info.\n";








int main()


  std::ifstream stream("E:\\Encoder\\libx264_movie.dat", std::ios::binary);

  if (stream.fail())

       std::cout << "Could not open file.\n ";


  for (int Index = 0; Index < 1000; Index++) // More iterations means more
memory allocated but it does not grow linearly. 



       stream.seekg(0, std::ios_base::beg);

       Transmux(stream, "E:\\Encoder\\output.mp4");


  std::cout << "Finished.\n";


  int n;

  std::cin >> n;




If I comment out avformat_find_stream_info() the amount of allocated memory
at the end of program is always the same regardless of number of times I
repeat Transmux() function.

If I leave avformat_find_stream_info() then not all memory is released back.
The more times I repeat Transmux() the more memory is left allocated. I do
not use Linux and Valgrind, I am not

Experienced enough to do so. I am developing under Windows with libraries
distributed with ffmpeg 4.0.0. I know that my testing for leak is very crude
but it definitely show some pattern.


Take a look:


Iterations Memory (KB)

1 2848

10 3708

100 4040

200 4040

500 4596

1000 5588


Am I not freeing something? 

One way of dealing with it (as a workaround) would be to reuse input_context
and io_context without allocating/freeing it but I don't know if this is


Thanks for any help.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20190226/47722484/attachment.html>

More information about the Libav-user mailing list