On Tue, 19 Aug 2014 11:44:46 +0200, g kuczera <[email protected]> wrote: > 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"?
If your libav is new enough to contain av_frame_*, then you shouldn't allocate the buffers manually with avpicture stuff, but use av_frame_get_buffer(). Then av_frame_free() will automagically free both the data and the frame for you. -- Anton Khirnov _______________________________________________ libav-api mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-api
