-
Notifications
You must be signed in to change notification settings - Fork 2
Platform layers
WebRTC is not one library built six ways. It is a shared C++ core, a native media layer aimed at desktop, and an integration layer that only some platforms receive. What a platform can do depends on which of those three reaches it — and on who compiled it.
This page records what is actually inside each artifact, so nobody has to rediscover it by debugging a null factory at run time.
Everything below was verified against a real branch-heads/7977 (Chromium M152) checkout and, where
stated, against the compiled Windows output — not from documentation.
| Tier | What it is | Where it lives |
|---|---|---|
| 3 | Integration layer — language bindings, hardware codecs, capture, rendering |
sdk/, or the host application |
| 2 | Native media I/O — microphone, camera, screen capture | modules/ |
| 1 | Core engine — transport, RTP, bandwidth estimation, software codecs, APM |
api/, pc/, call/, media/
|
Which layers each platform actually receives:
Regenerate with python tools/make_platform_diagram.py in the main repository after changing the
data; the two SVGs are build output, not hand-edited.
The same thing grouped by the four distinct stack shapes, for anyone who prefers a source form they can edit in place:
flowchart TB
subgraph MOBILE["📱 Android · iOS · Mac Catalyst"]
direction TB
M3["<b>Tier 3</b> — sdk/android, framework_objc<br/>hardware codecs · camera · renderer · bindings"]
M1["<b>Tier 1</b> — core engine"]
M3 --- M1
end
subgraph DESK["🖥 Windows · Linux"]
direction TB
D2["<b>Tier 2</b> — modules/<br/>audio · camera · screen capture"]
D1["<b>Tier 1</b> — core engine"]
D2 --- D1
end
subgraph WEB["🌐 Web"]
direction TB
W3["<b>Tier 3</b> — the browser<br/>Chromium //media · WebKit · Gecko"]
W1["<b>Tier 1</b> — core engine"]
W3 --- W1
end
The Apple platforms, Android and the Web sit on tier 3; Windows and Linux sit on tier 2. In table form:
| Tier | Android | iOS | Mac Catalyst | Windows | Linux | Web |
|---|---|---|---|---|---|---|
| 3 Integration | yes | yes | yes | being built here | none upstream | the browser |
| 2 Native media I/O | — | — | — | yes | yes | screen capture only |
| 1 Core engine | yes | yes | yes | yes | yes | yes |
Tier 2 being blank on the Apple and Android columns is not a gap. They do the same job in tier 3:
modules/audio_device/ contains win/, mac/ and linux/ and no mobile directories, because
iOS pulls sdk:audio_device instead. Same responsibility, different layer.
Mac Catalyst is an iOS app running on a Mac, so it is built with the iOS toolchain and everything true of iOS below is true of Catalyst — except screen capture, which WebRTC gates on being a Mac rather than on running on one. It has its own workflow and binding project all the same.
Native columns describe the artifacts this repository produces today, not WebRTC's full potential.
| Capability | Android | iOS | Mac Catalyst | Windows | Linux | Web |
|---|---|---|---|---|---|---|
| Transport, RTP, bandwidth estimation | yes | yes | yes | yes | yes | yes |
| VP8 · VP9 · AV1 · Opus | yes | yes | yes | yes | yes | yes |
| Software AEC · NS · AGC | yes | yes | yes | yes | yes | yes |
| Microphone / speaker | SDK | SDK | SDK | core | core | browser |
| Camera capture | SDK | SDK | SDK | core | core | browser |
| Screen & window capture | none | none | none | core | core | browser |
| Hardware echo cancellation | yes | yes | yes | none | none | browser |
| H.264 | hardware | hardware | hardware | none | none | yes |
| Hardware video encode / decode | MediaCodec | VideoToolbox | VideoToolbox | none | none | GPU process |
| Video renderer | EGL | Metal | Metal | none | none | <video> |
| High-level API bindings | Java | Obj-C | Obj-C | WebRtcInterop | C++ only | JavaScript |
"none" means the capability does not exist for that platform upstream. Screen capture is absent on
the Apple and Android columns because rtc_desktop_capture_supported excludes them by definition —
Mac Catalyst counts as iOS there, not as a Mac.
| Platform | Compiled by | Artifact | Reaches WebRTCme as |
|---|---|---|---|
| Android | this repository | libwebrtc.aar |
Java bindings |
| iOS | this repository | WebRTC.xcframework |
Objective-C bindings |
| Mac Catalyst | this repository |
WebRTC.xcframework (Catalyst slices) |
Objective-C bindings |
| Windows | this repository | webrtc.dll |
P/Invoke |
| Linux | this repository | libwebrtc.so |
P/Invoke |
| Web | Google · Mozilla · Apple | the browser binary | JSInterop over RTCPeerConnection
|
Mac Catalyst has its own workflow and its own binding project, even though it is built with the
iOS toolchain — WebRtcNativeMacCatalystLib runs the same build_ios_libs.py with
--arch catalyst:arm64 catalyst:x64. Dispatch it and the iOS workflow against the same
webrtc_branch, or they can land on different milestones.
A libwebrtc.dylib for native macOS is also built, but nothing consumes it — WebRTCme targets
net10.0-maccatalyst, not net10.0-macos. Those workflows are kept as a check that the tree still
builds on Apple silicon.
Chrome and Edge compile this tree as part of Chromium. Firefox maintains its own embedding —
build_with_mozilla guards appear in 9 build files. Safari uses WebKit's fork. There is no wasm or
web target in WebRTC; browsers compile the same C++ natively and expose it through the W3C API,
which is why WebRTCme.Bindings.Blazor wraps JavaScript rather than shipping a binary.
This is upstream's deliberate design, not neglect.
On desktop, WebRTC's consumer is Chrome, which supplies capture, rendering and hardware codecs from
Chromium's own media stack. Building a second one inside WebRTC would be duplicated work that
nobody would use. 133 build files carry build_with_chromium conditionals — the browser is not one
more target, it is the one this tree is written for.
The mobile SDKs exist because Google ships them as products to third-party app developers. No equivalent native desktop SDK was ever needed, so none was written.
The Web column is what the missing tier 3 looks like when someone does build it.
One flag separates them:
if (build_with_chromium) {
rtc_use_h264 = media_use_openh264 # the browser gets H.264
} else {
rtc_use_h264 = proprietary_codecs && ... # false outside branded Chrome
}
So OpenH264 is never compiled into our desktop libraries — confirmed empirically: 0 openh264
objects in the Windows build. The DLL still exports 26 H.264 symbols for SDP negotiation,
profile-level-id matching and RTP packetization, so the API looks alive, but
modules/video_coding/codecs/h264/h264.cc:174 is return nullptr. Every H.264 factory returns
null.
Consequence: desktop peers cannot interoperate over H.264 with Safari, with hardware-only endpoints, or with SFUs on their H.264 path. Blazor users are unaffected — the browser has it.
Enabling it means setting proprietary_codecs=true, which carries MPEG-LA licensing implications
for whoever distributes the result. That is a deliberate decision, not a build tweak.
Every other column reaches tier 3 somehow — Android and the Apple platforms through sdk/, the Web
through the browser. Windows and Linux have no sdk/ target upstream and no host to supply one, so
they stop at the core plus native media I/O.
That is what WebRtcInterop.dll is: the missing tier 3, built here rather than by Google.
Interop ABI is its contract, and it is partially implemented — Windows is the one
column in the figure whose tier 3 is our own work in progress rather than someone else's finished
product. Linux keeps the gap until the same shim is built for it.
The one capability desktop has and mobile does not. rtc_desktop_capture_supported is defined as
Windows, macOS and Linux (with X11 or PipeWire), explicitly excluding mobile. Confirmed: 61
desktop_capture objects in the Windows build.
Against a synced checkout:
# which platforms have native camera capture
ls modules/video_capture/ # linux, windows -- no mac
# which platforms have a native audio device module
ls modules/audio_device/ # linux, mac, win -- no mobile
# is H.264 compiled in?
find out/Default/obj -path '*openh264*' -name '*.obj' | wc -l # 0
# what the mobile scripts build
sed -n '41,45p' tools_webrtc/android/build_aar.py
grep -n 'framework_objc' sdk/BUILD.gn- Consuming the artifacts — wiring each artifact into WebRTCme
- Prebuilt distributions — other projects that build WebRTC
- Workflow reference — what each workflow builds
Using it
Building on it
Reference
When it breaks