[Libav-user] Significant memory leak when calling avcodec_decode_video2

Noah Spitzer-Williams noah at spitzer-williams.com
Thu Sep 22 16:09:13 CEST 2011


Hey guys,

I'm trying to do some basic video decoding and I'm noticing a huge
memory leak when I call avcodec_decode_video2. If I try scanning a 3gb
video file, my executable grows from ~10k of memory up to over 1gb by
the end of the scan. This is with ffmpeg 0.8.3 on Windows 7, running
in Visual Studio.

Any idea what I'm doing wrong? Thanks in advance!

Here's my code:


int Scan(const char *inputfile)
{

       AVFormatContext *pFormatCtx;
       unsigned int    i, videoStream;
       AVCodecContext  *pCodecCtx;
       AVCodec         *pCodec;
       AVFrame         *pFrame;
       AVFrame         *pFrameRGB;
       int             numBytes;
       uint8_t         *buffer;

       // Register all formats and codecs
       av_register_all();

       // Open video file
       if(av_open_input_file(&pFormatCtx, inputfile, NULL, 0, NULL)!=0)
       {
               return -1; // Couldn't open file
       }

       // Retrieve stream information
       if(av_find_stream_info(pFormatCtx)<0)
       {
               return -2; // Couldn't find stream information
       }

       // Dump information about file onto standard error
       dump_format(pFormatCtx, 0, inputfile, false);

       // Find the first video stream
       videoStream=-1;
       for(i=0; i<pFormatCtx->nb_streams; i++)
       {
               if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
               {
                       videoStream=i;
                       break;
               }
       }
       if(videoStream==-1)
       {
               return -3; // Didn't find a video stream
       }

       // Get a pointer to the codec context for the video stream
       pCodecCtx = pFormatCtx->streams[videoStream]->codec;

       // Find the decoder for the video stream
       pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
       if(pCodec==NULL)
       {
               return -4; // Codec not found
       }

       // Inform the codec that we can handle truncated bitstreams -- i.e.,
       // bitstreams where frame boundaries can fall in the middle of packets
       if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
               pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;

       // Open codec
       if(avcodec_open(pCodecCtx, pCodec)<0)
       {
               return -5; // Could not open codec
       }

       // Allocate video frame
       pFrame=avcodec_alloc_frame();

       // Allocate an AVFrame structure
       pFrameRGB=avcodec_alloc_frame();
       if(pFrameRGB==NULL)
       {
               return -6;
       }

       // Determine required buffer size and allocate buffer
       numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
       buffer=new uint8_t[numBytes];  // I've also tried buffer=(uint8_t
*)av_malloc(numBytes*sizeof(uint8_t));

       // Assign appropriate parts of buffer to image planes in pFrameRGB
       avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);

       AVPacket packet;
       int isFrameFinished;

       while (av_read_frame(pFormatCtx, &packet) >= 0)
       {

               if (isCancelled)
               {
                       break;
               }


               // Is this a packet from the video stream?
               if (packet.stream_index == videoStream)
               {
                       // Decode video frame


                       avcodec_decode_video2(pCodecCtx, pFrameRGB,
&isFrameFinished,
&packet);  // If I comment this out, there is no memory leak
                       av_free_packet(&packet);
               }

       }

       delete [] buffer;  // I've also tried av_free(buffer)
       av_free(pFrameRGB);

       // Free the YUV frame
       av_free(pFrame);

       // Close the codec
       avcodec_close(pCodecCtx);

       // Close the video file
       av_close_input_file(pFormatCtx);

}


More information about the Libav-user mailing list