FFmpeg视频播放的内存管理

本文探讨了在使用FFmpeg 3.4版本进行视频播放时遇到的内存管理问题,重点关注AVFrame和AVPacket的内存管理策略。作者指出直接赋值frame会导致数据丢失,建议使用新frame接收解码数据或在传递时复制。文章揭示了解码过程中内存未释放的原因,是由于FFmpeg的缓冲池机制,该机制通过引用计数管理内存,避免频繁分配和释放。作者通过源码分析,找出了解决内存泄漏的关键步骤,强调了解码结束时正确释放资源的重要性。
摘要由CSDN通过智能技术生成

在写这个播放器的时候,遇到了一些内存管理的问题,虽然棘手但是也让我对此有了比较完善的理解,而且很多相关资料并没有跟随FFmpeg的更新,比如缓冲池AVBufferPool的使用。

使用ffmpeg版本是3.4

AVFrame和AVPacket的内存管理策略
对AVFrame:

  • av_frame_alloc只是给AVFrame分配了内存,它内部的buf还是空的,就相当于造了一个箱子,但箱子里是空的。
  • av_frame_ref对src的buf增加一个引用,即使用同一个数据,只是这个数据引用计数+1.av_frame_unref把自身对buf的引用释放掉,数据的引用计数-1。
  • av_frame_free内部还是调用了unref,只是把传入的frame也置空。

发现还缺了一个buffer初始化的方法,初始化就在解码函数avcodec_send_packetavcodec_receive_frame内部。

然后对于解码有个坑,对avcodec_receive_frame函数:
Note that the function will always call av_frame_unref(frame) before doing anything else.

如果你使用同一个frame,每次去接收解码后的数据,那么每次传进去就会把前面的数据释放掉,导致就只有一个frame是有用的。

如果你觉得frame的alloc花费很大,想节省资源,然后又没注意到这个注释的话,很可能就会这么做。
对此有两种方案:

  1. 继续只使用一个frame来接收,但是在传递给下一步(渲染、播放等)的时候,下一步的模块使用一个新的frame和av_frame_ref来接收,而不是直接的赋值。
  2. 每次解码前构建一个新的AVFrame,把它传给avcodec_receive_frame,这样每次都是新的frame,互不干扰。但是在整个流程结束时,要释放这个frame.

方便来说,是第二种方案好;但从模块化角度说,是第一种的更好&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值