[Libav-user] Significant memory leak when calling avcodec_decode_video2

Matthew Einhorn moiein2000 at gmail.com
Thu Sep 22 21:59:34 CEST 2011


On Thu, Sep 22, 2011 at 10:09 AM, Noah Spitzer-Williams <
noah at spitzer-williams.com> wrote:

> 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);
>                }


Dunno if this will help, but av_free_packet(&packet); needs to be here
(outside the if (packet.stream_index == videoStream) clause). Because you
want to free even if it's the wrong stream.

Matt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20110922/79a8dc5c/attachment.html>


More information about the Libav-user mailing list