FFmpeg 9.1 AAC 編碼器重寫

FFmpeg 9.1 AAC 編碼器重寫

FFmpeg 9.1 引入了一個全新重寫的原生 AAC 編碼器,旨在取代先前次優的原生實作。新編碼器在各種位元率下提供更優秀的音訊品質,於 Google 的 Zimtohrli 與 ViSQOL 等指標上超越 fdk-aac 與 Apple 的 qaac

技術架構與最佳化

全新編碼器從頭開始重寫了速率控制、率失真最佳化(RDO)以及所有核心編碼工具。主要技術改進包括:

  • 完整 RDO 整合:所有編碼工具——包括感知噪聲置換(PNS)、時間噪聲整形(TNS)、強度立體聲(I/S)與中/側(M/S)編碼——皆納入 RDO 迴路。編碼器不會使用任意的位元率截斷或啟發式規則,而是僅在給定位元預算下提供最佳品質的工具。
  • 感知最佳化:不同於某些競爭者僅依賴簡單的頻段能量曲線,新編碼器使用受遮蔽的頻段能量進行 RDO,以更好地將位元分配給可聽頻率。
  • 嚴格的 CBR 實作:編碼器針對恆定位元率(CBR)進行最佳化,因為固定的位元預算目標能顯著提升編碼效率。開發者建議不要使用 -q:a(真實 VBR 模式)。
  • 策略性頻段歸零:編碼器會透過歸零或 PNS 處理受遮蔽的頻段,故意在頻譜圖中留下「洞」。此設計優先確保可聽頻段的高品質編碼,而非嘗試以低品質編碼所有頻段。

效能基準

根據開發者的說法,新編碼器(特別是 nmr 編碼器)在大多數位元率下,於 Zimtohrli 與 ViSQOL(Zim 越低、ViS 越高越好)測量中均優於 fdk-aac 與 Apple 的編碼器。

位元率 (kbps) 8.1 fast 8.1 twoloop nmr fdk-aac apple libopus
64 0.01315 / 2.65 0.00696 / 3.24 0.00309 / 3.83 0.00322 / 3.69 0.00612 / 3.29 0.00100 / 4.59
96 0.00338 / 3.77 0.00268 / 3.99 0.00134 / 4.04 0.00153 / 3.98 0.00175 / 3.87 0.00039 / 4.62
128 0.00229 / 4.10 0.00170 / 4.28 0.00072 / 4.47 0.00143 / 4.27 0.00081 / 4.44 0.00020 / 4.68
160 0.00129 / 4.30 0.00108 / 4.44 0.00051 / 4.56 0.00065 / 4.31 0.00117 / 4.51 0.00084 / 4.68
256 0.00105 / 4.41 0.00121 / 4.55 0.00031 / 4.61 0.00103 / 4.45 0.00067 / 4.63 0.00002 / 4.73

註:表中列出 Zim / ViS 數值。整體而言 Opus 仍是最佳表現者。

使用指南與限制

為了在新編碼器上取得最佳效果,使用者應遵循以下特定設定:

  • 取樣率:編碼器主要針對 48kHz 音訊進行最佳化。雖然支援 44.1kHz 與 96kHz,但建議使用 48kHz 以獲得最高品質。
  • 混音:若輸出預計會被混音,下混時應使用 -aac_is 0 -aac_pns 0 以保留原始訊號相位。
  • 頻寬截斷:開發者建議在 128kbps 時將頻寬降低至 16kHz,160kbps 以上則降低至 18kHz,使用 -cutoff 參數實現。

社群回饋與已知問題

在 HydrogenAudio 上的早期使用者測試指出以下幾點值得注意:

  • 整體品質:使用者在 134kbps 與 200kbps 時報告「極致聆聽」體驗,明顯優於舊原生編碼器的「啁啾」雜訊。
  • TNS 嘀嗒聲:有使用者在高位元率(192kbps)時聽到「嘀嗒聲」,在關閉 TNS (-aac_tns 0) 後消失。開發者推測可能是 libavcodec/aacenc_tns.c 中過於激進的 TNS 設定所致。
  • 低位元率立體聲影像:在 64kbps 立體聲下,有些使用者覺得新編碼器較舊編碼器更「模糊」或「金屬感」,開發者則指出 64kbps 通常對高品質立體聲 AAC 來說過低。

命令列範例

對於轉換至新編碼器的使用者,建議使用以下指令:

# 標準高品質編碼
ffmpeg -i input.flac -map 0:0 -c:a aac -b:a 128000 output.m4a

# 編碼時停用強度立體聲以保留相位
ffmpeg -i input.flac -map 0:0 -c:a aac -aac_is 0 -b:a 128000 output.m4a

# 編碼時停用 PNS 以保留相位
ffmpeg -i input.flac -map 0:0 -c:a aac -aac_pns 0 -b:a 128000 output.m4a

Sources