KunSpace
返回博客

Aetheryal Multi-Room 架构:从 TVUI 到 MS12 PCM 回调

2026年7月15日
1 次阅读

读完了?别空手走啊 😏

若有所获,赐一赞 — 作者会假装很忙实则刷新页面

写评论

赞同、吐槽、提问都行,评论区开放

这篇写什么?

Aetheryal Multi-Room 要把 本机正在播的系统音频 PCM 送到 TV 侧协议栈做多房间分发。整条链路跨 TVUI、常驻 TVBG、AIDL 服务、Dolby MS12 与 HAL 桥接库,最容易踩坑的是:没 ConnectToSink 就永远收不到回调

一句话:

TVUI 拉起 TVBG → registerCallback → ConnectToSink(开门控)
→ 系统播放进 MS12 → stereo_pcm_output → aetheryal_audio_write
→ platformWritePcmAudio → onPCMAudioDataReady → Aetheryal native

当前已验证:HAL → AIDL Service → TVBG callback 通路可用,且 dump 文件可正确还原播放音频。


代码时序图

Aetheryal Multi-Room 时序:TVUI/TVBG → AIDL → MS12 → HAL Bridge → PCM 回调Aetheryal Multi-Room 时序:TVUI/TVBG → AIDL → MS12 → HAL Bridge → PCM 回调

整体架构(10 步)

  1. tvuiapp 启动后拉起 tvbackground(或等价常驻进程)。
  2. tvbackground 通过 Binder 获取 IAetheryalAudio/default
  3. tvbackground 调用 registerCallback(IAetheryalAudioCallback)
  4. (必须写进集成说明) 再调用 aetheryalConnectToSinkStereo / aetheryalConnectToSinkMultichannel,使服务端 mAudioDataEnabled = true
    否则 platformWritePcmAudio 会门控,日志常见 pcm gated(disconnected)不会调用 onPCMAudioDataReady
    调试可用:vendor.media.audiohal.aetheryal.force_enable=1 绕过门控。
  5. 系统播放音频时,经 MS12 管线:
    • 生产者侧:从 out_write_new 等进入混音 / MS12 输入,经 dolby_ms12_system_process 等处理;
    • 消费者侧:MS12 通过回调产出 PCM,经 stereo_pcm_outputms12_output_master → … → 最终 ALSA / 硬件。
  6. #ifdef ENABLE_AETHERYAL_AUDIO_BRIDGE 下,audio_hw_ms12_v2.c::stereo_pcm_output() 末尾调用 aetheryal_audio_write(...)(与 ms12_info 中的格式 / 声道一致,常见 48k / 2ch / 16bit)。
  7. libaetheryalaudiohal 将 PCM 打成 byte[],调用 platformWritePcmAudio(...)
  8. AetheryalAudioAidlService::platformWritePcmAudio 在门控允许时调用 mCallback->onPCMAudioDataReady(...)
  9. tvbackground 在回调中收到 PCM → Aetheryal native / 协议栈。
  10. vendor.media.audiohal.aetheryal.dump=1,桥接库将同一份 PCM 追加到 /data/vendor/audiohal/aetheryal_bridge_in.pcm

关键模块

模块 职责
IAetheryalAudio.aidl 控制接口 + platformWritePcmAudio(HAL 注入的服务端入口)
AetheryalAudioAidlService 维护 register / unregister、连接门控(mAudioDataEnabled / force_enable)、把 PCM 转发到 onPCMAudioDataReady
audio_hw_ms12_v2.c::stereo_pcm_output() 音频消费者:MS12 解码后的立体声 PCM 路径;宏内调用 aetheryal_audio_write
audio_hw.c::out_write_new() 音频生产者侧写入口
libaetheryalaudiohal HAL ↔ AIDL 桥接(C 接口 aetheryal_audio_write、Binder 调 platformWritePcmAudio),并负责可控 dump

文字时序(对照图)

[TVUI App]
   │ (start/bind)
   ▼
[TVBG Service]
   │ 1) getService("…IAetheryalAudio/default")
   │ 2) registerCallback(IAetheryalAudioCallback)
   │ 3) aetheryalConnectToSinkStereo / Multichannel  ← 打开数据门控
   ▼
[AetheryalAudioAidlService]
   │ (holds mCallback, mAudioDataEnabled 或调试 force_enable)
   │
   │ <audio playback ongoing>
   │
[AudioFlinger] → [out_write_new → … → MS12 生产者路径]
                         │
                         │ dolby_ms12_system_process / threadloop …
                         ▼
              [MS12 消费者:ms12_output → stereo_pcm_output]
                         │
                         │ 立体声 PCM(sr/ch/bit 以 ms12_info / 实际 buffer 为准)
                         ▼
              [stereo_pcm_output()]  (#ifdef ENABLE_AETHERYAL_AUDIO_BRIDGE)
                         ▼
                 [aetheryal_audio_write()]  (libaetheryalaudiohal)
                         │
                         ├─(optional) dump if dump=1
                         │  → /data/vendor/audiohal/aetheryal_bridge_in.pcm
                         ▼
      platformWritePcmAudio(timestamp, sr, ch, bit, data)
                         ▼
[AetheryalAudioAidlService::platformWritePcmAudio]
                         ▼
mCallback->onPCMAudioDataReady(...)
                         ▼
[TVBG callback] → [Aetheryal native / audio pipeline]

调试属性

属性 作用
vendor.media.audiohal.aetheryal.log=1 HAL 侧 bridge stats、服务侧统计日志
vendor.media.audiohal.aetheryal.dump=1 落盘 /data/vendor/audiohal/aetheryal_bridge_in.pcm
vendor.media.audiohal.aetheryal.force_enable=1 调试时绕过 mAudioDataEnabled 门控

集成验收(必看)

正常集成: 应看到 pcm stats:(或等价非 gated 路径),不应长期只有 pcm gated(disconnected)

现象 常见原因 怎么处理
只有 pcm gated(disconnected) 没调 ConnectToSink,或连接失败 确认 stereo / multichannel 任一连接成功;或临时 force_enable=1
有 write、无 callback registerCallback,或 callback 已死 检查 TVBG 注册与进程存活
dump 文件无声 / 不对 格式与播放不一致,或未开 dump dump=1,用 48k/2ch/16bit 等实际参数还原
宏未编译进 HAL 未开 ENABLE_AETHERYAL_AUDIO_BRIDGE 确认 stereo_pcm_output 末尾能进 aetheryal_audio_write

一句话记住

先 ConnectToSink 开门控,再指望 onPCMAudioDataReady;PCM 从 MS12 的 stereo_pcm_output 抄一份出来,经 HAL 桥进 AIDL,最后进 TVBG。

评论

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

赞同、吐槽、提问都行,评论区开放