文章目录
- Q1: 音视频同步如何处理的?
- Q2: 播放器如何做到低延迟播放?
- Q3: Seek 怎么做?
- Q4:如何做到变速播放?
- Q5: 为什么播放器要多线程?各线程干什么?
- Q6: 架构总览
- Q7 : 为什么要用消息队列? 状态机有什么用?
- Q8: 解码后的数据格式
- Q9:如何控制解码的?
- Q10: 为什么需要两级队列?
- Q11: 时间戳转化问题
- Q12: 播放器跳转时能精确跳到指定位置吗?
Q1: 音视频同步如何处理的?
音视频不同线程、帧间隔不同、PTS 可能不准,所以要同步。我们以音频为主时钟,原因为:1 感知敏感度 2 同步的复杂性 3 缓存策略:以音频为基准,视频帧可以采用丢帧或者重复帧来处理,如果声音这样处理,容易声音的跳跃或者重复 4 时钟源:音频帧的事件源更稳定
完整做法:先用相邻 PTS 差得到正常帧间隔 delay,再算 diff = 视频时钟 − 主时钟。将diff的值和阈值进行比较,阈值大约夹在 40 到 100 毫秒: |diff| 很小,delay 保持静态帧间隔; diff 小于 −阈值,说明视频慢了,delay 收成 max(0, delay+diff),必要时丢帧; diff 大于 +阈值,说明视频快了,delay 加大,比如变成两倍。 再用 frame_timer + delay 和系统时间比:还没到就继续等(画面停在上一帧),到了或过了就显示下一帧,并更新 frame_timer。
为何同步? 不同线程 / 不同间隔 / PTS 不准
↓
选音频为主时钟(人对声音更敏感)
↓
┌─ 10-1 ─────────────────────────────┐
│ diff = 视频PTS − audclk │
│ >0 → 等;否则 → 显示 │
└────────────────────────────────────┘
↓(完整版继续)
delay₀ = 相邻PTS差 或 1/fps
diff = 视频时钟 − 主时钟
阈值 ≈ clamp(delay₀,
