ตัวเข้ารหัส AAC ใหม่ใน FFmpeg 9.1
(hydrogenaudio.org)- ตัวเข้ารหัส AAC แบบเนทีฟของ FFmpeg ถูกเขียนใหม่ทั้งหมด ตั้งแต่ rate control, RDO ไปจนถึง PNS·TNS·I/S·M/S โดยตั้งเป้าคุณภาพให้เทียบกับตัวเข้ารหัส AAC ภายนอกได้โดยตรง
- การใช้งานใหม่นี้ทำงานใกล้เคียงกับ CBR ที่เข้มงวด และไม่แนะนำโหมด VBR จริงที่อิง
-q:a - จากการเปรียบเทียบด้วย Zimtohrli·ViSQOL ตัวเข้ารหัส
nmrใหม่ให้ผลโดยรวมดีกว่า fdk-aac·Apple AAC ในช่วง 64~256kbps แต่ Opus ยังเหนือกว่าในการเปรียบเทียบแยกต่างหาก - PNS·TNS·I/S·M/S จะถูกเลือกภายใน ลูป RDO และหากคาดว่าจะมีการ downmix แนะนำให้ใช้
-aac_is 0 -aac_pns 0เพื่อรักษาเฟส - ตั้งแต่ 128kbps ขึ้นไปมีผลประเมินว่าดีขึ้นจำนวนมาก แต่ 64kbps stereo·ตัวอย่าง TNS บางส่วน·คอนเทนต์เสียงพูดยังเป็นพื้นที่ที่ต้องตรวจสอบเพิ่มเติม
เขียนตัวเข้ารหัส FFmpeg AAC ใหม่ทั้งหมด
- ตัวเข้ารหัส AAC ของ FFmpeg ถูกเขียนใหม่ทั้งหมด รวมถึง rate control, RDO, PNS, TNS, I/S, M/S
- PR การเขียนใหม่ ถูกแชร์ในฐานะเป้าหมายสำหรับการ merge และภายหลังมีการยืนยันในเธรดว่า merge แล้วจริง
- สามารถทดสอบได้หลังจาก build จากซอร์ส หรืออัปเดต BtbN nightly builds
- ตัวเข้ารหัสใหม่ใช้ได้ผ่าน codec
aacffmpeg -i input.flac -map 0:0 -c:a aac -b:a 128000 output.m4a- ปิด I/S:
-aac_is 0 - ปิด PNS:
-aac_pns 0
ตัวชี้วัดคุณภาพและคู่เทียบ
- การเปรียบเทียบใช้ Zimtohrli ของ Google, ViSQOL และการทดสอบการฟัง
- Zimtohrli ยิ่งต่ำยิ่งดี
- ViSQOL ยิ่งสูงยิ่งดี
- ในตาราง ตัวเข้ารหัสใหม่แสดงเป็น
nmrและถูกเทียบกับ FFmpeg 8.1 เดิมแบบfast·twoloop, fdk-aac, Apple AAC, libopus - ผลลัพธ์หลัก:
- 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 สูง Zimtohrli จะอิ่มตัว จึงใช้ ViSQOL เป็นตัวตัดสินเสมอ และตามเกณฑ์นี้ตัวเข้ารหัสใหม่เหนือกว่าคู่เทียบ ยกเว้น Opus
การออกแบบที่เน้น CBR และเครื่องมือเข้ารหัส
- ตัวเข้ารหัสใหม่ถูกออกแบบมาใกล้เคียงกับ CBR-only และ bitrate แกว่งน้อยมาก
- เป้าหมายงบประมาณบิตช่วยคุณภาพการเข้ารหัส
- ไม่แนะนำโหมด VBR จริงที่อิง
-q:a
- มีการเทียบว่าตัวเข้ารหัสอื่นแทบไม่ใช้เครื่องมือเข้ารหัสนอกจาก TNS และตัวเข้ารหัสใหม่เริ่มเทียบด้วย TNS อย่างเดียวก่อน จากนั้นจึง implement PNS, I/S, M/S ใหม่
- จากผล reverse engineering พบว่า qaac ไม่ได้ทำ perceptual optimization แต่ใช้เส้นโค้งการจัดสรรบิตที่ให้ความสำคัญกับความถี่สูงและ band energy
- ตัวเข้ารหัสใหม่ใช้ masked band energy กับเส้นโค้งคล้ายกันใน RDO
- เครื่องมือเข้ารหัสทั้งหมด ได้แก่ PNS, TNS, I/S, M/S ถูกเลือกภายใน ลูป RDO
- ไม่ใช้ heuristic แบบคงที่หรือ cutoff bitrate ตามอำเภอใจ
- เครื่องมือที่ใช้ได้จะถูกใช้ตามการตัดสินของ RDO
- ที่ bitrate สูง หากตัวเข้ารหัสทำงานได้ดีพอ เครื่องมืออย่าง I/S และ PNS จะปิดตัวเองเพื่อรักษา bitrate
ความเข้ากันได้ของตัวถอดรหัสและข้อควรระวังเรื่อง downmix
- ตัวถอดรหัส AAC ของ FFmpeg มีปัญหาในการจัดการ stereo PNS และบั๊กเดียวกันอาจมีในตัวถอดรหัส AAC อื่นด้วย จึงมีการหลบเลี่ยงในฝั่งตัวเข้ารหัส
- ตัวเข้ารหัสเดิมไม่ได้ใช้ PNS ปัญหานี้จึงไม่เคยปรากฏจนถึงตอนนี้
- หากมีแผนจะ downmix หรือมีโอกาสที่ output จะถูก downmix แนะนำให้ใช้
-aac_is 0 -aac_pns 0- เป้าหมายคือการรักษา เฟส ของสัญญาณเดิม
- การเห็นช่องว่างจำนวนมากใน spectrogram เป็นพฤติกรรมที่ตั้งใจไว้
- band ที่ถูก masking จะถูกทำให้เป็น 0 หรือประมวลผลด้วย PNS
- หาก band ข้างเคียงดังพอจนทำให้ band ที่หายไปสังเกตได้ยาก จะเลือกเข้ารหัส band ที่ได้ยินให้ดีขึ้น แทนที่จะเข้ารหัสทุก band แบบคุณภาพแย่
นโยบาย sample rate และ cutoff
- ตัวเข้ารหัสถูกปรับแต่งโดยเน้น เสียง 48kHz เป็นหลัก
- 44.1kHz และ 96kHz ก็ใช้งานได้
- หากต้องการคุณภาพสูงสุด แนะนำให้ใช้ 48kHz
- benchmark ที่เผยแพร่ส่วนใหญ่ทำที่ 44.1kHz ส่วนข้อมูลที่จูนด้วยการฟังเป็น 48kHz
- logic บางส่วนของ windowing/transient ผูกกับ 48kHz
- ที่ 44.1kHz ความต่างของ timing ไม่มาก จึงคงไว้เช่นเดิม
- ภายหลังมีการปรับนโยบาย bandwidth
- 128kbps จำกัดที่ 16kHz
- 160kbps ขึ้นไปจำกัดที่ 18kHz
- ที่ 192kbps ต่อ channel เปลี่ยนให้เข้ารหัส spectrum ทั้งหมดตั้งแต่ 20kHz ขึ้นไป
- ที่ 64kbps stereo มีสิ่งที่ทำได้ไม่มาก และหากเพิ่ม PNS มากขึ้นอาจทำให้ stereo image เสียได้
- ที่ 64kbps แม้ 15kHz ก็อาจสูงเกินไป จึงมีการขอให้ทดสอบ cutoff 12kHz ใหม่
- ใน mono ไม่ต้องหลบเลี่ยงบั๊กของตัวถอดรหัส จึงใช้ PNS ได้มากกว่ามาก
ขอบเขตการทดสอบและสถิติ debug
- การทดสอบของฝั่งพัฒนาทำกับคอลเลกชันเพลง 3000 แทร็ก
- คอนเทนต์เสียงพูดถูกทดสอบน้อยมาก จึงอาจต้องปรับแต่งเพิ่มเติม
- ตัวเข้ารหัสจะแสดงสถิติเพิ่มเติมเมื่อจบการทำงาน
- ตัวอย่าง:
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%
- ตัวอย่าง:
- ความหมายของสถิติ:
Qavg: ค่า lambda เฉลี่ย ยิ่งสูงแปลว่ายิ่งรักษา rate ได้ยากTr: short blocksTNS(L): อัตราการใช้ TNS ใน long frameTNS(S): อัตราการใช้ TNS ใน short frameM/S: อัตราการใช้ Mid/Side codingI/S: อัตราการใช้ intensity stereo codingPNS: อัตราการใช้ perceptual noise substitution
- หากพบ artifact ที่รบกวน สามารถส่งตัวอย่าง input ต้นฉบับพร้อมบรรทัดสถิตินี้เพื่อใช้วิเคราะห์ได้
การทดสอบผู้ใช้ช่วงแรกและปัญหาที่ยังเหลือ
- ผู้ใช้รายหนึ่งทดสอบเพลง
Burn the Boatsเพลงเดียวที่ 64kbps, 134kbps, 200kbps- 64kbps ดี แต่มี artifact เล็กน้อย
- 134kbps และ 200kbps ฟังดูดีมาก
- ในการทดสอบอื่น มี feedback ว่าในตัวอย่าง
The Towerที่ 64kbps ตัวเข้ารหัสnmrใหม่ให้ความรู้สึก smear และ metallic มากกว่าtwoloopเดิมtwoloopเดิมก็มีปัญหา collapse ช่วงเริ่มต้น รวมถึง noise และ roughness โดยรวม
- ในตัวอย่าง
fatboy_30secที่ 192kbps ได้ยิน ticking sound ที่วินาที 6.836 และ 10.480 และหลัง resample เป็น 48kHz มี tick เพิ่มที่วินาที 14.125- เมื่อปิด TNS ด้วย
-aac_tns 0ticking จะหายไป - มีการขอต่อให้ลองเพิ่มค่า
TNS_PG_C1_SHORTในlibavcodec/aacenc_tns.cเป็น 3.2, 4.2, 5.0 แล้วตรวจสอบ
- เมื่อปิด TNS ด้วย
- ผู้ใช้รายหนึ่งประเมินว่าภายใต้เงื่อนไข 64kbps และ cutoff 16kHz, Fraunhofer AAC ฟังดีกว่า และตัวเข้ารหัสใหม่ฟังดู metallic
- ผู้ใช้รายเดียวกันประเมินว่าที่ bitrate สูงเกิน 128kbps ตัวเข้ารหัสใหม่ทำงานได้ดี
- ยังมีความเห็นว่าตัวเข้ารหัส AAC ที่เข้าถึงได้กว้างภายใน FFmpeg แบบเนทีฟนั้นใช้งานได้ดีพอแล้ว
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
เป็นตัวอย่างที่แสดงให้เห็นว่า Opus แข็งแกร่งแค่ไหน
งานแบบนี้เองก็มีคุณค่า และการที่เอนโค้ดเดอร์สำหรับโคเดกเก่า ๆ ดีขึ้นก็เป็นประโยชน์แน่นอน แต่ถ้าดูตัวเลขของ Opus ในเบนช์มาร์กนี้ แม้ที่ 64kbps ก็ยังเหนือกว่าเอนโค้ดเดอร์ AAC ทั้งหมด
ตลอดเกือบ 20 ปีที่ผ่านมา มาตรฐานโดยพฤตินัยของวิดีโอสตรีมมิงแบบเรียลไทม์คือ RTMP ที่ใช้วิดีโอ H.264 กับเสียง AAC และแทบไม่มีการรองรับโคเดกอื่น
ถ้าจะส่งสตรีมไปยัง YouTube หรือ Twitch สุดท้ายก็ต้องส่ง H.264 กับ AAC อยู่ดี และ OBS ในโหมดสตรีมมิงก็ไม่อนุญาตให้เลือกโคเดกวิดีโอ·เสียงอื่นเลย โดยถือว่าสตรีมเมอร์จะใช้ H.264 กับ AAC
แค่ใช้ Opus ก็จบ และถ้าด้วยเหตุผลบางอย่างใช้ Opus ไม่ได้ ก็ใช้ AAC ที่บิตเรตสูงมากเพื่อความเข้ากันได้
สามารถได้คุณภาพดีโดยไม่ต้องไปค้นว่าควรเลือกเอนโค้ดเดอร์กับโหมดไหน
ถึงอย่างนั้น การมีเอนโค้ดเดอร์ AAC ดี ๆ เป็นค่าเริ่มต้นก็ยอดเยี่ยม แต่ยังไม่ค่อยเข้าใจว่าทำไมจึงเน้น บิตเรตคงที่ เป็นหลัก
ด้วยเหตุนี้ Opus จึงแทบไม่ถูกใช้ในเกมหรือแพ็กเกจที่เผยแพร่ผ่านสโตร์ ซึ่งอาจเกิดปัญหาเรื่องไลเซนส์บางอย่างได้
รอดูอยู่ว่าประสิทธิภาพจริงจะเป็นอย่างไร
เอนโค้ดเดอร์ AAC เดิมของ FFmpeg มีคุณภาพเอาต์พุตแย่ และมักมีอาร์ติแฟกต์แบบเสียงจิ๊บ ๆ ที่น่ารำคาญ ดังนั้นถ้าต้องการเสียงที่ดี ก็ต้องติดตั้งเอนโค้ดเดอร์ Apple Core Audio บนคอมพิวเตอร์ทุกเครื่องที่ใช้บันทึกวิดีโอ
เมื่อลองเปรียบเทียบแบบ A/B/X พบว่า MP3 320kbps ดีกว่า AAC 320kbps ที่เอนโค้ดด้วย FFmpeg และใกล้เคียงกับ AAC 256kbps ที่เอนโค้ดด้วย Core Audio
ถ้าตอนนี้ไม่จำเป็นต้องติดตั้ง Core Audio แล้ว ก็ถือเป็นการปรับปรุงครั้งใหญ่ และคนที่บันทึกหน้าจอหรือสตรีมด้วยเครื่องมืออย่าง OBS อาจได้คุณภาพเสียงดีขึ้นมากในการอัปเดตครั้งถัดไป
มันห่อหุ้ม iTunes Windows DLL ให้กลายเป็นเครื่องมือเอนโค้ดแบบสแตนด์อโลนที่มี CLI และเท่าที่ทราบก็ทำงานบน Wine ใน Linux ได้ด้วย: https://web.archive.org/web/20250814194428/https://www.andre...
การเอนโค้ด AAC คุณภาพสูงไม่จำเป็นต้องมี Mac หรือติดตั้ง iTunes ทั้งชุดเสมอไป
เมื่อก่อนตอนเปรียบเทียบ FDK AAC กับ Apple AAC ที่ 192kbps ผมฟังความต่างไม่ออก แต่เอนโค้ดเดอร์ AAC เดิมของ FFmpeg พังที่บิตเรตนี้
แต่เป็นการวัดตามบิตเรตคงที่
Core Audio ยังมี TVBR ซึ่งเป็นโหมด บิตเรตแปรผัน ที่เอนโค้ดเดอร์ใหม่ไม่มี
ดังนั้นในกรณีที่ใช้ TVBR ได้ Core Audio อาจยังเป็นตัวเลือกที่ดีที่สุดต่อไป แต่ผมคาดว่าเอนโค้ดเดอร์ FFmpeg ตัวใหม่ก็น่าจะดีพอได้ หากมีคนจำนวนมากขึ้นช่วยหาและส่งตัวอย่างที่มีปัญหาเพื่อปรับจูน
หรือไม่ก็ใช้ Opus ไปเลย ใช้กับเสียงพูดก็โอเค และทุกวันนี้แทบทำงานได้ทุกที่
ถ้า Apple ไม่เลือกใช้ H.265 เราอาจได้อยู่ในยูโทเปียของ AV1 ไปแล้วก็ได้
ส่วนที่บอกว่า “ดีโค้ดเดอร์ AAC ของ FFmpeg มีบั๊กในการจัดการ PNS แบบสเตอริโอ และอาจมีในดีโค้ดเดอร์ AAC ตัวอื่นด้วย จึงเลี่ยงปัญหาที่ฝั่งเอนโค้ดเดอร์ เอนโค้ดเดอร์ตัวอื่นไม่ได้ใช้ PNS เลยจึงไม่ถูกพบมาจนถึงตอนนี้” น่าสนใจ
ผมไม่รู้ว่า PNS คืออะไร แต่รู้สึกเหมือนมันคงรบกวน use case เฉพาะทางมาก ๆ ของใครบางคนมาตลอด 20 ปี
อย่างแรกคือถ้าใช้ TNS บน PNS นอยส์ที่ถูกใส่เข้ามาจะถูก shaping ด้วย TNS ทั้งที่ตัวที่สร้างนอยส์คือดีโค้ดเดอร์ ไม่ใช่เอนโค้ดเดอร์ จึงไม่สมเหตุสมผล
สิ่งนี้ทำให้ PNS เสีย และปัญหาที่ใหญ่กว่าคือเมื่อใช้ PNS ร่วมกับเครื่องมือสเตอริโอบางอย่าง นอยส์จะรั่วเข้าไปเหมือนกันทั้งสองแชนเนล ทำให้ stereo imaging เสีย
ดังนั้นทางที่ดีที่สุดคือเปิด PNS เฉพาะเมื่อย่านความถี่นั้นของทั้งสองแชนเนลเป็นนอยส์ทั้งหมด หรือมีความเป็นโทนเสียงต่ำพอและถูก masking
เป็นอัปเดตที่ยอดเยี่ยมและสรุปรายละเอียดได้ดี
Opus ยอดเยี่ยมและมีที่ทางของมัน แต่ AAC คงไม่หายไปไหน
มีตอนหนึ่งที่บอกว่า “ตัวเข้ารหัสถูกปรับให้เหมาะกับเสียง 48kHz เป็นหลัก ยอมรับซะ ตอนนี้ปี 2026 แล้ว การรีแซมเปิลไม่มีต้นทุน และ 48kHz คือมาตรฐาน 44.1kHz ก็ใช้ได้ 96kHz ก็ใช้ได้ แต่ถ้าอยากได้คุณภาพดีที่สุด ให้ใช้ 48kHz” ทุกวันนี้ 48kHz เป็นมาตรฐานจริง ๆ หรือ?
ในบทคัดย่อระบุว่า สำหรับการผลิต การประมวลผล และการแลกเปลี่ยนโปรแกรมเสียงที่ใช้ PCM แนะนำให้ใช้ ความถี่การสุ่มตัวอย่าง 48kHz และยังยอมรับ 44.1kHz สำหรับแอปพลิเคชันดิจิทัลสำหรับผู้บริโภคบางประเภท, 32kHz สำหรับแอปพลิเคชันที่เกี่ยวข้องกับการส่งสัญญาณ และ 96kHz สำหรับแอปพลิเคชันที่ต้องการแบนด์วิดท์สูงขึ้นหรือฟิลเตอร์ป้องกัน aliasing ที่ผ่อนคลายกว่า
ส่วนตัวแล้วรู้สึกว่า 44.1kHz เป็นเหมือนความยุ่งยากเล็ก ๆ ที่ตกทอดมาจากอดีต
ดังนั้นหน้าต่าง 20ms กับ 60ms จึงฟังต่างกันมากสำหรับหูมนุษย์ ทำให้ต้องปรับจูน พารามิเตอร์ psychoacoustic ทั้งหมดของตัวเข้ารหัสใหม่หมดสำหรับแต่ละ sample rate
แน่นอนว่าใน Opus ปัญหานี้ถูกแก้ไปแล้ว
เช่น ทำให้ซิงก์รูปปากหลังตัดต่อง่ายขึ้น
ยินดีกับตัวเข้ารหัส FFmpeg AAC ใหม่ที่ดีกว่าเดิม แต่ในรายละเอียดมีข้อแม้ใหญ่ ๆ อยู่สองอย่าง
รองรับเฉพาะบิตเรตคงที่ และ ปรับให้เหมาะกับการสุ่มตัวอย่าง 48kHz เท่านั้น
การเข้ารหัสแบบบิตเรตแปรผันตามเกณฑ์คุณภาพไม่ได้ถือเป็นช่องว่างใหญ่ และเมื่อคิดว่าเสียง CD ทั่วโลกเป็น 44.1kHz นี่ก็ดูเหมือนเป็นการขาดหายที่ใหญ่เช่นกัน
เสียงแบบบิตเรตแปรผันฟังแย่มาก และก็ไม่ได้ประหยัดบิตเรตได้มากเท่าไร
-q:aจะใช้บิตเรตแปรผัน “จริง ๆ” ได้ แต่คะแนนชี้วัดต่ำลงไม่กี่เปอร์เซ็นต์ถึงอย่างนั้นก็น่าจะรับรู้ได้ยาก และยังคิดว่ายังชนะอยู่
เบนช์มาร์กทำที่ 44.1kHz เป็นหลัก ส่วนข้อมูลที่จูนด้วยหูเป็น 48kHz ดังนั้นลอจิกบางส่วนเกี่ยวกับ windowing และ transient จึงผูกกับ 48kHz
แต่ก็ย้ายมาใช้กับ 44.1kHz ได้ดีพอ และความต่างด้านเวลาไม่มาก จึงปล่อยไว้แบบนั้น
น่าสนใจที่หลายส่วนขึ้นอยู่กับหูของนักพัฒนาเอง
ในขณะเดียวกันก็น่ากังวลและค่อนข้างเท่ด้วย เพราะ การตัดสินคุณภาพเสียง เป็นเรื่องอัตวิสัยมากขนาดนี้
Musepack ก็เคยได้รับความนิยมในกลุ่มเฉพาะอยู่พักหนึ่ง เป็น codec ที่เรียบง่ายแต่จูนมาดีมาก
ลำโพงและหูฟังก็เหมือนกัน ผู้คนมักคิดว่าเป็นเรื่องคุณภาพชิ้นส่วน แต่จริง ๆ แล้วความเข้าใจฟิสิกส์เสียงโดยรวมและความสามารถในการจูนให้ดีต่างหากที่เป็นปัจจัยส่วนใหญ่
เป็นการเพิ่มเข้ามาที่น่ายินดีมาก
ตอนนี้หวังว่าจะใช้แทน fdk-aac ได้
มีคนสร้าง ตัวเข้ารหัส AAC ที่อาจดีที่สุดตลอดกาลมาให้ แต่ปฏิกิริยาแรกกลับเป็นผู้ดูแลมาถกเรื่อง 48kHz หรือ 44kHz นี่มันอินเทอร์เน็ตยุคเก่าของจริง
ผู้เขียนไม่ได้ทดสอบกับ sample rate ที่ใช้กันแพร่หลายที่สุดจริง ๆ ดังนั้นสำหรับโปรเจกต์จริงจังใด ๆ การยกเครื่อง pipeline ที่ใช้งานมาหลายสิบปีทั้งชุดจึงเป็นเรื่องไร้เหตุผล
การรอจนกว่าจะตรวจสอบเพียงพอแล้วเป็นเรื่องสมเหตุสมผลอย่างสมบูรณ์
เมื่อก่อนตอนใช้ ffmpeg เข้ารหัสเพลงสำหรับ iPod nano ไฟล์เสีย
ระหว่างเล่นจะมีเสียงป๊อปกับคลิกแทรกขาด ๆ ทุกไม่กี่วินาที สงสัยว่าตอนนี้แก้แล้วหรือยัง