[libav-api] AVFrame memory management

g kuczera gkuczera at gmail.com
Tue Aug 19 11:44:46 CEST 2014


Hi Boys and Girls,
This time I was wandering about AVFrame's memory management. In my project,
I receive frames, which have to be merged (I got them from the Internet).

I can't operate on the original frame, so I create "copied frames", which
will be used to perform operations on. The copy operation is the sws_scale
function usage.

Here is the sample, in which I merge two cloned frames (the same ones) into
bigger one in my FramesMerger class.

void gotFrame(AVFrame* pFrame)
{
AVPixelFormat tFrameFormat = static_cast<AVPixelFormat>(pFrame->format);
AVFrame* tCopiedFrame1 = getPreparedFrame(tFrameFormat, pFrame->width,
pFrame->height);
AVFrame* tCopiedFrame2 = getPreparedFrame(tFrameFormat, pFrame->width,
pFrame->height);
// if (tCopiedFrame1 && tCopiedFrame2)
SwsContext* tScaleContext = sws_getContext(pFrame->width, pFrame->height,
tFrameFormat, pFrame->width, pFrame->height, tFrameFormat, SWS_BILINEAR,
NULL, NULL, NULL);

sws_scale(tScaleContext, (const uint8_t* const *)pFrame->data,
pFrame->linesize, 0, pFrame->height, tCopiedFrame1->data,
tCopiedFrame1->linesize);
sws_scale(tScaleContext, (const uint8_t* const *)pFrame->data,
pFrame->linesize, 0, pFrame->height, tCopiedFrame2->data,
tCopiedFrame2->linesize);

tCopiedFrame1->width = pFrame->width;
tCopiedFrame1->height = pFrame->height;
tCopiedFrame1->format = tFrameFormat ;

tCopiedFrame2->width = pFrame->width;
tCopiedFrame2->height = pFrame->height;
tCopiedFrame2->format = tFrameFormat ;

mFramesMerger.addFrame(tCopiedFrame1, 1);
mFramesMerger.addFrame(tCopiedFrame2, 2);

AVFrame* tMergedFrame = mFramesMerger.getFrame();
}

The getPreparedFrame function looks like this:

AVFrame* getPreparedFrame(AVPixelFormat pPixelFormat, int pWidth /*= 320*/,
int pHeight /*= 240*/)
{
AVFrame* tFrame = av_frame_alloc();

if (!tFrame)
{
return NULL;
}

int tBytesNeeded = avpicture_get_size(pPixelFormat, pWidth, pHeight);
uint8_t* tBuffer = (uint8_t*)av_malloc(tBytesNeeded * sizeof(uint8_t));
avpicture_fill((AVPicture*)tFrame, tBuffer, pPixelFormat, pWidth, pHeight);

return tFrame;
}

After all of that I release the added frames in this way:


avpicture_free((AVPicture*)mFrame);
av_frame_free(&mFrame);
mFrame = NULL;

But when I look at my memory usage (CTRL + SHIFT + ESC in Windows) I can
see that it's growing fast while the program is running. What do you think
about releasing the frame? I should also delete the frame data right
(tBuffer)? How to get access to this field, when I only have pointer to the
AVFrame? I realize that freeing AVFrame's memory should be proceeded on two
levels: one deletion of data and one of the frame structure - av_frame_free
deletes the second one, but how about the raw data?

Can you "give me a hand" or at least "point a direction"?


More information about the libav-api mailing list