Call 对象 · 一次通话的媒体中枢
PeerConnection 管控制面,Call 管媒体面——它是所有发送流/接收流的中枢,也是拥塞控制的宿主。这一章读 call/call.h:Call 怎么创建和管理 AudioSendStream/VideoReceiveStream,以及它为什么活在 worker 线程。
Call 对象 · 一次通话的媒体中枢
前八部分,我们从会话协商一路走到音视频数据的收发。第 9 部分退后一步,看统管媒体面的中枢——Call(call/call.cc)。早在第 1 部分它就作为 PeerConnection 的 call_ 成员出现过,现在细看它。
Call:媒体流的中枢
PeerConnection 管控制面(SDP 协商、ICE/DTLS),而 Call 管媒体面——一次通话里所有的发送流和接收流,都由它创建和管理。看它的接口(call/call.h):
// call/call.h(节选)
class Call {
virtual AudioSendStream* CreateAudioSendStream(...);
virtual VideoSendStream* CreateVideoSendStream(...);
virtual VideoReceiveStreamInterface* CreateVideoReceiveStream(...);
// 以及 AudioReceiveStream、FlexfecReceiveStream 等
};Call 是“一次通话”在媒体层面的化身——它是所有音视频流的工厂 + 容器 + 协调者**。** 协商出要发一路视频、收一路音频,PeerConnection 就让 Call 创建对应的 VideoSendStream、AudioReceiveStream。这些流由 Call 拥有、生命周期随通话。为什么要一个中枢来管、而不是各流自治?因为这些流共享资源、需要协调:
- 共享带宽 —— 所有发送流共用一个总带宽预算,要统一分配(音频优先)。
- 共享拥塞控制 —— 一套 GoogCC 服务所有流(而非每流一个)。
- 共享传输 —— BUNDLE 下所有流走一条传输。
Call 就是这个“协调共享资源”的中枢——它持有拥塞控制的总控 RtpTransportControllerSend 和码率分配器 BitrateAllocator,让所有流在统一的资源框架下协作。
Call 活在 worker 线程
呼应第 1 部分:call_ 成员带着 RTC_GUARDED_BY(worker_thread())——Call 及其媒体流活在 worker 线程。这符合三线程分工:worker 线程管“媒体处理”,而 Call 正是媒体处理的中枢。编解码、码率分配、拥塞控制这些计算,都在 worker 线程上跑;而实际的包收发会派发到 network 线程。PeerConnection 的控制面在 signaling 线程、Call 的媒体面在 worker 线程——两者通过跨线程派发协作。
Call 持有什么
Call 是个“大管家”,它持有一次通话媒体面的关键部件:
| Call 持有 | 干什么 | 本教程 |
|---|---|---|
| 各 SendStream / ReceiveStream | 音视频收发管线 | 第 6/7 部分 |
RtpTransportControllerSend | 发送侧传输控制(含拥塞控制、pacer) | 下一章 |
BitrateAllocator | 总码率在各流间分配 | 第 9 部分 |
于是数据流是这样:协商 → Call 建流 → 流用编解码器(由媒体引擎提供)编解码 → RtpTransportControllerSend 的拥塞控制 + pacer调度发送 → network 线程发包。Call 站在这一切的中心。
谁调用 Call
Call 不直接面对应用,而是被上层驱动:PeerConnection 的各组件(channel、transceiver)根据协商结果,调 Call 建流、配流。可以说 Call 是会话协商(“发什么、怎么发”)和实际媒体管线(“真的发”)之间的执行层——控制面谈定的东西,在 Call 这里变成真正跑起来的媒体流。
小结与下一章
Call(call/call.cc)是一次通话的媒体中枢——所有音视频发送 / 接收流的工厂 + 容器 + 协调者(CreateAudioSendStream 等)。它统管的原因是这些流共享带宽 / 拥塞控制 / 传输,需要中枢协调——它持有RtpTransportControllerSend(拥塞控制 + pacer)和 BitrateAllocator。Call 活在 worker 线程(媒体处理),与 signaling 线程的控制面协作。它是会话协商到媒体管线之间的执行层。
Call 持有的拥塞控制总控 RtpTransportControllerSend 是发送侧的神经中枢。下一章看它。👉 RtpTransportControllerSend。
参考资料
- [1] libwebrtc 源码.
call/call.h/call.cc(Call、CreateAudioSendStream等)。 - [2] libwebrtc 源码.
call/call_factory.cc、api/call/。 - [3] 关联PeerConnection 的 call_ 成员、线程模型。