iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0

Media Framework:AudioFlinger、MediaCodec、Camera HAL

intro

在 Android 裡,「多媒體 (Media) 框架」是串接 App 與硬體 (聲音、影像、攝影機) 的關鍵層。當我們播放音樂、錄製影片、使用相機拍照/錄影,這些功能背後都會經過以下三大子系統:

  • Audio sub-system:負責音訊播放與錄製,其核心為 AudioFlinger 與 Audio HAL
  • Codec / 編碼解碼子系統:負責把壓縮格式(如 H.264、AAC 等)編碼與解碼,主要由 MediaCodec(或新版的 Codec 2.0)承擔
  • Camera subsystem:從應用層的 Camera API 到 HAL 與攝影機硬體,進行預覽、拍照、錄影等操作

AudioFlinger 與音訊子系統

  1. 音訊架構總覽
    整個 Android 音訊架構可以簡化為以下層次:
App 層 (MediaPlayer、AudioTrack、AudioRecord)
    ↓
Audio Framework 層 (AudioManager, AudioPolicyService, AudioFlinger)
    ↓
Audio HAL (legacy C HAL / HIDL / AIDL)
    ↓
Linux Kernel Audio Driver / DSP / Codec 硬體
  • 應用透過 AudioTrack、AudioRecord 或 MediaPlayer、MediaRecorder 對音訊進行操作
  • AudioManager 提供音量控制、路由選擇、音效政策 (音訊重路由、混音策略)
  • AudioPolicyService 負責高層的政策決策(哪個輸出裝置、優先順序)
  • AudioFlinger 是系統服務,負責音訊混音 (mixer)、音軌管理 (track management)、與 HAL 連動
  • Audio HAL 是硬體抽象層,負責與音訊晶片或 DSP 的具體交互
  1. AudioFlinger 的角色與架構
    AudioFlinger 是運行於 Media 中心 (媒體伺服器 / media server / mediaserver) 的服務,初始化時由 SystemServer 啟動。它管理多個音軌 (track),並負責把各條音軌混音 (mixing)、處理音量、音效 (effects)、以及透過 HAL 將音訊資料送到硬體輸出。

其核心模組包括:

  • Track 管理:每個播放或錄製會對應一條 AudioTrack 或 AudioRecord track
  • Mixer / 音訊混音器:將多條音軌的 PCM 資料加總,處理音量與效果
  • 環繞 / 效果處理:如 EQ、混響、回聲消除等
  • 輸出 / HAL 接口:將混音結果交給 HAL 層進行實際輸出
    AudioFlinger 與 HAL 之間通過標準接口溝通。硬體廠商須實現 Audio HAL,以便支援該裝置的音訊裝置 (揚聲器、耳機、藍牙、USB audio 等)。
  1. 音訊流程範例:播放音樂
    以下是一個簡化版本的播放流程:
App (MediaPlayer / AudioTrack) → 音訊資料 → AudioFlinger (track creation) → 混音 / volume / 效果 → HAL 接口 → Kernel audio driver → 揚聲器輸出

具體步驟可能如下:

  1. App 建立 AudioTrack,呼叫 track = AudioFlinger.createTrack(...)
  2. AudioFlinger 為該音軌分配緩衝區 (buffer)、設定參數 (頻率、通道、格式)
  3. App 提供 PCM 資料 (寫 buffer or 通知 callback)
  4. AudioFlinger 的混音執行緒 (mixer thread) 將多條音軌資料進行加總、處理音量、效果
  5. 混音結果經由 HAL 音訊輸出流 (stream out) 傳到硬體

音訊架構較複雜的部分還包含音效服務 (AudioEffect)、音訊路由 (切換耳機 / 外放 / 藍牙) 等。

  1. About AudioFlinger
  • AudioFlinger 與 AudioPolicyService 的差異
  • 如何實現低延遲音訊 (low-latency playback)?
  • 音軌 (Track) 的 buffer 與混音 (mixer) 是怎麼做的?
  • 音訊 HAL 接口 (legacy vs HIDL / AIDL)
  • 支援 Bluetooth A2DP、USB Audio、數位音效處理

MediaCodec:編碼 / 解碼子系統

在音視頻播放或錄製的場景中,必須將壓縮格式 (如 H.264, AAC 等) 轉換為裸 PCM / YUV 或反過來。這就是 MediaCodec 的職責。

  1. MediaCodec 的定位
    MediaCodec 是 Android Framework 提供的編碼 / 解碼 API。其背後可支援硬體加速 (HW codec) 或軟體實現。使用者不必知道底層硬體細節,只需操作高階 API。

MediaCodec 與之配套的有 MediaExtractor(負責從文件 / 資源中讀取 Codec 資訊與壓縮資料)、MediaMuxer / MediaFormatMediaCodec.Callback 等。

在 Android Q (10) 或更新版本,Google 推出 Codec 2.0 架構,以取代舊的 ACodec + OpenMAX 架構。Codec 2.0 提供零拷貝、component chaining、filter 等能力。

  1. 架構與流程
    架構如下:
App 層 (MediaPlayer / MediaRecorder / ExoPlayer)
   ↓
MediaCodec API 層
   ↓
Codec HAL / 驅動 / vendor codec module
   ↓
硬體編解碼器 (DSP / GPU / SoC codec)

流程例如影片播放(解碼):

  1. 使用 MediaExtractor 讀取壓縮資料與格式
  2. 用 MediaCodec.createDecoderByType() 建立解碼器
  3. 呼叫 configure() + start()
  4. 將壓縮資料放入 input buffer (queueInputBuffer)
  5. 解碼器產出解碼後資料在 output buffer (dequeueOutputBuffer)
  6. 將其送往 Surface 或直接輸出 YUV 給應用層
    若要錄製影片或轉碼,則用編碼器 (encoder),流程類似但方向反向。

在 Codec 2.0 中,許多底層細節已被封裝為更統一的 middleware,支援零拷貝、filter pipeline 與更現代的 buffer 管理方式。

  1. 與 Surface / SurfaceTexture 互動
    當你要把相機拍下來的畫面直接給 MediaCodec 編碼時,一般會透過 SurfaceSurfaceTexture
  • 相機預覽輸出到 SurfaceTexture → 綁定 OpenGL texture
  • MediaCodec 提供一個 input Surface (createInputSurface())
  • 從 Camera HAL 或預覽流程,把畫面渲染到該 Surface
  • 編碼器讀取該 Surface 的 buffer 進行編碼
    這樣可以避免中間的記憶體拷貝,達到效率化。
  1. About MediaCodec
  • ACodec + OpenMAX 架構與新版 Codec 2.0 差異
  • MediaCodec 如何支援零拷貝 (zero copy)
  • 硬體 codec 與軟體 codec 如何選擇
  • Buffer 管理 (input / output buffer) 與同步模式
  • 與 Surface 的整合:如何把 camera 預覽輸出與 codec input 結合

Camera HAL 與攝影機子系統

Camera 子系統在 Android 中相對專業且複雜,它從 Application API, Framework, HAL, 到硬體驅動層都有交互。

  1. Camera HAL 的定位與角色
    Camera HAL (硬體抽象層)連接了 Framework 的 CameraService 與底層的攝影機硬體 (driver / sensor / ISP)。廠商需針對其攝影機晶片實作 HAL,提供標準接口供 Framework 調用。

從 Android 8.0 起,Camera HAL 接口被規範為 HIDL HAL;在 Android 13 起,還可以使用基於 AIDL 的 HAL 方式。

  1. Camera 架構總覽
App 層 (Camera API / CameraX / camera2)
    ↓
Camera Service (Framework)
    ↓ (Binder / HIDL / AIDL)
Camera HAL 接口
    ↓
Camera 驅動 / V4L2 / Sensor / ISP

Camera HAL 主要接口包括:

  • ICameraProvider:列舉可用攝影機設備
  • ICameraDevice:打開攝影機設備、設定參數
  • ICameraDeviceSession:處理 capture request / 流 (preview, video, snapshot)

框架會透過 HAL 接口與攝影機設備溝通,傳遞參數 (曝光、白平衡、AF/AE 等) 與緩衝區 (buffers) 的交換。
HAL 接口也會回報 metadata 和圖像 buffer。

  1. Camera 拍照 / 錄影流程
    以相機拍照或錄影為例,流程大致如下:
    i. App 呼叫 CameraManager.openCamera()
    ii. Framework (CameraService) 做權限檢查、資源競爭管理、建構 camera device
    iii. HAL 接收到 openDevice(),初始化 sensor / 設定 streaming 配置
    iv. App 建立 CameraCaptureSession,提交 capture request
    v. HAL 接 processCaptureRequest(),控制 sensor、ISP、記憶體、緩衝區
    vi. HAL 將 image buffer 和 metadata 回傳
    vii. Framework 將 buffer 交給 application 層 (透過 ImageReader, Surface 等)
    viii. 若是錄影,該 buffer 可交給 MediaCodec 編碼

因為這涉及緩衝區交換、記憶體管理 (gralloc)、同步,以及硬體處理流程 (ISP pipeline),整體架構比較複雜。

  1. HAL 與效能 / 資源管理挑戰
    實作 Camera HAL 時,常見挑戰包括:
  • 緩衝區管理 (如何配置足夠 buffer 數量、不造成延遲)
  • S/N、白平衡、鏡頭校正 (lens distortion) 控制
  • 多流支援 (preview + video + JPEG 拍照)
  • 適時釋放資源 (當 App 退出或切換 camera)
  • 對齊 AIDL / HIDL 接口版本,支援新功能 (例如 RAW capture)

三大子系統如何協同工作

當你在手機上錄製一段攝影機影片並同時錄音,整個流程其實是這三者交互合作:

  1. Camera HAL 捕獲影像 buffer,透過 Surface 提供給 App 或解碼器
  2. MediaCodec 接收來自 Camera 的 frame buffer 作為 input,進行壓縮編碼
  3. AudioFlinger 或相應的音訊子系統錄製音訊資料
  4. 最後將音訊與影像混流 (multiplex) 成 MP4 / MKV 等封裝格式

也就是說:

  • Camera 提供原始影像 (如 YUV)
  • MediaCodec 編碼影像
  • AudioFlinger / Audio HAL 提供音訊
  • App 層或 MediaMuxer 將音訊與影像封裝成影片檔
    在這個流程中,buffer 傳遞與同步 (timestamp, pts) 是非常關鍵的部分。

典型時序流程圖

下面是一個簡化的流程圖,描述從「開始錄影」到「得到影片檔案」的整體流程:

https://ithelp.ithome.com.tw/upload/images/20251009/20178907PMZXPJRwah.png

七、效能優化與挑戰
在這些子系統中,有許多性能優化與挑戰點,包括:

  • 零拷貝 (Zero-copy)
    • 使用 Surface / SurfaceTexture 和 MediaCodec input surface,避免中間拷貝。
    • Codec 2.0 提供 zero-copy pipeline 機制,以減少記憶體拷貝。
  • 同步 (Timing / Timestamp)
    • Video 和 Audio 必須同步,即音畫同步 (A/V sync)。
    • Camera HAL 必須提供準確 metadata、timestamp,MediaCodec 需轉換 PTS/PTS 調整。
  • Buffer 管理
    • 適當數量 buffer 避免「空緩衝」或「緩衝爆掉」
    • 回收 buffer、避免 memory leak
  • 多流支援
    • 同時提供 preview、video 和 snapshot 等不同 stream
    • HAL 必須能處理多流 pipeline、資源分配
  • 延遲 (Latency)
    • 錄影、預覽、編碼都希望延遲低
    • Mixer / 音訊子系統也需配合低延遲策略
  • 版本相容性與 HAL 升級
    • 廠商須從 legacy HAL → HIDL HAL → AIDL HAL 遷移
    • 必須保障向後相容 (例如相機的 HAL3 等級)

Questions

  • AudioFlinger 的角色與 mixer, track 管理如何實作?
  • Audio HAL / 音效 policy 與路由的設計方式
  • MediaCodec 架構與 ACodec / Codec2.0 差異
  • MediaCodec 與 Surface 的整合、零拷貝機制
  • Camera HAL3 架構 (HIDL / AIDL) 的接口設計
  • captureRequest → HAL → 驅動 → metadata → buffer 流程
  • 當多流 (preview + video + snapshot) 同時運行時的資源管理
  • 音訊 / 視訊同步 (A/V sync) 的處理方式
  • 實作 Camera HAL 常見挑戰:buffer management、ISPs、驅動匹配
  • 如何在系統中建構一條從 Camera → Codec → Audio → 封裝的流程

Summary

  • AudioFlinger:處理音訊混音、音軌管理與輸出,是音訊子系統的核心服務
  • MediaCodec:提供高階 API 用於硬體 / 軟體編解碼,新的 Codec 2.0 架構支援高效率與 zero-copy
  • Camera HAL:作為硬體抽象層,橋接 Framework 與攝影機硬體,支援 capture request、metadata、緩衝區交換

這三大子系統彼此協作:例如錄影時,Camera HAL 提供影像 buffer → MediaCodec 編碼 → 同時錄音 (AudioFlinger) → 最終封裝成影片檔


上一篇
#23
下一篇
#25
系列文
安豬複習26
  1. 22
    #21
  2. 23
    #22
  3. 24
    #23
  4. 25
    #24
  5. 26
    #25
完整目錄
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言