Bộ mã hóa AAC mới trong FFmpeg 9.1
(hydrogenaudio.org)- Bộ mã hóa AAC native của FFmpeg đã được viết lại toàn diện về rate control, RDO và cả PNS·TNS·I/S·M/S, với mục tiêu đạt chất lượng đủ để so sánh trực tiếp với các bộ mã hóa AAC bên ngoài
- Cách triển khai mới hoạt động gần với CBR nghiêm ngặt, và không khuyến nghị dùng chế độ VBR thực sự dựa trên
-q:a - Trong các phép so sánh bằng Zimtohrli·ViSQOL, bộ mã hóa
nmrmới nhìn chung cho kết quả tốt hơn fdk-aac và Apple AAC trong dải 64~256kbps, nhưng Opus vẫn giữ lợi thế trong các so sánh riêng - PNS·TNS·I/S·M/S được chọn bên trong vòng lặp RDO, và nếu dự kiến sẽ downmix thì nên dùng
-aac_is 0 -aac_pns 0để giữ nguyên pha - Dù có nhiều đánh giá cải thiện từ 128kbps trở lên, stereo 64kbps, một số mẫu TNS và nội dung giọng nói vẫn là các khu vực cần được kiểm chứng thêm
Viết lại toàn diện bộ mã hóa AAC của FFmpeg
- Bộ mã hóa AAC của FFmpeg đã được viết lại toàn diện, bao gồm rate control, RDO, PNS, TNS, I/S, M/S
- PR viết lại đã được chia sẻ để hợp nhất, và trong các trao đổi tiếp theo việc hợp nhất thực tế cũng đã được xác nhận
- Có thể thử nghiệm bằng bản build từ mã nguồn hoặc sau khi BtbN nightly builds được cập nhật
- Bộ mã hóa mới có thể dùng với codec
aacffmpeg -i input.flac -map 0:0 -c:a aac -b:a 128000 output.m4a- Tắt I/S:
-aac_is 0 - Tắt PNS:
-aac_pns 0
Chỉ số chất lượng và đối tượng so sánh
- Việc so sánh sử dụng Zimtohrli, ViSQOL của Google và các bài kiểm tra nghe
- Zimtohrli: càng thấp càng tốt
- ViSQOL: càng cao càng tốt
- Trong bảng, bộ mã hóa mới được ghi là
nmr, và được so với FFmpeg 8.1fast·twoloop, fdk-aac, Apple AAC và libopus - Kết quả tiêu biểu:
- 64kbps:
nmr0.00309 / 3.83, fdk-aac 0.00322 / 3.69, Apple 0.00612 / 3.29, libopus 0.00100 / 4.59 - 128kbps:
nmr0.00072 / 4.47, fdk-aac 0.00143 / 4.27, Apple 0.00081 / 4.44, libopus 0.00020 / 4.68 - 256kbps:
nmr0.00031 / 4.61, fdk-aac 0.00103 / 4.45, Apple 0.00067 / 4.63, libopus 0.00002 / 4.73
- 64kbps:
- Ở bitrate cao, Zimtohrli bị bão hòa nên ViSQOL được dùng làm tiêu chí phân định; theo tiêu chí này, bộ mã hóa mới dẫn trước trong các so sánh ngoại trừ với Opus
Thiết kế tập trung vào CBR và các công cụ mã hóa
- Bộ mã hóa mới được thiết kế gần như dành riêng cho CBR, với mức dao động bitrate rất nhỏ
- Mục tiêu ngân sách bit giúp cải thiện chất lượng mã hóa
- Không khuyến nghị dùng chế độ VBR thực sự dựa trên
-q:a
- Qua so sánh, các bộ mã hóa khác hầu như không dùng công cụ mã hóa nào ngoài TNS; bộ mã hóa mới trước tiên được so sánh chỉ với TNS, sau đó mới triển khai lại PNS, I/S, M/S
- Theo kết quả reverse engineering, qaac không thực hiện tối ưu hóa tri giác mà dùng đường cong phân bổ bit ưu tiên tần số cao và band energy
- Bộ mã hóa mới dùng đường cong tương tự và đưa masked band energy vào RDO
- Tất cả công cụ mã hóa gồm PNS, TNS, I/S, M/S đều được chọn bên trong vòng lặp RDO
- Không dùng heuristic cố định hay ngưỡng bitrate tùy ý
- Công cụ nào được phép dùng sẽ được áp dụng theo quyết định của RDO
- Ở bitrate cao, nếu bản thân bộ mã hóa đã hoạt động đủ tốt thì các công cụ như I/S và PNS sẽ tự giảm đi để giữ bitrate
Tương thích bộ giải mã và lưu ý khi downmix
- Bộ giải mã AAC của FFmpeg có vấn đề trong xử lý stereo PNS, và lỗi tương tự có thể cũng tồn tại ở các bộ giải mã AAC khác, nên phía bộ mã hóa phải né tránh
- Do các bộ mã hóa trước đây không dùng PNS nên vấn đề này chưa từng lộ ra cho tới nay
- Nếu dự kiến sẽ downmix hoặc đầu ra có khả năng bị downmix, nên dùng
-aac_is 0 -aac_pns 0- Mục đích là giữ nguyên pha của tín hiệu gốc
- Việc thấy nhiều khoảng trống trên spectrogram là hành vi có chủ đích
- Các band bị masking sẽ được đưa về 0 hoặc xử lý bằng PNS
- Nếu các band lân cận đủ mạnh để khó nhận ra band bị thiếu, thì bộ mã hóa sẽ ưu tiên mã hóa tốt hơn những band nghe thấy được thay vì mã hóa kém toàn bộ các band
Sample rate và chính sách cutoff
- Bộ mã hóa được tối ưu chủ yếu cho audio 48kHz
- 44.1kHz và 96kHz cũng hoạt động
- Nếu muốn chất lượng cao nhất thì nên dùng 48kHz
- Các benchmark được công bố chủ yếu chạy ở 44.1kHz, còn dữ liệu tinh chỉnh bằng tai thì ở 48kHz
- Một phần logic windowing/transient gắn với 48kHz
- Do chênh lệch thời gian ở 44.1kHz không lớn nên vẫn được giữ nguyên
- Sau đó chính sách băng thông đã được điều chỉnh
- 128kbps bị giới hạn ở 16kHz
- Từ 160kbps trở lên bị giới hạn ở 18kHz
- Ở 192kbps mỗi kênh, đã đổi sang mã hóa toàn bộ phổ trên 20kHz
- Với stereo 64kbps thì không còn nhiều dư địa, và nếu tăng PNS thêm nữa có thể làm hỏng stereo image
- Ở 64kbps, ngay cả 15kHz cũng có thể còn quá cao nên đã có đề nghị kiểm tra lại với cutoff 12kHz
- Với mono, không cần né lỗi bộ giải mã nên có thể dùng PNS nhiều hơn đáng kể
Phạm vi thử nghiệm và thống kê debug
- Phía phát triển đã thử nghiệm trên bộ sưu tập nhạc 3000 track
- Nội dung giọng nói được thử rất ít nên có thể cần tối ưu thêm
- Bộ mã hóa sẽ in thêm thống kê khi kết thúc
- Ví dụ:
Qavg: 207.975 Tr: 5.3% TNS(L): 4.8% TNS(S): 36.9% M/S: 3.9% I/S: 10.0% PNS: 5.1%
- Ví dụ:
- Ý nghĩa các thống kê:
Qavg: giá trị lambda trung bình, càng cao thì càng khó giữ rateTr: short blocksTNS(L): tỷ lệ dùng TNS ở long frameTNS(S): tỷ lệ dùng TNS ở short frameM/S: tỷ lệ dùng Mid/Side codingI/S: tỷ lệ dùng intensity stereo codingPNS: tỷ lệ dùng perceptual noise substitution
- Nếu phát hiện artifact gây khó chịu, có thể cung cấp kèm sample input gốc và dòng thống kê này để phân tích
Thử nghiệm ban đầu của người dùng và các vấn đề còn lại
- Một người dùng đã thử một bài
Burn the Boatsở 64kbps, 134kbps, 200kbps- 64kbps nghe ổn nhưng có chút artifact
- 134kbps và 200kbps nghe rất tốt
- Trong thử nghiệm khác, với sample
The Towerở 64kbps, có phản hồi rằng bộ mã hóanmrmới cho cảm giác smeary và metallic hơntwoloopcũ- Bản
twoloopcũ cũng có vấn đề collapse ở phần đầu cùng noise và roughness nhìn chung
- Bản
- Với sample
fatboy_30sec, ở 192kbps có tiếng ticking tại 6.836 giây và 10.480 giây, còn sau khi resample sang 48kHz thì xuất hiện thêm tiếng tick ở 14.125 giây- Tắt TNS bằng
-aac_tns 0thì tiếng ticking biến mất - Sau đó có đề nghị thử tăng giá trị
TNS_PG_C1_SHORTtronglibavcodec/aacenc_tns.clên 3.2, 4.2, 5.0 để kiểm tra
- Tắt TNS bằng
- Một người dùng đánh giá Fraunhofer AAC nghe hay hơn trong điều kiện 64kbps và cutoff 16kHz, còn bộ mã hóa mới nghe metallic hơn
- Cùng người đó cũng đánh giá rằng ở bitrate cao trên 128kbps, bộ mã hóa mới hoạt động tốt
- Đồng thời cũng có nhận xét rằng giờ đây FFmpeg native đã có một bộ mã hóa AAC đủ dùng và dễ tiếp cận rộng rãi
1 bình luận
Ý kiến trên Hacker News
Đây là một ví dụ cho thấy Opus mạnh đến mức nào
Bản thân công việc này cũng có giá trị, và việc encoder cho một codec cũ được cải thiện rõ ràng là có lợi, nhưng nếu nhìn vào các con số của Opus trong benchmark này thì ngay cả ở 64kbps nó cũng áp đảo tất cả các encoder AAC
Trong gần 20 năm, tiêu chuẩn de facto của video streaming thời gian thực là RTMP dùng video H.264 và audio AAC, gần như không hỗ trợ codec nào khác
Nếu muốn gửi stream lên YouTube hay Twitch thì cuối cùng vẫn phải gửi H.264 và AAC; OBS cũng hoàn toàn không cho chọn codec video/audio khác trong chế độ streaming và mặc định rằng streamer sẽ dùng H.264 và AAC
Chỉ cần dùng Opus là xong; nếu vì lý do nào đó không dùng được Opus thì dùng AAC ở bitrate thật cao để đảm bảo tương thích
Bạn vẫn có chất lượng tốt mà không cần tìm hiểu nên chọn encoder và chế độ nào
Dù vậy, việc có một encoder AAC mặc định chất lượng tốt là rất tuyệt, nhưng tôi không hiểu lắm vì sao chủ yếu lại là bitrate cố định
Vì vậy Opus hầu như không được dùng trong game hoặc các bản phân phối qua store, nơi có thể phát sinh một số vấn đề giấy phép nhất định
Rất mong xem hiệu năng thực tế sẽ ra sao
Encoder AAC hiện có của FFmpeg có chất lượng đầu ra kém và thường có artifact kiểu tiếng ríu rít khó chịu, nên để có âm thanh ổn thì phải cài encoder Apple Core Audio trên từng máy tính dùng để ghi hình video
Khi so sánh A/B/X, MP3 320kbps nghe tốt hơn AAC 320kbps encode bằng FFmpeg, và tương đương với AAC 256kbps encode bằng Core Audio
Nếu từ giờ không cần cài Core Audio nữa thì đây là một cải tiến lớn, và những người quay màn hình hoặc stream bằng các công cụ như OBS có thể thấy chất lượng âm thanh cải thiện đáng kể trong bản cập nhật tiếp theo
Nó bọc các DLL iTunes trên Windows thành một công cụ encode độc lập có CLI, và theo tôi biết thì cũng chạy được trên Wine của Linux: https://web.archive.org/web/20250814194428/https://www.andre...
Không nhất thiết phải có Mac hoặc cài trọn bộ iTunes để encode AAC chất lượng cao
Trước đây khi so sánh FDK AAC và Apple AAC ở 192kbps thì tôi không nhận ra khác biệt, nhưng encoder AAC cũ của FFmpeg thì sụp hẳn ở bitrate này
Tuy nhiên đó là theo bitrate cố định
Core Audio còn có TVBR, một chế độ bitrate biến đổi mà encoder mới không có
Vì vậy trong các trường hợp có thể dùng TVBR, Core Audio có thể vẫn là lựa chọn tốt nhất, nhưng tôi kỳ vọng encoder FFmpeg mới cũng sẽ đủ tốt nếu có thêm nhiều người tìm các sample gây vấn đề và đóng góp để tinh chỉnh
Hoặc cứ dùng Opus là được; nó cũng ổn cho giọng nói và ngày nay gần như chạy được ở mọi nơi
Nếu Apple không chọn H.265, có lẽ chúng ta đã sống trong một thiên đường AV1 rồi
Phần “decoder AAC của FFmpeg có lỗi trong xử lý PNS stereo, và các decoder AAC khác cũng có thể có lỗi này nên encoder sẽ tránh né. Vì các encoder khác không dùng PNS nên đến giờ lỗi chưa được phát hiện” khá thú vị
Tôi không biết PNS là gì, nhưng có vẻ nó đã hành hạ một use case rất đặc thù nào đó của ai đó suốt 20 năm
Một là nếu dùng TNS trên PNS thì nhiễu được chèn vào sẽ bị TNS shaping, nhưng bên tạo ra nhiễu lại là decoder chứ không phải encoder, nên điều đó vô lý
Vì thế PNS bị hỏng, và vấn đề lớn hơn là khi dùng PNS cùng một số công cụ stereo, nhiễu sẽ rò vào hai kênh giống hệt nhau và phá hỏng stereo imaging
Do đó cách tốt nhất là chỉ bật PNS khi dải tương ứng ở cả hai kênh đều là nhiễu, hoặc đủ phi âm sắc và bị che lấp
Đây là một bản cập nhật tuyệt vời, các chi tiết được trình bày rất rõ
Opus rất tuyệt và có vị trí của nó, nhưng AAC sẽ không biến mất
Có đoạn nói rằng “Bộ mã hóa chủ yếu được tối ưu cho âm thanh 48kHz. Hãy chấp nhận đi. Giờ là năm 2026, resampling miễn phí, và 48kHz là tiêu chuẩn. 44.1kHz cũng chạy, 96kHz cũng chạy, nhưng nếu muốn chất lượng tốt nhất thì hãy dùng 48kHz”; ngày nay 48kHz có thật sự là tiêu chuẩn không?
Phần tóm tắt khuyến nghị tần số lấy mẫu 48kHz cho việc sản xuất, xử lý và trao đổi chương trình âm thanh dùng PCM, đồng thời cũng thừa nhận 44.1kHz cho một số ứng dụng số tiêu dùng, 32kHz cho các ứng dụng liên quan đến truyền dẫn, và 96kHz cho các ứng dụng cần băng thông cao hơn hoặc bộ lọc chống aliasing ít gắt hơn
Cá nhân tôi thấy 44.1kHz giống như một phiền toái nhỏ còn sót lại từ di sản cũ
Vì vậy cửa sổ 20ms và 60ms nghe rất khác nhau với tai người, nên phải tối ưu lại hoàn toàn mọi tham số tâm lý âm học của bộ mã hóa cho từng sampling rate
Trong Opus thì dĩ nhiên vấn đề này đã được giải quyết
Ví dụ như sau khi dựng phim, việc đồng bộ khẩu hình trở nên dễ hơn
Một bộ mã hóa FFmpeg AAC mới tốt hơn là điều đáng hoan nghênh, nhưng có hai lưu ý khá lớn trong chi tiết
Nó chỉ hỗ trợ bitrate cố định và chỉ được tối ưu cho lấy mẫu 48kHz
Không thể encode bitrate biến thiên dựa trên tiêu chí chất lượng là một khoảng trống lớn, và xét việc âm thanh CD trên toàn thế giới là 44.1kHz thì đây cũng có vẻ là một thiếu sót lớn
Âm thanh bitrate biến thiên nghe rất tệ và cũng không tiết kiệm được bitrate nhiều đến vậy
-q:athì có thể dùng bitrate biến thiên “thật”, nhưng chỉ số thấp hơn vài phần trămDù vậy vẫn khó cảm nhận được và tôi cho rằng nó vẫn thắng
Benchmark chủ yếu được làm ở 44.1kHz, còn dữ liệu tinh chỉnh bằng tai là 48kHz, nên một số logic về windowing/transient bị gắn với 48kHz
Tuy nhiên nó cũng đã được chuyển sang 44.1kHz đủ tốt, chênh lệch timing không lớn nên cứ để nguyên như vậy
Thật thú vị là rất nhiều phần trong đó phụ thuộc vào đôi tai của chính lập trình viên
Vừa khiến tôi bất an, vừa khá ngầu, vì đánh giá chất lượng âm thanh chủ quan đến vậy
Musepack cũng từng được ưa chuộng trong một thời gian ở một ngách nhỏ; đó là một codec đơn giản nhưng được tinh chỉnh rất tốt
Loa và tai nghe cũng vậy: người ta nghĩ đó là chất lượng linh kiện, nhưng thực ra hiểu biết tổng thể về vật lý âm thanh và khả năng tinh chỉnh tốt mới là yếu tố chi phối phần lớn
Một bổ sung rất đáng mừng
Hy vọng giờ đây nó có thể thay thế fdk-aac
Có người mang đến bộ mã hóa AAC hay nhất từ trước đến nay, vậy mà phản ứng đầu tiên lại là quản trị viên bắt bẻ chuyện 48kHz hay 44kHz; đúng là Internet kiểu cũ
Tác giả thực ra chưa kiểm thử ở sampling rate phổ biến nhất, nên với bất kỳ dự án nghiêm túc nào, việc thay thế toàn bộ một pipeline đã vận hành hàng chục năm là điều vô lý
Chờ đến khi có đủ kiểm chứng là hoàn toàn hợp lý
Trước đây khi tôi encode bài hát cho iPod nano bằng ffmpeg thì file bị hỏng
Khi phát, cứ vài giây lại có tiếng pop và click chen vào ngắt quãng; không biết giờ đã được sửa chưa