<div class="gmail_quote">On Thu, Sep 22, 2011 at 10:09 AM, Noah Spitzer-Williams <span dir="ltr"><<a href="mailto:noah@spitzer-williams.com">noah@spitzer-williams.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hey guys,<br>
<br>
I'm trying to do some basic video decoding and I'm noticing a huge<br>
memory leak when I call avcodec_decode_video2. If I try scanning a 3gb<br>
video file, my executable grows from ~10k of memory up to over 1gb by<br>
the end of the scan. This is with ffmpeg 0.8.3 on Windows 7, running<br>
in Visual Studio.<br>
<br>
Any idea what I'm doing wrong? Thanks in advance!<br>
<br>
Here's my code:<br>
<br>
<br>
int Scan(const char *inputfile)<br>
{<br>
<br>
AVFormatContext *pFormatCtx;<br>
unsigned int i, videoStream;<br>
AVCodecContext *pCodecCtx;<br>
AVCodec *pCodec;<br>
AVFrame *pFrame;<br>
AVFrame *pFrameRGB;<br>
int numBytes;<br>
uint8_t *buffer;<br>
<br>
// Register all formats and codecs<br>
av_register_all();<br>
<br>
// Open video file<br>
if(av_open_input_file(&pFormatCtx, inputfile, NULL, 0, NULL)!=0)<br>
{<br>
return -1; // Couldn't open file<br>
}<br>
<br>
// Retrieve stream information<br>
if(av_find_stream_info(pFormatCtx)<0)<br>
{<br>
return -2; // Couldn't find stream information<br>
}<br>
<br>
// Dump information about file onto standard error<br>
dump_format(pFormatCtx, 0, inputfile, false);<br>
<br>
// Find the first video stream<br>
videoStream=-1;<br>
for(i=0; i<pFormatCtx->nb_streams; i++)<br>
{<br>
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)<br>
{<br>
videoStream=i;<br>
break;<br>
}<br>
}<br>
if(videoStream==-1)<br>
{<br>
return -3; // Didn't find a video stream<br>
}<br>
<br>
// Get a pointer to the codec context for the video stream<br>
pCodecCtx = pFormatCtx->streams[videoStream]->codec;<br>
<br>
// Find the decoder for the video stream<br>
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);<br>
if(pCodec==NULL)<br>
{<br>
return -4; // Codec not found<br>
}<br>
<br>
// Inform the codec that we can handle truncated bitstreams -- i.e.,<br>
// bitstreams where frame boundaries can fall in the middle of packets<br>
if(pCodec->capabilities & CODEC_CAP_TRUNCATED)<br>
pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;<br>
<br>
// Open codec<br>
if(avcodec_open(pCodecCtx, pCodec)<0)<br>
{<br>
return -5; // Could not open codec<br>
}<br>
<br>
// Allocate video frame<br>
pFrame=avcodec_alloc_frame();<br>
<br>
// Allocate an AVFrame structure<br>
pFrameRGB=avcodec_alloc_frame();<br>
if(pFrameRGB==NULL)<br>
{<br>
return -6;<br>
}<br>
<br>
// Determine required buffer size and allocate buffer<br>
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,<br>
pCodecCtx->height);<br>
buffer=new uint8_t[numBytes]; // I've also tried buffer=(uint8_t<br>
*)av_malloc(numBytes*sizeof(uint8_t));<br>
<br>
// Assign appropriate parts of buffer to image planes in pFrameRGB<br>
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,<br>
pCodecCtx->width, pCodecCtx->height);<br>
<br>
AVPacket packet;<br>
int isFrameFinished;<br>
<br>
while (av_read_frame(pFormatCtx, &packet) >= 0)<br>
{<br>
<br>
if (isCancelled)<br>
{<br>
break;<br>
}<br>
<br>
<br>
// Is this a packet from the video stream?<br>
if (packet.stream_index == videoStream)<br>
{<br>
// Decode video frame<br>
<br>
<br>
avcodec_decode_video2(pCodecCtx, pFrameRGB,<br>
&isFrameFinished,<br>
&packet); // If I comment this out, there is no memory leak<br>
av_free_packet(&packet);<br>
}</blockquote><div> </div><div>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.<br>
</div></div><br>Matt<br>