Reputation: 1622
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)
Upvotes: 0
Views: 2301
Reputation: 51
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.
Upvotes: 0
Reputation: 731
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);
Upvotes: 0