这篇写什么?
双屏电视上一种「看起来像解码卡、其实是音频线程拖后腿」的现象:
- 大屏 进入 No Signal(无信号)
- 小屏 再播视频 → 画面/声画卡顿
根因不在小屏播放器本身,而在 TV audio patch 输入线程 在无信号分支里 睡得太久,环形缓冲处理节奏被打乱。
一句话:
无信号 / tv_mute
→ patch 输入线程清缓冲后 usleep
→ 20ms 太长:醒得少、积得多、醒来连吐
→ 小屏卡顿
→ 改成 5ms:更勤检查、更少堆积

相关:TV HDMI-IN Patch 流程、ALSA period 与缓冲。
一、现象
| 条件 | 表现 |
|---|---|
| 大屏 | 无信号(No Signal) |
| 小屏 | 播放视频出现卡顿 |
| 关联模块 | audio_patch_input_threadloop(TV 音频 patch 输入循环) |
大屏无节目时,patch 线程仍会跑「静音 / 无信号」分支;若这里节奏不对,会 indirectly 影响同进程里其它音频路径的调度与缓冲水位,小屏听感/观感就会发糊、发顿。
二、原因:无信号分支里 usleep(20ms) 太长
问题出在类似逻辑(示意):
if (aml_dev->tv_mute || !check_tv_stream_signal(&in->stream)) {
memset(patch->in_buf, 0, bytes_avail);
ring_buffer_clear(ringbuffer);
usleep(20 * 1000); // 原来:每次循环睡 20ms
}
含义拆开看:
| 步骤 | 作用 |
|---|---|
tv_mute 或 !check_tv_stream_signal |
电视静音,或检测不到有效 TV 音频信号(含 No Signal) |
memset + ring_buffer_clear |
丢掉无效/脏数据,避免乱响 |
usleep |
空转时少占 CPU,隔一段时间再检查信号 |
20ms 的问题:
- 线程在无信号状态下 醒来频率偏低(大约 50 次/秒量级)
- 其它路径仍可能往环里写、或共享调度资源
- 线程长时间阻塞 → 缓冲侧更容易出现 滞留 / 水位异常
- 一旦信号或路径恢复、线程连续跑起来,容易 短时间连吐堆积数据
- 表现到小屏:播放发卡、声画不跟手
所以不是「清缓冲写错了」,而是 清完以后睡太久,处理节拍跟不上。
三、修复:20ms → 5ms
if (aml_dev->tv_mute || !check_tv_stream_signal(&in->stream)) {
memset(patch->in_buf, 0, bytes_avail);
ring_buffer_clear(ringbuffer);
usleep(5 * 1000); // 改为 5ms
}
| 对比 | 20ms | 5ms |
|---|---|---|
| 醒来检查频率 | 约 50 Hz | 约 200 Hz |
| 无信号时空转 CPU | 更省 | 略高一点,仍可接受 |
| 环缓冲滞留风险 | 更高 | 更低 |
| 小屏卡顿 | 易复现 | 验证可解除 |
usleep 单位是 微秒:5 * 1000 = 5000µs = 5ms。
改完后,无信号时仍会清缓冲、仍会休眠降载,但会 更勤地醒来看信号、维持环水位,避免「睡久了 → 积一堆 → 醒来连吐」。
四、为什么双屏更容易暴露?
单屏时,大屏无信号往往整机都闲着,卡顿不明显。
双屏时:
大屏 patch:No Signal → 长 usleep 空转
小屏:仍在播视频,需要正常音频/调度
两边共用 audio 服务与缓冲策略时,一侧睡太死,另一侧就更容易抖。把无信号空转从 20ms 收到 5ms,是很小的改动,但对「双屏各干各的」场景很关键。
五、调参时注意
| 注意点 | 说明 |
|---|---|
| 不是越短越好 | usleep(0) 或极短会导致空转打满 CPU |
| 5ms 是经验值 | 在「降载」和「及时处理」之间折中;现场可按 CPU 占用再微调 |
| 先确认进了这个分支 | log / 断点确认 No Signal 时确实走 tv_mute / !check_tv_stream_signal |
| 与 pop 修复区分 | 清缓冲防的是脏数据噪声;这里卡顿是 睡太久,别混成一个问题 |
六、小结
| 项目 | 内容 |
|---|---|
| 现象 | 大屏 No Signal → 小屏播视频卡顿 |
| 根因 | audio_patch_input_threadloop 无信号分支 usleep(20ms) 过长 |
| 修复 | 改为 usleep(5 * 1000) |
| 本质 | 空转要省电,但不能把 patch 线程睡到跟不上环缓冲 |
一句话:无信号时可以睡,但别睡到小屏都卡。
相关阅读
评论
还没有评论,来做第一个吧
赞同、吐槽、提问都行,评论区开放