简体   繁体   中英

Cleaning AVFrame properly

I'm creating AVFrame object using av_frame_alloc() function and clearing it using av_frame_free(&frame) which internally calls av_frame_unref(), but it's not cleaning the memory properly. Heap size of my app grows exponentially in run time.

Not working:

AVFrame* frame = av_frame_alloc();
av_frame_free(&frame);

Working:

AVFrame* frame = av_frame_alloc();
av_free(frame->data[0]);

As far as I know, av_frame_free() calls av_freep() which calls av_free() to free the dynamic memory. Memory gets cleaned, If I use av_free(frame->data[0]) directly instead of av_frame_free(&frame)

I developed a personal project about video screen sharing application using libav with H.264, in order to do 60 FPS video encoding.

To fix my memory leak issues, I allocate frame using av_frame_alloc , I make it writable every cycle with av_frame_make_writable and I free their memory using av_free or av_freep .

So, use one of these:

av_free(frame);
av_freep(frame);

I have met this problem when i convert cv Mat to av frame in my program, the demo like this

for ( int i = 0; i < 10000; i++ ) {
    cv::Mat img = cv::Mat::zeros(2160, 3840, CV_8UC3);

    //std::shared_ptr<cv::Mat> mat_ptr = std::make_shared<cv::Mat>( img.clone() );
    cv::Mat tmp = img.clone();
    AVFrame* frame = nullptr;
    frame = cv_mat_bgr_to_av_frame_yuv420p( tmp, i );

    if ( i % 10 == 0) {
        std::cout << "#####" << i << std::endl;
    }
    //av_frame_unref(frame);
    av_freep(&frame->data[0]);
}

The cv_mat_bgr_to_av_frame_yuv420p function is defined as:

AVFrame* cv_mat_bgr_to_av_frame_yuv420p( cv::Mat& mat , int frame_number ) {

AVFrame* frame = av_frame_alloc();
frame->format = AV_PIX_FMT_YUV420P;
frame->width = mat.cols;
frame->height = mat.rows;
frame->pts = (int64_t) ( frame_number *  TIME_BASE / FPS  );

cv::Mat mat_yuv;
cvtColor( mat, mat_yuv, cv::COLOR_BGR2YUV_I420 );

av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, 
                    static_cast<AVPixelFormat>(frame->format), 16);


// ergodic rows
int width = frame->width;
int height = frame->height;

for ( int j = 0; j < height; j++ ) {
    memcpy( frame->data[0] + j * frame->linesize[0], mat_yuv.data + j * width, width);
}

for ( int j = 0; j < height / 2; j++ ) {
    memcpy( frame->data[1] + j * frame->linesize[1], 
        mat_yuv.data + height * width + j * width / 2 , width / 2 );
}

for ( int j = 0; j < height / 2; j++ ) {
    memcpy(  frame->data[2] + j * frame->linesize[2], 
        mat_yuv.data + height * width * 5 / 4 + j * width / 2, width / 2 );
}

//av_frame_free(&frame);
return frame;

}

When i just use av_frame_free(&frame) to free the memory, i met the problem like you. However, when i use av_freep(&frame->data[0]), the problem is solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM