# FFmpeg 9.1의 새로운 AAC 인코더

> Clean Markdown view of GeekNews topic #31052. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31052](https://news.hada.io/topic?id=31052)
- GeekNews Markdown: [https://news.hada.io/topic/31052.md](https://news.hada.io/topic/31052.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-07-03T02:43:46+09:00
- Updated: 2026-07-03T02:43:46+09:00
- Original source: [hydrogenaudio.org](https://hydrogenaudio.org/index.php/topic,129691.0.html)
- Points: 1
- Comments: 1

## Topic Body

- FFmpeg의 네이티브 **AAC 인코더**가 rate control, RDO와 PNS·TNS·I/S·M/S까지 전면 재작성되며, 외부 AAC 인코더와 직접 비교할 만한 품질을 목표로 함
- 새 구현은 **엄격한 CBR**에 가깝게 동작하고, `-q:a` 기반 실제 VBR 모드는 권장되지 않음
- Zimtohrli·ViSQOL 비교에서 새 `nmr` 인코더는 64~256kbps 구간에서 fdk-aac·Apple AAC보다 대체로 좋은 결과를 보였지만, **Opus**는 별도 비교에서 여전히 우위로 남음
- PNS·TNS·I/S·M/S는 **RDO 루프** 안에서 선택되며, 다운믹스가 예상되면 위상 유지를 위해 `-aac_is 0 -aac_pns 0` 사용이 권장됨
- 128kbps 이상에서는 개선 평가가 많았지만, 64kbps 스테레오·일부 TNS 샘플·음성 콘텐츠는 추가 검증이 필요한 영역으로 남아 있음

---

### FFmpeg AAC 인코더 전면 재작성
- FFmpeg의 AAC 인코더가 **rate control**, RDO, PNS, TNS, I/S, M/S를 포함해 전면 재작성됨
- [재작성 PR](https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23430)은 병합 대상으로 공유됐고, 이후 스레드에서 실제 병합이 확인됨
- 테스트는 소스 빌드 또는 [BtbN nightly builds](https://github.com/BtbN/FFmpeg-Builds/releases/tag/latest) 업데이트 이후 가능함
- 새 인코더는 `aac` 코덱으로 사용할 수 있음
  - `ffmpeg -i input.flac -map 0:0 -c:a aac -b:a 128000 output.m4a`
  - I/S 비활성화: `-aac_is 0`
  - PNS 비활성화: `-aac_pns 0`

### 품질 지표와 비교 대상
- 비교에는 Google의 [Zimtohrli](https://github.com/google/zimtohrli), [ViSQOL](https://github.com/google/visqol), 청감 테스트가 사용됨
  - Zimtohrli는 낮을수록 좋음
  - ViSQOL은 높을수록 좋음
- 표에서 새 인코더는 `nmr`로 표시됐고, 기존 FFmpeg 8.1 `fast`·`twoloop`, fdk-aac, Apple AAC, libopus와 비교됨
- 대표 결과:
  - 64kbps: `nmr` 0.00309 / 3.83, fdk-aac 0.00322 / 3.69, Apple 0.00612 / 3.29, libopus 0.00100 / 4.59
  - 128kbps: `nmr` 0.00072 / 4.47, fdk-aac 0.00143 / 4.27, Apple 0.00081 / 4.44, libopus 0.00020 / 4.68
  - 256kbps: `nmr` 0.00031 / 4.61, fdk-aac 0.00103 / 4.45, Apple 0.00067 / 4.63, libopus 0.00002 / 4.73
- 고비트레이트에서는 Zimtohrli가 포화되므로 ViSQOL이 타이브레이커로 쓰였고, 이 기준에서는 Opus를 제외한 비교에서 새 인코더가 앞섬

### CBR 중심 설계와 코딩 도구
- 새 인코더는 **CBR 전용**에 가깝게 설계됐고, 비트레이트 변동이 매우 작음
  - 비트 예산 목표가 코딩 품질에 도움이 됨
  - `-q:a` 기반 실제 VBR 모드는 권장되지 않음
- 다른 인코더들은 TNS 외 코딩 도구를 거의 쓰지 않는 것으로 비교됐고, 새 인코더는 TNS만으로 먼저 비교한 뒤 PNS, I/S, M/S를 다시 구현함
- qaac는 역공학 결과 지각 최적화를 하지 않고, 고주파를 선호하는 비트 할당 곡선과 밴드 에너지를 사용함
  - 새 인코더는 유사한 곡선에 **masked band energy**를 RDO에 사용함
- 모든 코딩 도구인 PNS, TNS, I/S, M/S는 **RDO 루프** 안에서 선택됨
  - 고정 휴리스틱이나 임의 비트레이트 컷오프를 쓰지 않음
  - 사용할 수 있는 도구는 RDO 판단에 따라 적용됨
- 고비트레이트에서는 인코더 자체가 충분히 잘 동작하면 I/S와 PNS 같은 도구가 스스로 꺼져 비트레이트를 유지함

### 디코더 호환성과 다운믹스 주의점
- FFmpeg의 AAC **디코더**는 stereo PNS 처리에 문제가 있고, 같은 버그가 다른 AAC 디코더에도 있을 수 있어 인코더에서 우회함
  - 기존 인코더들이 PNS를 쓰지 않아 이 문제가 지금까지 드러나지 않았음
- 다운믹스가 예정돼 있거나 출력이 다운믹스될 가능성이 있으면 `-aac_is 0 -aac_pns 0` 사용이 권장됨
  - 목적은 원래 신호의 **위상** 유지임
- 스펙트로그램에서 많은 구멍이 보이는 것은 의도된 동작임
  - 마스킹된 밴드는 0으로 만들거나 PNS 처리함
  - 이웃 밴드가 충분히 커서 빠진 밴드를 인지하기 어렵다면, 모든 밴드를 나쁘게 코딩하기보다 들리는 밴드를 더 잘 코딩하는 쪽을 택함

### 샘플레이트와 컷오프 정책
- 인코더는 주로 **48kHz 오디오**에 맞춰 최적화됨
  - 44.1kHz와 96kHz도 동작함
  - 최고 품질을 원하면 48kHz 사용이 권장됨
- 게시된 벤치마크는 주로 44.1kHz에서 수행됐고, 귀로 튜닝한 데이터는 48kHz였음
  - 일부 windowing/transient 로직은 48kHz에 묶여 있음
  - 44.1kHz에서도 타이밍 차이가 크지 않아 그대로 유지됨
- 이후 대역폭 정책이 조정됨
  - 128kbps는 16kHz로 제한
  - 160kbps 이상은 18kHz로 제한
  - 192kbps per channel에서는 20kHz 이상 전체 스펙트럼을 코딩하도록 변경됨
- 64kbps 스테레오에서는 할 수 있는 일이 많지 않고, PNS를 더 키우면 스테레오 이미지가 망가질 수 있음
  - 64kbps에서는 15kHz도 너무 높을 수 있어 12kHz 컷오프 재테스트가 요청됨
  - 모노에서는 디코더 버그 우회가 필요 없어 PNS를 훨씬 많이 쓸 수 있음

### 테스트 범위와 디버그 통계
- 개발 측 테스트는 **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 blocks
  - `TNS(L)`: long frame의 TNS 사용률
  - `TNS(S)`: short frame의 TNS 사용률
  - `M/S`: Mid/Side coding 사용률
  - `I/S`: intensity stereo coding 사용률
  - `PNS`: perceptual noise substitution 사용률
- 거슬리는 아티팩트를 발견하면 원본 입력 샘플과 이 통계 줄을 함께 제공해 분석할 수 있음

### 초기 사용자 테스트와 남은 문제
- 한 사용자는 `Burn the Boats` 한 곡으로 64kbps, 134kbps, 200kbps를 테스트함
  - 64kbps는 좋지만 약간의 아티팩트가 있음
  - 134kbps와 200kbps는 매우 좋게 들림
- 다른 테스트에서는 64kbps의 `The Tower` 샘플에서 새 `nmr` 인코더가 기존 `twoloop`보다 더 smeary하고 metallic하게 느껴진다는 피드백이 나옴
  - 기존 `twoloop`도 시작 부분 collapse, 전반적 noise와 roughness 문제가 있음
- `fatboy_30sec` 샘플에서는 192kbps에서 6.836초와 10.480초에 ticking sound가 들렸고, 48kHz 리샘플링 후에는 14.125초 tick이 추가됨
  - `-aac_tns 0`으로 TNS를 끄면 ticking이 사라짐
  - `libavcodec/aacenc_tns.c`의 `TNS_PG_C1_SHORT` 값을 3.2, 4.2, 5.0으로 올려 확인해 달라는 요청이 이어짐
- 한 사용자는 64kbps와 16kHz 컷오프 조건에서 Fraunhofer AAC가 더 낫게 들렸고, 새 인코더는 metallic하게 들렸다고 평가함
  - 같은 사용자는 128kbps 초과 고비트레이트에서는 새 인코더가 잘 동작한다고 평가함
  - 네이티브 FFmpeg 안에서 널리 접근 가능한 AAC 인코더가 충분히 쓸 만해졌다는 평가도 함께 나옴

## Comments



### Comment 61118

- Author: neo
- Created: 2026-07-03T02:43:47+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48747116) 
- Opus가 얼마나 강한지 보여주는 사례임  
  이런 작업 자체도 가치 있고, 오래된 코덱용 인코더가 좋아지는 건 분명 이득이지만, 이 벤치마크에서 **Opus** 수치를 보면 64kbps에서도 모든 AAC 인코더를 압도함
  - 좋은 **AAC 인코더**의 가장 큰 장점은 효율이 아니라 호환성임  
    거의 20년 동안 실시간 스트리밍 영상의 사실상 표준은 H.264 영상과 AAC 음성을 쓰는 RTMP였고, 다른 코덱 지원은 거의 없음  
    YouTube나 Twitch로 스트림을 보내려면 결국 H.264와 AAC를 보내게 되며, OBS도 스트리밍 모드에서는 다른 영상·음성 코덱 선택을 아예 허용하지 않고 스트리머는 H.264와 AAC를 쓸 거라고 가정함
  - 기사에 들어가기 전까지 **Opus**가 모델이 아니라 인코더를 말하는 거라는 걸 잠깐 헷갈렸음
  - 손실 오디오 코덱 선택은 이제 거의 고민할 필요가 없어졌음  
    그냥 **Opus**를 쓰면 끝이고, 어떤 이유로 Opus를 못 쓰면 호환성을 위해 AAC를 아주 높은 비트레이트로 쓰면 됨  
    어떤 인코더와 모드를 골라야 할지 조사하지 않아도 좋은 품질을 얻을 수 있음  
    그래도 품질 좋은 기본 AAC 인코더가 생기는 건 훌륭하지만, 왜 주로 **고정 비트레이트**인지 이해는 잘 안 됨
  - [https://en.wikipedia.org/wiki/Opus_(audio_format)#/media/Fil...](<https://en.wikipedia.org/wiki/Opus_(audio_format)#/media/File:Opus_bitrate+latency_comparison.svg>)
  - Opus의 가장 큰 문제는 명세가 부족하다는 데 있다고 봄: [https://nothings.org/stb/stb_opus.html](<https://nothings.org/stb/stb_opus.html>)  
    이 때문에 특정 라이선스 문제가 생길 수 있는 게임이나 스토어 배포물에서는 Opus가 거의 쓰이지 않게 됨

- 실제 성능이 어떨지 기대됨  
  FFmpeg의 기존 **AAC 인코더**는 출력 품질이 나빴고 거슬리는 지저귐 같은 아티팩트가 자주 있어서, 제대로 된 소리를 얻으려면 영상 녹화용 컴퓨터마다 Apple Core Audio 인코더를 설치해야 했음  
  A/B/X 비교를 해보면 320kbps MP3가 FFmpeg로 인코딩한 320kbps AAC보다 낫고, Core Audio로 인코딩한 256kbps AAC와는 비슷했음  
  이제 Core Audio 설치가 필요 없어지면 큰 개선이고, OBS 같은 도구로 화면 녹화나 스트리밍을 하는 사람들은 다음 업데이트 때 음질이 크게 좋아질 수 있음
  - Apple Core Audio와 관련해서 **qaac**가 유용함  
    iTunes Windows DLL을 감싸서 CLI가 있는 독립 인코딩 도구로 만들어 주고, Linux의 Wine에서도 동작하는 것으로 알고 있음: [https://web.archive.org/web/20250814194428/https://www.andre...](<https://web.archive.org/web/20250814194428/https://www.andrews-corner.org/qaac.html>)  
    고품질 AAC 인코딩을 위해 Mac이나 전체 iTunes 설치가 꼭 필요하지는 않음
  - 나는 **FDK AAC** 인코더를 쓰고 있었고, Apple 인코더가 Apple 외 시스템에서도 가능한 줄은 몰랐음  
    예전에 192kbps에서 FDK AAC와 Apple AAC를 비교했을 때는 차이를 못 느꼈지만, 기존 FFmpeg AAC 인코더는 이 비트레이트에서 무너졌음
  - Hydrogenaudio 토론 스레드의 지표 표에서는 새 인코더가 **Core Audio**보다 더 좋은 점수를 받음  
    다만 고정 비트레이트 기준임  
    Core Audio에는 새 인코더에 없는 **가변 비트레이트** 모드인 TVBR도 있음  
    그래서 TVBR을 쓸 수 있는 경우에는 Core Audio가 계속 최고일 수도 있지만, 더 많은 사람이 문제 샘플을 찾아 기여해서 튜닝하면 새 FFmpeg 인코더도 충분히 괜찮아질 거라 기대함
  - 품질을 신경 쓴다면 왜 무손실 코덱을 쓰지 않는지 궁금함  
    아니면 Opus를 쓰면 되고, 음성에도 괜찮고 요즘은 거의 어디서나 동작함
  - Apple이 독점 코덱에 매달리는 건 이해가 안 됨  
    Apple이 **H.265**를 채택하지 않았다면 우리는 AV1 유토피아에 살고 있었을지도 모름

- “FFmpeg의 AAC 디코더는 스테레오 PNS 처리에 버그가 있고, 다른 AAC 디코더에도 있을 수 있어서 인코더에서 우회한다. 다른 인코더는 PNS를 쓰지 않았기 때문에 지금까지 발견되지 않았다”는 부분이 흥미로움  
  **PNS**가 뭔지는 모르지만, 누군가의 아주 특수한 사용 사례를 20년 동안 괴롭혀 왔을 것 같음
  - 문제는 두 가지였음  
    하나는 PNS 위에 **TNS**를 쓰면 삽입된 노이즈가 TNS로 셰이핑되는데, 노이즈를 만든 쪽은 인코더가 아니라 디코더라서 말이 안 됨  
    이 때문에 PNS가 망가졌고, 더 큰 문제는 PNS를 어떤 스테레오 도구와 함께 쓰면 노이즈가 양쪽 채널에 동일하게 새어 들어가 **스테레오 이미징**을 망친다는 점이었음  
    그래서 양쪽 채널의 해당 대역이 모두 노이즈이거나 충분히 비음조적이고 마스킹될 때만 PNS를 켜는 게 최선임
  - [https://www.audiolabs-erlangen.de/content/resources/aesCodin...](<https://www.audiolabs-erlangen.de/content/resources/aesCodingTutorial/pns.html>)

- 세부 사항이 잘 정리된 훌륭한 업데이트임  
  Opus는 훌륭하고 제자리가 있지만, **AAC**가 사라질 일은 없음

- “인코더는 주로 48kHz 오디오에 최적화됐다. 받아들여라. 2026년이고 리샘플링은 공짜이며 48kHz가 표준이다. 44.1kHz도 동작하고 96kHz도 동작하지만, 최고의 품질을 원하면 48kHz를 써라”라는 대목이 있는데, 요즘 정말 **48kHz**가 표준인가?
  - 실제 “표준”에 가장 가까운 건 AES5-2018, “전문 디지털 오디오 권장 관행”이라고 봄  
    초록에서는 PCM을 쓰는 오디오 프로그램의 제작, 처리, 교환에는 **48kHz 샘플링 주파수**를 권장하고, 일부 소비자 디지털 애플리케이션의 44.1kHz, 전송 관련 애플리케이션의 32kHz, 더 높은 대역폭이나 완화된 안티앨리어싱 필터가 필요한 애플리케이션의 96kHz도 인정한다고 되어 있음  
    개인적으로는 44.1kHz가 유산으로 남은 사소한 귀찮음처럼 느껴짐
  - AAC에는 샘플링 레이트에 따라 창 크기가 달라지는 이상한 특성이 있음  
    그래서 20ms 창과 60ms 창은 사람 귀에 아주 다르게 들리므로, 각 샘플링 레이트마다 인코더의 모든 **심리음향 파라미터**를 완전히 다시 최적화해야 함  
    Opus에서는 당연히 이 문제가 해결됐음
  - **48kHz**는 영상과 음성의 정렬을 훨씬 쉽게 만들어 줌  
    예를 들면 편집 후 입 모양 동기화가 쉬워짐
  - Opus 코덱은 모든 입력을 **48kHz**라고 가정하고, 입력을 그쪽으로 리샘플링하는 것으로 알고 있음
  - 거의 모든 DAC는 운영체제가 합리적인 기본값으로 고르기 때문에 기본적으로 **48kHz**로 동작함

- 더 나은 새 FFmpeg AAC 인코더는 환영하지만, 세부 사항에 꽤 큰 단서가 두 가지 있음  
  **고정 비트레이트만 지원**하고, **48kHz 샘플링에만 최적화**되어 있음  
  품질 기준 가변 비트레이트 인코딩을 못 하는 건 큰 공백이고, 전 세계 CD 오디오가 44.1kHz인 점을 생각하면 이것도 큰 누락처럼 보임
  - 오디오 인코딩에 왜 **가변 비트레이트**가 필요한지 모르겠음  
    가변 비트레이트 오디오는 소리가 끔찍하고 비트레이트도 그다지 많이 아끼지 못함
  - `-q:a`를 쓰면 “진짜” 가변 비트레이트를 사용할 수 있지만, 지표는 몇 퍼센트 낮음  
    그래도 지각하기 어렵고 여전히 이긴다고 봄  
    벤치마크는 주로 44.1kHz에서 했고, 귀로 튜닝한 데이터는 48kHz였기 때문에 일부 윈도잉·트랜지언트 로직이 48kHz에 묶여 있음  
    다만 44.1kHz에도 충분히 잘 옮겨졌고 타이밍 차이가 크지 않아서 그대로 둔 것임

- 이 많은 부분이 개발자 본인의 귀에 달려 있다는 게 흥미로움  
  동시에 불안하기도 하고 꽤 멋지기도 한데, **오디오 품질 판단**이 이렇게 주관적임
  - 표와 비교에는 “Google의 새 **Zimtohrli**, ViSQOL, 그리고 내 청각”이 쓰였음
  - 오디오에서는 보통 이런 식임  
    Musepack도 한동안 틈새에서 인기가 있었는데, 단순하지만 튜닝이 아주 잘 된 코덱이었음  
    스피커와 헤드폰도 마찬가지라서, 사람들은 부품 품질이라고 생각하지만 실제로는 전반적인 오디오 물리 이해와 잘 튜닝하는 능력이 대부분을 좌우함

- 아주 반가운 추가임  
  이제 **fdk-aac**를 대체할 수 있으면 좋겠음

- 누군가 역대 최고의 **AAC 인코더**를 만들어 왔는데, 첫 반응이 48kHz냐 44kHz냐를 두고 관리자가 따지는 것이라니 진짜 옛 인터넷답다
  - 그렇게 냉소적으로 볼 일은 아님  
    작성자가 실제로 가장 흔히 쓰이는 샘플링 레이트에서 테스트하지 않았으니, 어떤 진지한 프로젝트라도 수십 년 된 동작 중인 파이프라인을 통째로 갈아엎는 건 터무니없음  
    충분한 검증이 끝날 때까지 기다리는 게 완전히 타당함

- 예전에 ffmpeg로 iPod nano용 노래를 인코딩했을 때는 파일이 깨졌음  
  재생 중 몇 초마다 팝과 클릭 소리가 끊겨 들어갔는데, 이제 고쳐졌는지 궁금함
