Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFmpeg memory leak

I have developed just a simple library modifing a library that I found on the internet.

What scares me, is that, when I play an avi, it plays and free the memory when the video ends, but when I play the video, it's like a memory leak! It grows to 138mb although the video has ended and the FreeAll method (A function that deletes the context, etc...) has been called.

Here is the code of the method that is causing the memory leak:

int VideoGL::NextVideoFrame(){
int frameDone = 0;
int result = 0;
double pts = 0;

if(!this->ended){

if (!_started) return 0;
AVPacket* packet;

// Get the number of milliseconds passed and see if we should display a new frame
int64_t msPassed = (1000 * (clock() - _baseTime)) / CLOCKS_PER_SEC;
if (msPassed >= _currentPts)
{
    // If this is not the current frame, copy it to the buffer
    if (_currentFramePts != _currentPts){
        _currentFramePts = _currentPts;
        memcpy(buffer_a,buffer, 3 * _codec_context_video->width * _codec_context_video->height);
        result = 1;
    }

    // Try to load a new frame from the video packet queue
    bool goodop=false;
    AVFrame *_n_frame = avcodec_alloc_frame();
    while (!frameDone && (packet = this->DEQUEUE(VIDEO)) != NULL)
    {
        if (packet == (AVPacket*)-1) return -1;

        goodop=true;

        _s_pts = packet->pts;
        avcodec_decode_video2(_codec_context_video, _n_frame, &frameDone, packet);
        av_free_packet(packet);

        if (packet->dts == AV_NOPTS_VALUE)
        {
            if (_n_frame->opaque && *(uint64_t*)_n_frame->opaque != AV_NOPTS_VALUE) pts = (double) *(uint64_t*)_n_frame->opaque;
            else pts = 0;
        }
        else pts = (double) packet->dts;

        pts *= av_q2d(_codec_context_video->time_base);

    }

    if (frameDone)
    {
        // if a frame was loaded scale it to the current texture frame buffer, but also set the pts so that it won't be copied to the texture until it's time
        sws_scale(sws_ctx,_n_frame->data, _n_frame->linesize, 0, _codec_context_video->height, _rgb_frame->data, _rgb_frame->linesize);


        double nts = 1.0/av_q2d(_codec_context_video->time_base);
        _currentPts = (uint64_t) (pts*nts);

    }

    avcodec_free_frame(&_n_frame);
    av_free(_n_frame);

    if(!goodop){
        ended=true;
    }
}
}

return result;
}

I'll be waiting for answers, thanks.

like image 240
Spamdark Avatar asked Oct 05 '22 00:10

Spamdark


2 Answers

I had a memory leak problem either. For me, the deallocation worked when I included the following commands:

class members:

AVPacket avpkt;
AVFrame *frame;
AVCodecContext *avctx;
AVCodec *codec;

constructor:

av_init_packet(&avpkt);
avcodec_open2(avctx, codec, NULL);
frame = avcodec_alloc_frame();

destructor:

av_free_packet(&avpkt);
avcodec_free_frame(&frame);
av_free(frame);
avcodec_close(avctx);
like image 118
Mauricio Avatar answered Oct 10 '22 02:10

Mauricio


i also had the same problem. According to the ffplay.c you should call

av_frame_unref(pFrame);
avcodec_get_frame_defaults(pFrame);

after every sw_scale call. this will free up all malloc during decode.

like image 33
Sarin Sukumar Avatar answered Oct 10 '22 01:10

Sarin Sukumar