FFmepg D3D11va解码渲染 内存泄漏排查
背景介绍
Rtsp播放器,采用FFmepg D3D11va硬解码 + D3D11渲染。
正常播放,内存使用正常,稳定在80M左右。
轮询,即定时关闭后重新打开,发现存在内存泄漏,半小时内存增长30M。
排查思路
因为内存泄漏只会出现在轮询的时候,所以初步定位泄漏发生在关闭视频,资源释放的时候。
因为D3D11渲染view这块收尾比较仓促,所以初步将目光对准了d3d11的渲染view。
D3D渲染对象
D3D成员变量几乎全采用ComPtr维护,该智能指针可以帮助我们来管理这些COM组件实现的接口实例,而无需过多担心内存的泄漏。该智能指针的大小和一般的指针大小是一致的,没有额外的内存空间占用。
这里不放心的话,可以使用ID3D11Debug来协助检查内存泄漏。
具体用法见检查D3D对象是否释放

经检测,有两个对象没有释放,遂手动释放。
重新测试,发现居然还有内存泄漏的情况,顿感棘手。
因为现在所有的解码渲染流程都和软解一样,但是软解不存在内存泄漏。
花费一个下午。通过控制变量,再次确认排除了渲染,解码流程存在泄漏的可能。
第二天,终于想起一个点,硬解采用了内存探测的方式打开输入流,会不会是探测这部分数据未释放导致泄漏?
FFmpeg内存探测
观察这段代码,明显有两处申请内存的地方。
我之前一直以为这里的空间通过
avformat_close_input(&m_pFmtCtx)这一行代码就可以回收,现在心里却有些拿不准。
于是baidu了一下,发现这里确实需要手动释放。于是修改如下:
// An highlighted block
if (m_pFmtCtx) {
if (m_pFmtCtx->pb) {
av_freep(&(m_pFmtCtx->pb->buffer));
avio_context_free(&m_pFmtCtx->pb);
}
avformat_close_input(&m_pFmtCtx);
}
通过验证,内存泄漏修复,大功告成!