采集与编码器输入 · Source、Sink 与 VideoStreamEncoder

摄像头怎么把帧喂给编码器?靠 source/sink 接口。这一章读 video/video_stream_encoder.h:VideoStreamEncoder 作为帧的 sink 接收采集、SetSource 绑定视频源、以及它在把帧交给编码器前做的第一道处理(丢帧、格式转换)。

作者 David更新于 第 53 篇(共 112 篇)

采集与编码器输入 · Source、Sink 与 VideoStreamEncoder

视频帧从摄像头产出后,怎么流到编码器?WebRTC 用一对简洁的接口连接「帧的生产者」和「消费者」,而消费的核心是 VideoStreamEncoder(video/video_stream_encoder.h)。这一章看这个入口。

Source 与 Sink:生产者与消费者

WebRTC 用 source / sink 模式连接视频的生产和消费(api/video/):

  • VideoSourceInterface<VideoFrame>(源) —— 帧的生产者:摄像头、屏幕采集、测试图案生成器……凡是「能产出帧」的都是 source。
  • VideoSinkInterface<VideoFrame>(汇) —— 帧的消费者:通过 OnFrame(frame) 接收帧。编码器、本地预览都是 sink。

VideoStreamEncoder 本身就是一个 sink——它 SetSource 绑定一个视频源,之后源每产一帧,就通过 OnFrame 推给它:

// video/video_stream_encoder.h(节选)
void SetSource(VideoSourceInterface<VideoFrame>* source,
               const DegradationPreference& degradation_preference) override;

注意 SetSource 的第二个参数 DegradationPreference——它一开始就定下了「网络 / CPU 不够时,这条流优先牺牲什么」。 降分辨率还是降帧率,取决于内容:讲课 / 共享屏幕(细节重要)宁可降帧率保清晰,视频通话(动作重要)宁可降分辨率保流畅。这个偏好在绑定源时就传入,是下一步自适应的依据。source/sink 这层抽象还带来一个好处:采集源可以随意替换(摄像头、屏幕、虚拟背景处理后的帧……),VideoStreamEncoder 不关心帧从哪来,只管消费——又是 WebRTC 解耦哲学的体现。

进编码器前的第一道处理

帧到了 VideoStreamEncoder,不是直接扔进编码器,中间还有几道处理:

  • 帧率控制 / 丢帧 —— 如果目标帧率低于采集帧率(比如摄像头 30fps,但当前只编 15fps),就丢掉一半的帧,别浪费 CPU 编了又不发。源头丢帧比编码后丢经济得多。
  • 格式转换 —— 把采集的格式(NV12、RGB 等)转成编码器要的 I420。
  • 分辨率缩放 —— 若自适应要求降分辨率,在这里把帧缩小。
  • 过载保护 —— 如果编码器忙不过来(CPU 跟不上),丢帧或降质,别让队列堆积、延迟爆炸。

VideoStreamEncoder 是「编码前的调度中枢」——它决定每一帧是编、是丢、还是缩,再交给底层编码器。 这个位置极关键:它把「摄像头恒定产帧」和「网络 / CPU 能承受多少」之间的鸿沟填平。摄像头不管网络好坏都按 30fps 产帧,但网络可能只够 15fps、CPU 可能只够编 720p——VideoStreamEncoder 就在这里做取舍:丢掉多余的帧、缩小过大的帧、跳过编不过来的帧。它是码率 / 分辨率 / 帧率自适应的执行现场,下一章专讲这套自适应逻辑。

在管线里的位置

图表加载中…

VideoStreamEncoder 一手连着采集源,一手连着编码器,中间接收拥塞控制的码率指令,做出「这一帧怎么处理」的决策。

小结与下一章

WebRTC 用 source/sink 连接帧的生产与消费:视频源 VideoSourceInterface 产帧,VideoStreamEncoder(一个 sink)SetSource 绑定源、OnFrame 收帧,绑定时传入 DegradationPreference(定优先降什么)。进编码器前,VideoStreamEncoder 做帧率控制 / 丢帧、格式转 I420、缩放、过载保护——它是「编码前的调度中枢」,填平「摄像头恒定产帧」与「网络 / CPU 能承受多少」的鸿沟。

帧准备好了,交给编码器。下一章看统一的 VideoEncoder 抽象,以及 VP8/VP9/AV1/H264/H265 这些编解码器。👉 编码器抽象与编解码器。

参考资料

  • [1] libwebrtc 源码.video/video_stream_encoder.h(SetSource、OnFrame)、api/video/video_source_interface.h、video_sink_interface.h。
  • [2] libwebrtc 源码.api/video/video_stream_encoder_interface.h。
  • [3] 关联自适应、g3doc/adaptation.md。

本页目录