千家信息网

播放器技术分享(2):缓冲区管理

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,搞音视频开发好些年,分享过许多博客文章,比如:前几年发布的《FFmpeg Tips》系列,《Android 音频开发》系列,《直播疑难杂症排查》系列等等。最近想把多年来开发和优化播放器的经验也分享出来
千家信息网最后更新 2026年11月03日播放器技术分享(2):缓冲区管理

搞音视频开发好些年,分享过许多博客文章,比如:前几年发布的《FFmpeg Tips》系列,《Android 音频开发》系列,《直播疑难杂症排查》系列等等。最近想把多年来开发和优化播放器的经验也分享出来,同时也考虑把自己业余时间开发的基于 ffmpeg 的播放器内核开源出来,希望能帮助到音视频领域的初学者。第一期文章要推出的内容主要涉及到播放器比较核心的几个技术点,大概的目录如下:

1. 播放器技术分享(1):架构设计

2. 播放器技术分享(2):缓冲区管理

3. 播放器技术分享(3):音画同步

4. 播放器技术分享(4):首开时间

5. 播放器技术分享(5):延时优化

本篇是系列文章的第二篇,主要聊一聊播放器的缓冲区管理。

1 概述

在上一篇文章中,我们有提到利用缓冲区把单线程模型的数据流改造为多线程模型,从而可以有效抵抗网络和解码的抖动,防止频繁卡顿,同时也能充分利用多核 CPU 的计算能力,如下图所示:

播放器的读线程,将 IO 和 Parser 模块输出的"未解码"的音视频数据包放到"帧缓冲区"队列中,将解码后的数据,存放到"显示缓冲区"队列中。

2 缓冲区的作用

我们深挖一下,这个 "帧缓冲区" 和 "显示缓冲区" 究竟起到了一个什么作用 ?

2.1 帧缓冲区

帧缓冲区,作为"读线程"和"解码线程"之间的缓冲池,它主要起到了三个作用:

  1. 抵抗网络抖动

  2. 抵抗解码抖动

  3. 避免被动丢帧导致花屏

假设没有"帧缓冲区",即:IO -> Parser -> Decoder 整个流程是串行的,那么会有如下潜在问题:

  1. IO 网络抖动的时候(比如:短暂拥塞,无法读到数据),那么整个数据链条都会被卡住,Decoder 只能干等着 IO 恢复

  2. Decoder 同样会出现"抖动",因为解码某些复杂的视频帧,会耗时比较久,如果 Decoder 卡住,同样 IO 模块也只能干等着

  3. 因为整个流程是串行的,每一帧都必须 IO -> Parser -> Decoder 走完才会读取和处理下一帧,那么,当网络抖动的时候,会出现服务端的 TCP 协议栈缓存了较多的数据,在网络恢复的时候,下发到客户端的时候,因为接收不及时,导致 TCP 发送队列爆满而产生被动丢帧,从而使得后续因为数据不完整导致解码花屏

2.2 显示缓冲区

显示缓冲区,作为"解码线程"和"显示线程"之间的缓冲池,它主要起到了三个作用:

  1. 实现 "音画同步" 的必要条件

  2. 抵抗渲染抖动

假设没有"显示缓冲区",即:Decoder -> Renderer 整个流程是串行的,那么会有如下潜在问题:

  1. 无论是视频帧还是音频数据,都是解码完了就立马送入了渲染模块,无法添加音画同步的逻辑处理

  2. 如果渲染模块出现"抖动",会直接阻塞×××,无法异步去解码帧缓冲区中的数据,降低了效率

3 "主动缓冲" 与 "被动缓冲"

了解了缓冲区的作用,我们再看看缓冲区的数据是怎么被填充的 ?

缓冲区的数据填充,主要分为 2 种情况,第一种叫 "主动缓冲",另一种叫做 "被动缓冲"

主动缓冲:是指播放器主动暂停缓冲区的数据消费,等待数据生产者逐渐填充数据,直到达到某种条件再恢复

被动缓冲:是指数据的消费速度赶不上生产速度,从而被动滞留了数据在缓冲区中

主动缓冲,多用于点播场景,为了降低频繁卡顿,在开始播放视频之前,会主动 buffering 一段时间(比如:10s)的数据,再开始播放。当缓冲区内的数据因为网络抖动等原因消耗完了,会再次启动 buffering,如此循环。

如图所示,假设播放器缓冲区内的数据低于 Low 这个水位点后,会主动暂停播放,启动 buffering 过程直到缓冲区中的数据达到 M 水位值。

被动缓冲,多出现在直播场景,可能有 2 种原因:

  1. 手机等设备的解码性能不足,比如软解 1080P 的高清视频,导致视频的解码和渲染的速度赶不上视频的读取速度,导致数据堆积在"帧缓冲区"

  2. 网络的频繁抖动,导致客户端无法及时拿到数据进行解码渲染,当网络恢复后,数据会迅速下发下来,但播放器已没有办法再快速消费掉(因为播放的速率是固定的,除非添加追帧的逻辑,后续文章会详细介绍)

4 缓冲区的大小怎么定 ?

理解了缓冲区的作用,那这两个缓冲区的大小如何制定呢 ?首先,我们需要知道这两个缓冲区大小究竟影响或者决定了什么 ?

  1. 缓冲区越大 -> 抗抖动能力越强

  2. 缓冲区越大 -> 内存占用越高

  3. 缓冲区越大 -> 播放延时越大

由此可见,缓冲区也不是越大越好,需要根据实际的使用场景来决定。

"显示缓冲区" 其实是 解码线程 和 渲染线程 之间的桥梁,由于解码和渲染的抖动并不频繁,所以并不需要特别大的缓冲区,最低 3 帧左右即可,一帧在生产,一帧在消费,还有一帧在缓冲区中待命。

而 "帧缓冲区" 是用来抵抗网络抖动的,网络抖动往往是比较频繁的,抖动的时间也有时会比较久一些,所以 "帧缓冲区" 相对要设置得大一点,但以不过于影响内存和播放延时为前提。

对于直播场景,为了防止 "被动丢帧",往往 "帧缓冲区" 默认是设置为 "无限大" 的,当检测到缓冲区达到一定阈值后,启动一些诸如主动丢帧或者倍数播放的方式,来快速消耗掉缓冲的内容,从而降低内存和延时。

5 缓冲区何时会主动清空 ?

有如下几种场景,播放器会主动清空缓冲区内的数据:

  1. 播放器重置

  2. 播放进度条被拖动

  3. 消除累积延时

  4. 系统内存告警

6 IJKPlayer 的缓冲区管理

ijkplayer 使用非常广泛,这里以它为例看看播放器缓冲区的真实案例是怎么样的 ?

  1. 播放器打开后,缓冲 100ms,再开始播放

  2. 如果遇到了卡顿(缓冲区为空),则暂停播放,缓冲到 1000ms,再开始播放

3. 如果再次遇到卡顿,则缓冲到 2000ms 再播,依次类推,直到 5000ms

可以看出,它的缓冲区的最大阈值是逐步递增上去的,这是一个非常棒的用户体验优化,因为如果用户网络不是那么差的话,不用第一次缓冲就等 5s 了

7 总结

播放器的缓冲区管理,就分享到这里了,如有疑问的小伙伴欢迎来信 lujun.hust@gmail.com 交流。另外,也欢迎大家关注我的新浪微博 @卢_俊 或者 微信公众号 @Jhuster 获取最新的文章和资讯。


缓冲 缓冲区 数据 播放器 网络 线程 技术 主动 作用 视频 频繁 场景 文章 抵抗 管理 会主 内存 时候 模块 速度 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技海报 互联网是第几次科技革命的成果 河南云网互联网络科技有限公司 北京路客互联网科技有限公司 互联网科技行业发展 互联网下的科技发展 美国互联网科技 礼当家互联网科技 互联网科技logo设计 互联网金融监管科技 青岛中康互联网医疗科技有限公司 中盈科技互联网信息有限公司 央行互联网金融科技公司 崇明区互联网教育科技诚信经营 杭州壁岐互联网科技有限公司 互联网科技和信息 互联网科技研发水平 恒生互联网科技业指数调整周期 10位科技互联网大佬 银川新华互联网科技学校招聘 融贸通互联网科技 互联网科技汛 昭通云南众福互联网科技有限公司 亳州好赞互联网科技有限公司 洛阳共同富裕互联网科技有限公司 山东子淼互联网科技有限公司 玉溪新华互联网科技怎么选 数字科技和互联网金融哪个好 瑞安市蟠桃会互联网科技有限公司 伍佰万互联网科技是干嘛的
0