KunSpace
返回博客

Soundbar / eARC 无声打包修:待机、OOBE、CEC 与 hold bus

2026年6月26日
尚无阅读

读完了?别空手走啊 😏

这行字出现时,你的大拇指应该已经 itch 了

写评论

读完了不评论,作者会以为你在沉思

这篇写什么?

一串看起来像「好多单」的投诉,其实都钉在同一条链上:HDMI ARC / eARC + Soundbar / AVR 不出声

典型场景
待机 / 重启后 Soundbar 无声
OOBE(开箱向导)过程中接 Soundbar 无声
大版本升级后 Soundbar 无声
播任意音频,Soundbar 仍无声
HDMI1 播 4K Dongle + HDMI ARC/eARC 接 AVR,无声
笼统的 HDMI-ARC/eARC 无声

一轮合入从 Framework CEC开机 OneTouchPlay,到 内核 eARC hold bus 一起加强。本文按「现象 → 分层修法」整理。

一句话:

无声 ≠ 只有 HAL 音量错
  → ARC 状态被误关掉 / 启动时 OTP 抢早
  → eARC 与 ARC CEC 互踩
  → 编码格式切换未按 HDMI 2.1 做 mute+hold bus
  → 分层修:状态、时序、消息过滤、总线保持

eARC / Soundbar 无声四层修复

相关:Zoom + ARC 双无声拔 ARC 音量飙最大


一、为什么会「一整片」无声?

ARC/eARC 要同时稳住三件事:

职责
CEC / 系统音频模式 谁是 Audio System、ARC 是否 Initiated、eARC 开时别再走旧 ARC 握手
启动 / 输入切换 OneTouchPlay、OOBE 未完成时别乱切源
内核 eARC TX 编码类型变化时按规范 mute + hold bus 再恢复

任一环在待机唤醒、首次插线、升级后冷启动时掉链子,听感都是同一个词:Soundbar 没声


二、修法一:别把 ARC 状态误关掉(待机恢复)

文件示意: SetArcTransmissionStateAction.java

问题形态:从待机恢复后,声音从 ARC 掉回本机喇叭,外放变哑。

关键改动:

  • <Report ARC Initiated> 发送失败时:日志从 debug 提到 warning
  • 去掉 失败分支里的 setArcStatus(false)

原先 NACK 一次就 setArcStatus(false),等于把 ARC 判死刑;待机抖动、瞬时 NACK 很常见,误关之后外放就没了。
修法:发送失败不要立刻拆掉 ARC 状态,避免「醒过来 ARC 已经 false」。


三、修法二:OneTouchPlay 等开机 / OOBE 完成(避免漏声道)

文件示意: InputChangeAdapter.java

问题形态:开机或 OOBE 未完成 时 Soundbar 已接上,OneTouchPlay / 输入切换过早,漏掉外放通路

改动要点:

做法
启动未完成 先缓存 OTP 行为,boot complete 后再切
OOBE user_setup_complete 未完成则直接 return,不处理
前台已是 TV 输入 走广播切源;否则 startActivity 切到对应 passthrough input
Handler 用延迟 / 投递保证时序,避免启动竞态

目标:启动向导和系统音频就绪之后,再响应 OneTouchPlay,Soundbar 声道不会被「太早的一次切源」弄丢。


四、修法三:CEC 上理顺 ARC / eARC,少静音、少冲突

涉及: HdmiCecLocalDevice(Tv).javaHdmiControlService.javaRequestArcInitiationAction.java 等。

1)eARC 已开时,别再当真处理一套 ARC CEC

例如在 eARC on 时:

  • 忽略 / 不按旧逻辑处理 INITIATE_ARC、部分 System Audio 相关消息
  • 避免 eARC 物理链路已通,CEC 又去 Terminate/Refuse ARC 把策略搅乱

2)ARC 尚未建立时,别乱触发音频切换

startArcAction 等路径增加保护:旧状态与新请求都是「关」时,干净落 setArcStatus(false) 并返回,减少无效动作。

收到 ReportArcInitiated 请求时,条件扩展为 isEarcOn() || mArcEstablished,eARC 场景也能正确回 Report ARC Initiated

3)RequestArcInitiationAction 加重试

  • 发送 <Request Arc Initiation> 失败时 最多重试(如 2 次)
  • 超时同样可重试再 finish
  • 收到对 Initiation 的 Feature Abort 时:不要 粗暴 disableArc(AVR 在 eARC / 切换瞬间 Abort 很常见)

提高「请求建 ARC」的成功率,减少「以为建好了其实没有」。

4)其它配套

  • handleReportShortAudioDescriptor 等返回行为调整,避免短音频描述被直接丢掉
  • TV 侧消息分发走 dispatchMessage,保证待机 handler 与常规 CEC 路径一致
  • System Audio 从 AVR 发起时,避开与 DeviceDiscoveryAction 打架

五、修法四:内核 eARC——编码切换要 mute + hold bus

文件示意: earc.c / earc_hw.c

HDMI 2.1 对 eARC TX 在音频编码类型变化时,要求做足够的 总线保持与静音(规范侧常见表述含 至少约 100ms 量级的 hold;实现里用可调 delay_time,默认示例 40ms 起步,需按规范与联调拉齐)。

数据结构

struct work_struct tx_hold_bus_work;
enum audio_coding_types last_tx_audio_coding_type;

工作函数(示意)

tx_hold_bus_work_func:
  earctx_dmac_mute_and_hold_bus(..., true);
  msleep(delay_time);
  earctx_dmac_mute_and_hold_bus(..., false);

aml_earctx_enable / earc_dai_trigger 里:当 tx_audio_coding_type 相对 last_* 变化schedule_work(tx_hold_bus_work),并更新 last。

插拔 / probe 时把 last_tx_audio_coding_type 置为 UNDEFINED,避免沿用上一次编码类型。

硬件侧 earctx_dmac_mute_and_hold_bus:配 mute block、hold min time,再脉冲启动 / 恢复 biphase——保证 AVR/Soundbar 在格式切换窗不会吃到非法流而「整段哑火」。


六、场景 ↔ 修法对照

场景 更相关的修法
待机 / 重启后无声 勿因 Report 失败 setArcStatus(false);ARC 发起重试
OOBE 中接 Soundbar 无声 OTP 推迟 + user_setup_complete 门闩
升级后无声 启动时序 + eARC/ARC CEC 过滤 + hold bus
任意播放无声 / Dongle+AVR eARC 开时忽略冲突 ARC 消息;编码切换 hold bus
笼统 ARC/eARC 无声 以上整包回归

七、验证建议

  • 待机 → 唤醒,Soundbar / AVR 是否仍有声
  • 冷启动、OOBE 未完成 / 完成后各插一次外放
  • 纯 ARC 设备与 eARC 设备各测
  • HDMI1 播 Dongle + ARC/eARC 播系统音
  • 切换 PCM ↔ Bitstream(编码类型变化)听是否断流后能恢复
  • log:hold bus finish、Request Arc Initiation retry、OTP deferred

八、小结

一句话
ARC 状态 失败别轻易 setArcStatus(false)
开机 OTP 等 boot / OOBE,再切声道
CEC eARC 开着就别和旧 ARC 消息互殴;Initiation 可重试
内核 编码一变就 mute + hold bus,再恢复

口诀:外放无声,先分清是状态被关了、切源太早了、CEC 打架了,还是格式切换没 hold 住总线。


相关阅读

评论

还没有评论,来做第一个吧

读完了不评论,作者会以为你在沉思