Meta의 libwebrtc Fork 복귀 사례 — Shim을 이용한 점진적 전환
Meta가 공개한 엔지니어링 글을 기준으로 장기 유지한 libwebrtc fork를 upstream 계열로 전환한 과정을 정리합니다. 두 구현의 호출 경계를 shim으로 통제하고 use case별로 이동한 방식, fork가 보안 패치와 기능 추적에 만드는 비용, 공개된 사실과 추정을 구분하는 방법을 다룹니다.
목차(25개 항목)
- 0. Meta는 fork를 최신 upstream 기반 구조로 옮겼다
1. 왜 fork로 시작했나 — libwebrtc라는 사실상의 표준
2. fork의 함정 — upstream과 멀어지는 비용은 복리로 늘어난다
3. shim 아키텍처 — fork를 빠져나오는 다리
4. 공개된 최적화 영역 — AV1 적용과 비디오 스케일러
5. P2P → 미디어 서버 전환 — 어디까지가 사실인가
6. 업계 지형 — 다른 벤더들은 어디서 출발했나
7. 그래서 Meta 사례에서 배울 것 — 의사결정 체크리스트
- 8. 한 줄 결론
- 관련 글
- 참고 자료
"Meta 정도 되는 회사면 WebRTC도 바닥부터 자체 개발하지 않았을까요?"라는 질문이 나올 수 있습니다. Meta는 구글의 오픈소스 libwebrtc를 fork해서 시작했고, 그 fork를 수년간(Meta 공식 표현은 'years', 구체 연수 미공개) 유지하다 최신 upstream을 골격으로 쓰는 구조로 마이그레이션했습니다.
이 글은 fork가 왜 매력적이었고 어떤 유지 비용을 만들었는지, Meta가 shim 아키텍처로 최신 upstream 기반 구조로 옮긴 과정을 정리합니다. AV1은 AOMedia가 표준화한 코덱이며, Meta의 공개 성과는 이를 모바일 RTC에 적용한 저복잡도 인코더·디코더 통합과 자체 비디오 스케일러입니다. 공개 자료로 확인되지 않는 구현과 수치는 본문에서 제외했습니다.
0. Meta는 fork를 최신 upstream 기반 구조로 옮겼다
Meta는 오래된 libwebrtc fork를 최신 upstream을 골격으로 쓰는 모듈형 구조로 옮겼다. shim과 자동 renamespacing으로 legacy와 latest 구현을 함께 검증했고, 핵심 구성요소에는 Meta 구현과 패치를 계속 주입한다. AV1 자체를 만든 것이 아니라 AOMedia의 AV1을 RTC에 맞게 채택·최적화했다.
흔한 오해와 정정부터 박아둡니다.
| 오해 | 정확한 이해 |
|---|---|
| Meta는 WebRTC를 바닥부터 자체 개발했다 | Google libwebrtc를 fork해서 시작 |
| Meta는 현재 upstream 코드를 그대로만 쓴다 | 최신 upstream을 골격으로 사용하지만 핵심 구성요소에 자체 구현·패치를 계속 주입 |
| fork는 통제권을 주니 무조건 좋다 | 초기 통제권과 장기 통합 비용의 교환 |
| Meta가 전 세계 SFU 미디어 서버를 깔았다 | 이 글이 인용한 Meta 공식 자료는 해당 배포 구조를 설명하지 않으므로 제외 |
| Meta가 AV1 자체 개발로 막대한 라이선스 비용을 절감했다 | AV1은 AOMedia가 표준화했습니다. Meta는 라이선스 고려를 밝혔지만 구체적 절감액은 공개하지 않았습니다. |
1. 왜 fork로 시작했나 — libwebrtc라는 사실상의 표준
WebRTC 구현에는 오디오/비디오 캡처, 코덱 통합, 지터 버퍼(#23 참고), 손실 복구, 혼잡 제어, ICE/STUN/TURN(#0, #8 참고), DTLS-SRTP 암호화가 필요합니다.
Google의 libwebrtc는 널리 사용되는 오픈소스 구현 중 하나입니다. 다만 모든 브라우저와 RTC 제품이 같은 코드베이스를 사용한다고 일반화할 수는 없습니다.
fork를 선택하는 이유
거대 서비스가 라이브러리를 그냥 가져다 쓰지 않고 fork(코드를 통째로 복사해 자기 저장소에 넣음) 하는 이유는 명확합니다.
| 동기 | 설명 |
|---|---|
| 통제권 | upstream의 변경 일정에 끌려가지 않고 내 일정으로 패치 |
| 커스텀 패치 | 자사 인프라(로깅, 메트릭, A/B 실험)에 맞춘 hook 삽입 |
| 독자 최적화 | 자체 코덱·스케일러·혼잡 제어를 직접 이식 |
| 빌드 통합 | 거대 monorepo 빌드 시스템에 소스째 편입 |
단기적으로 fork는 일정과 패치를 직접 통제할 수 있습니다.
대신 upstream과의 차이를 관리하는 비용이 누적됩니다.
2. fork의 함정 — upstream과 멀어지는 비용은 복리로 늘어난다
fork의 진짜 비용은 fork하는 순간이 아니라, upstream이 계속 발전하는 동안 발생합니다.
무엇이 비싸지는가
1. 보안 패치 백포팅 upstream이 보안 취약점을 고쳐도, 내 fork에 자동으로 들어오지 않습니다. 수년치 커스텀 변경과 충돌하는 패치를 손으로 병합해야 합니다.
2. 신규 기능 누락 upstream이 AV1, 향상된 혼잡 제어, 새 FEC를 추가해도 내 fork는 옛 버전에 갇힙니다. 받으려면 다시 거대한 rebase.
3. 점점 커지는 diff
변경이 쌓일수록 충돌 후보와 검증 범위가 늘어납니다. 증가율은 패치 결합도와 자동화 수준에 따라 달라지므로 기하급수적이라고 단정하지 않습니다.
비유: fork는 "본가에서 분가해 따로 집을 짓는 것"과 같습니다. 처음엔 자유롭지만, 본가가 수도·전기·보안 시스템을 계속 업그레이드하는 동안 내 집은 그대로입니다. 본가 업그레이드를 가져오려면 매번 벽을 뜯어야 합니다. 기술적으로 환원하면: upstream의 매 커밋이 내 fork의 커스텀 패치와 merge conflict를 일으킬 잠재적 후보이며, conflict 해결 비용은 누적 diff 크기에 비례합니다.
Meta의 실제 상황
Meta는 수년간 운영한 libwebrtc fork를 최신 upstream 기반 모듈형 구조로 옮긴 작업을
Escaping the Fork에 문서화했습니다. 2026년 기준 50개가 넘는 use case가 이 구조를 사용합니다. 공식 글은 정확히 7년이라고 밝히지 않습니다.
이게 fork의 함정입니다. 통제권을 얻는 대신, 시간이 지날수록 "산업 표준의 발전에서 고립"되는 비용을 냅니다.
3. shim 아키텍처 — fork를 빠져나오는 다리
Meta는 오래된 fork를 한 번에 바꾸는 대신 점진적 마이그레이션을 가능하게 하는 중간 레이어(shim)를 만들었습니다.
사실: shim 아키텍처는 Meta 공식 블로그('Escaping the Fork')에 명시적으로 문서화되어 있습니다. shim layer는 'flavor' 설정을 들고 있다가 런타임에 각 호출을 legacy WebRTC 또는 최신(upstream) WebRTC 구현 중 하나로 dispatch합니다.
shim이 푸는 문제 — 두 버전 공존
마이그레이션 기간에는 옛 fork와 새 upstream이 한 바이너리 안에 동시에 존재해야 합니다. 그런데 둘 다 namespace webrtc { ... }를 씁니다. 같은 심볼이 충돌합니다.
Meta는 자동화된 renamespacing으로 이를 갈랐습니다.
그리고 호출부는 webrtc::를 직접 부르지 않고 shim을 거칩니다.
왜 이게 안전한가
| 항목 | big bang 교체 | shim 점진 교체 |
|---|---|---|
| 전환 단위 | 전부 한 번에 | use case 하나씩 (flavor 토글) |
| 롤백 | ❌ 거의 불가능 | ✅ flavor만 되돌리면 됨 |
| 두 버전 공존 | ❌ 불가 | ✅ renamespacing으로 가능 |
| 위험 노출 | 수십억 통화 동시 | 소수 트래픽부터 점진 |
비용 문제 — 바이너리 크기
두 버전을 다 넣으면 바이너리가 뚱뚱해집니다. 모바일 앱에서 이건 심각한 문제(다운로드/메모리)입니다.
사실: Meta는 두 버전을 그대로 모두 포함하면 바이너리가 약 38MB 늘 것을, shim 설계로 약 5MB 수준으로 억제했다고 기술했습니다. 또한 shim 생성을 AST(Abstract Syntax Tree) 기반 자동 코드 생성으로 자동화해, 수작업이라면 하루 1개 수준이던 shim 생성을 하루 3~4개로 끌어올렸습니다.
비유: shim은 "통역사를 가운데 두고 옛 직원과 새 직원을 한 사무실에서 동시에 일하게 하는 것"입니다. 기술적으로 환원하면: shim은 호출 인터페이스를 안정적으로 고정한 채(애플리케이션은 shim API만 봄), 뒤에서 실제 구현(legacy/latest)을 런타임 설정으로 교체하는 indirection layer입니다. 즉 fork 교체를 "코드 수정"이 아니라 "설정 토글" 문제로 바꿉니다.
"버전 독립을 위해 호출부와 구현 사이에 indirection을 둔다"는 일반적인 adapter 접근을 Meta의 monorepo 규모에 맞게 자동화한 사례입니다.
4. 공개된 최적화 영역 — AV1 적용과 비디오 스케일러
fork/shim은 엔진 관리 방식의 이야기입니다. 미디어 처리에서는 AV1 적용과 비디오 스케일러 최적화가 공식 문서로 확인됩니다.
AV1 도입 — royalty-free가 핵심 동기
Meta는 모바일 RTC에 AV1을 도입했습니다. 2024년 글은 경량 품질 지표에서 H.264 대비 약 2dB 향상을, 2026년 글은 해당 제품·테스트 설정에서 H.264 대비 최소 20%의 비트레이트 절감을 보고합니다. 이 수치는 모든 영상과 기기에 적용되는 보편값이 아닙니다.
AV1은 Alliance for Open Media가 개발한 royalty-free 코덱입니다. Meta는 코덱 라이선스와 동시 사용료를 선택 기준 가운데 하나로 언급했습니다.
Meta는 라이선스 고려가 중요했다고 밝혔지만 구체적인 절감액은 공개하지 않았습니다. 공개되지 않은 절감액이나 특정 H.264 연간 상한을 Meta의 성과로 연결하지 않습니다.
AV1의 트레이드오프 — 공짜 점심은 없다
AV1은 품질은 좋지만 비쌉니다.
| 항목 | 효과 | 트레이드오프 |
|---|---|---|
| 압축 효율 | Meta 테스트에서 품질·비트레이트 개선 | 콘텐츠·설정에 따라 결과 변동 |
| 라이선스 | AOMedia가 royalty-free로 제공 | 구현·특허 정책은 조직의 법무 검토 필요 |
| 연산량 | 저복잡도 인코더와 dav1d 디코더를 적용 | 기기 capability와 전력 측정 필요 |
| 기기 적용 | H.264와 AV1을 협상 | 기기별 지원·성능에 따라 선택 |
AV1은 모든 기기에 고정 적용하지 않고 H.264와 함께 capability와 제품 정책에 따라 협상합니다.
자체 비디오 스케일러
사실: Meta는 커스텀 비디오 스케일러를 개발해, 공개 테스트에서 PSNR 평균 0.75dB 이득을 보고했습니다. 이는 표준 스케일러 대비 우수한 성능으로 기술됩니다.
스케일러는 인코딩 전 해상도를 줄이거나 키울 때 쓰는 모듈입니다. 저대역폭 사용자에게 보내는 저해상도 영상의 품질을 좌우합니다. Meta는 여기에 콘텐츠 인식 인코딩(얼굴 영역 우선, Region-of-Interest)을 결합했습니다.
정정 — libyuv 대체 범위: Meta 원문은 커스텀 스케일러의 PSNR +0.75dB가 WebRTC 기본 libyuv box filter 대비라고 명시합니다. 다만 libyuv를 전면 대체했는지(부분 보강인지)까지는 단정하지 않습니다.
5. P2P → 미디어 서버 전환 — 어디까지가 사실인가
"수십억 통화"라면 당연히 거대한 미디어 서버 인프라가 있을 것 같습니다. 여기서는 확인되는 것과 확인되지 않는 것을 엄격히 구분합니다.
확인되는 것 — Rsys signaling 통합
사실: Meta는 2020년 Rsys라는 RTC 아키텍처 재구성을 문서화했습니다(engineering.fb.com, 2020-12). Rsys는 **1:1 통화와 그룹 통화를 하나로 통합한 '상태 머신 기반 signaling 아키텍처'**입니다.
이 자료에서 확인되지 않는 것 — 전 세계 SFU 인프라
이 글이 인용한 Rsys와
Escaping the Fork는 전 세계 SFU 배포 구조를 설명하지 않습니다. 따라서Meta가 P2P에서 SFU로 전환해 전 세계에 미디어 서버를 배포했다는 단락은 삭제하고, Rsys에서 확인되는 signaling 통합만 기술합니다.
| 주장 | 판정 | 근거 |
|---|---|---|
| Rsys로 1:1/그룹 signaling 통합 | ✅ 확인됨 | engineering.fb.com Rsys(2020) |
| P2P → SFU 전환 | 이 글에서는 다루지 않음 | 인용한 공식 문서에 구체적 기술 없음 |
| 전 세계 SFU 인프라 배포 | 이 글에서는 다루지 않음 | 상동 |
참고로 SFU가 무엇이고 왜 필요한지는 일반 RTC 토폴로지 지식입니다.
다만 위 SFU 다이어그램은 일반 원리이며, Meta가 정확히 이 토폴로지를 전역 배포했다는 근거는 아닙니다.
6. 업계 지형 — 다른 벤더들은 어디서 출발했나
Meta의 선택을 맥락에 놓으려면 동종 벤더와 비교하는 게 유용합니다. "대부분 libwebrtc에서 출발했다"는 큰 틀은 맞지만, '모두'는 아닙니다. 정정 포인트가 많아 표로 정리합니다.
| 벤더 | 기반 | 정정/주의 |
|---|---|---|
| Agora | 공개 제품 문서 기준으로 평가 | 비공개 코어 구현은 단정하지 않음 (#43) |
| Twilio Video | WebRTC 서비스 | EOL 발표를 번복했고 현재 공식 FAQ는 active development로 설명 |
| LiveKit | Go 기반 Pion WebRTC (C++ libwebrtc 아님) | ⚠️ SFU 서버는 Go. Rust는 일부 SDK 레벨, 핵심 서버는 Go |
| Daily | WebRTC 서비스 | 공식 room API에 P2P/SFU 전환 설정이 공개됨 |
| Zoom | 제품별 공식 문서 확인 | 비공개 미디어 스택과 WebAssembly 인코더 주장은 제외 |
| Discord | 제품별 공식 문서 확인 | Read States의 Rust 전환을 음성 엔진으로 확대 해석하지 않음 |
| Slack Huddles | Amazon Chime SDK | ✅ AWS 파트너십, Chime Transcribe로 캡션 |
특히 강조할 정정 3가지
"Discord가 미디어 엔진을 Rust로 재작성했다"는 근거 없음
Discord 공식 글의 Go→Rust 재작성 대상은 Read States 서비스입니다. 음성 미디어 엔진과는 다른 컴포넌트이므로 음성 스택의 언어·SFU 구현까지 추론하지 않습니다.
"LiveKit은 Rust/libwebrtc 네이티브" → 부정확
정정: LiveKit SFU 서버는 Go(Pion WebRTC 기반)입니다. C++ libwebrtc 기반이 아닙니다. Rust 컴포넌트는 일부 SDK 수준에서 존재하지만 핵심 서버의 언어는 Go입니다.
"Twilio Video는 2024년 종료됐다" → 현재 사실이 아님
정정: EOL 발표는 있었으나 이후 번복되었습니다. 2024-10 Twilio가 Twilio Video 지속 투자를 재공표했습니다. 최종 상태는 '종료'가 아니라 '결정 역행(reversal)'입니다.
큰 그림 — 차별화는 코덱이 아니라 네트워크
RTC 제품은 코덱뿐 아니라 SFU 토폴로지, 지역 네트워크, 운영 도구, 적응형 비트레이트, 확장성과 비용에서 차이가 납니다. 어떤 요소가 중요한지는 워크로드로 검증해야 합니다.
Meta의 AV1 자체 개발이 흥미로운 건, 바로 이 "코덱은 별 차별화 안 된다"는 통념의 예외라는 점입니다. Meta 규모에서는 코덱의 라이선스·압축률·CPU가 곧 인프라 비용이라, 코덱 자체가 다시 차별화 영역이 됩니다.
7. 그래서 Meta 사례에서 배울 것 — 의사결정 체크리스트
Meta의 여정은 "fork할 것인가, upstream을 따를 것인가"라는 모든 인프라 팀의 질문에 데이터를 줍니다.
핵심 교훈 카드
| 교훈 | 한 줄 |
|---|---|
| fork는 부채다 | 통제권을 얻는 대신 upstream 고립 비용을 복리로 지불 |
| indirection이 탈출구다 | shim/adapter로 "코드 교체"를 "설정 토글"로 전환 |
| 자동화가 규모를 만든다 | AST 기반 코드 생성으로 shim 생성 1→3~4개/일 |
| 코덱도 비용 변수다 | 품질·연산량·라이선스·기기 지원을 제품 규모에서 평가 |
| 공개 자료의 한계를 인정하라 | SFU 인프라처럼 "그럴듯하지만 미문서화"인 영역 구분 |
8. 한 줄 결론
Meta는 오래된 libwebrtc fork를 shim·자동 renamespacing·점진적 검증으로 최신 upstream 기반 모듈형 구조에 옮겼다. upstream을 골격으로 쓰면서도 핵심 구성요소에는 자체 구현과 패치를 주입한다. AV1은 AOMedia가 만든 코덱이며, Meta의 공개 성과는 모바일 RTC용 저복잡도 구현과 커스텀 스케일러다. 전 세계 SFU 배포나 구체적인 라이선스 절감액은 인용한 공식 자료가 확인하지 않는다.
관련 글
- #43 Agora 자체 코덱 vs Web SDK — SD-RTN과 FEC의 실체 — "코덱 레이어 vs 네트워크 레이어" 분리 관점, Meta 사례와 직접 대비
- #40 라이브 스트리밍 프로토콜 선택 — HLS / LL-HLS / WebRTC — WebRTC가 어느 위치에 있는지
- #28 H.264 Profile·인코더 옵션·비트레이트의 현실 — 코덱 트레이드오프(AV1 vs H.264 맥락)
- #23 오디오 파이프라인 — Opus / RTP / Jitter Buffer — libwebrtc가 내장한 미디어 처리 스택
- #0 WebRTC란? ICE? STUN? NAT? TURN? — libwebrtc가 추상화하는 기본 구조
참고 자료
- Escaping the Fork: How Meta modernized WebRTC across 50 use cases (engineering.fb.com, 2026-04) — shim 아키텍처·renamespacing·AST 자동화 원문
- Rsys: Meta's RTC architecture (engineering.fb.com, 2020-12) — signaling 통합 (SFU 인프라는 미문서화)
- Bringing AV1 to RTC video for HD on mobile (engineering.fb.com, 2024-03) — AV1 도입·커스텀 스케일러·라이선스 동기
- Adopting AV1 for RTC at Meta (engineering.fb.com, 2026-06) — 저복잡도 인코더·dav1d·제품 조건의 비트레이트 비교
- How AV1 powers Facebook & Instagram Reels (engineering.fb.com, 2023-02) — AV1 채택 배경
- Why Discord is switching from Go to Rust — 정정 근거: Rust 재작성 대상은 'Read States'
- LiveKit SFU internals — 정정 근거: SFU 서버는 Go(Pion)
- Twilio Programmable Video End-of-Life Notice — 정정 근거: EOL 번복
- Slack & Amazon Chime SDK (AWS Blog) — Slack Huddles 기반
- WebRTC.org / libwebrtc — 공통 출발점인 오픈소스 구현