FFmpeg渲染QImage内存泄漏致崩溃,求正确内存释放方案
问题分析与解决方案
你的代码存在多处内存泄漏点,逐一修正如下:
1. SwsContext 重复创建未释放
你当前每次处理帧都调用sws_getContext创建格式转换上下文,但未对应释放。若转换的分辨率、像素格式固定,只需初始化一次(放在处理循环外);若必须每次创建,用完后必须调用sws_freeContext释放上下文内存。
2. AVFrame 内存释放不完整
avpicture_alloc为frameRGB分配了像素数据缓冲区,直接调用av_frame_free仅会释放AVFrame结构体本身,不会释放avpicture_alloc分配的像素内存。需先调用avpicture_free释放像素数据,再释放AVFrame结构体。
修正后的代码示例
初始化(仅执行一次)
// 固定参数下,转换上下文只需初始化一次,放在帧处理循环外 SwsContext* img_convert_ctx = sws_getContext(codecCtx->width, codecCtx->height, codecCtx->pix_fmt, codecCtx->width, codecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
帧处理循环内
AVFrame* frameRGB = av_frame_alloc(); if (!frameRGB) { // 处理分配失败逻辑 return; } // 分配像素内存 int ret = avpicture_alloc((AVPicture*)frameRGB, AV_PIX_FMT_RGB24, codecCtx->width, codecCtx->height); if (ret < 0) { av_frame_free(&frameRGB); // 处理分配失败逻辑 return; } // 格式转换 sws_scale(img_convert_ctx, frame->data, frame->linesize, 0, codecCtx->height, frameRGB->data, frameRGB->linesize); // 注意:QImage直接使用外部内存时不会接管所有权,若需在frameRGB释放后继续使用,必须调用copy()创建副本 QImage image(frameRGB->data[0], codecCtx->width, codecCtx->height, frameRGB->linesize[0], QImage::Format_RGB888); QImage imageCopy = image.copy(); // 按顺序释放内存:先释放像素数据,再释放AVFrame结构体 avpicture_free((AVPicture*)frameRGB); av_frame_free(&frameRGB);
程序退出或不再需要转换上下文时
sws_freeContext(img_convert_ctx);
额外注意事项
- 若分辨率或像素格式会动态变化,每次创建新的SwsContext前,必须先调用
sws_freeContext(img_convert_ctx)释放旧上下文。 - 避免直接使用绑定了
frameRGB内存的QImage,否则frameRGB释放后QImage会出现野指针问题,务必使用copy()生成独立副本。
内容的提问来源于stack exchange,提问作者Integer75
相关产品推荐
相关产品推荐

