[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