1. WebRTC 与视频编码概述

各位同学好,我是老张。今天咱们正式开始这门课的第一章。说实话,WebRTC 和视频编码这个话题,我做了快十年,踩过的坑能写满一个笔记本。但别担心,我会把这些经验揉碎了讲给你听。

这一章,我们先搭个框架。搞清楚 WebRTC 到底怎么工作的,视频编码在里面扮演什么角色,以及 H264 和 H265 这两个老冤家到底差在哪。

1.1 WebRTC 架构简介

WebRTC,全称是 Web Real-Time Communication。说白了,就是让浏览器之间能直接视频通话、传文件,不用装任何插件。我当年第一次接触它,就觉得这东西太酷了。

它的核心架构,我习惯分成三层来看:

  • API 层:给开发者用的接口,比如 getUserMedia、RTCPeerConnection、RTCDataChannel。你调这些接口,就能拿到摄像头数据、建立连接、传文件。
  • 引擎层:这是 WebRTC 的心脏。包括视频引擎、音频引擎、网络传输引擎。编码、解码、丢包重传、抖动缓冲,全在这层处理。
  • 底层:硬件抽象、网络 I/O、加密。这些你平时看不见,但出了问题往往就是它们搞的鬼。

嗯,这里要注意。很多初学者以为 WebRTC 只是一个 API,其实它是一整套实时通信的解决方案。我见过有人自己写 UDP 传输层,然后问为什么 WebRTC 连不上——兄弟,你这是在重复造轮子啊。

核心要点:WebRTC 的架构设计目标就是「低延迟、高可靠」。视频编码模块就嵌在引擎层里,直接决定了通话的画质和流畅度。

下面这张图,是我自己画的 WebRTC 架构简图。你看一眼,心里有个数就行。

WebRTC 架构分层图 API 层 getUserMedia | RTCPeerConnection | RTCDataChannel 媒体流获取 | 连接建立 | 数据通道 引擎层(核心) 视频引擎 编码/解码/Jitter Buffer 音频引擎 编码/解码/回声消除 网络传输引擎 ICE/DTLS/SRTP/拥塞控制 底层 硬件抽象层 | 网络 I/O | 加密(SSL/TLS) 摄像头/麦克风驱动 | UDP/TCP 套接字

1.2 视频编码在实时通信中的角色

你想想看,如果没有视频编码,摄像头采集到的原始数据直接通过网络传出去,会是什么结果?

我算给你看。一个 1080p 的画面,30 帧每秒,每帧 1920×1080×3 字节(RGB),算下来每秒的数据量是:

1920 × 1080 × 3 × 30 ≈ 186 MB/s

186 MB 每秒!普通家庭宽带的上传速度也就 5-10 MB/s。这还没算音频和信令。所以,视频编码不是「要不要」的问题,而是「必须做」的问题。

视频编码在 WebRTC 里干三件事:

  1. 压缩:把原始视频数据压缩到原来的 1/100 甚至 1/1000。H264 和 H265 干的就是这个活。
  2. 抗丢包:实时通信的网络环境很复杂,丢包是家常便饭。编码器可以通过 NAL 单元分割、参考帧管理,让丢包的影响降到最低。
  3. 码率自适应:网络带宽是动态变化的。编码器需要根据当前带宽,动态调整编码参数。带宽高了用高码率,带宽低了降分辨率或帧率。

我的经验:我在项目中遇到过最头疼的问题,就是编码器在带宽波动时反应太慢。用户那边网络突然变差,画面直接卡死。后来我调整了码率控制策略,把响应时间从 2 秒降到了 500 毫秒,体验好了很多。

1.3 H264 与 H265 的核心差异

H264 和 H265,都是视频编码标准。H264 是 2003 年发布的,H265 是 2013 年发布的。差了十年,技术自然有代差。

我直接给你上表格,对比最核心的几个维度:

对比维度 H264 (AVC) H265 (HEVC)
发布年份 2003 2013
压缩效率 基准 同等画质下码率降低 30%-50%
编码单元 宏块(16×16 像素) 编码树单元 CTU(最大 64×64)
帧内预测 9 种模式 33 种模式 + 平面模式
运动补偿 1/4 像素精度 1/4 像素 + 1/8 像素精度
并行处理 Slice 级 Tile + WPP(波前并行)
硬件支持 几乎所有设备 较新设备(iPhone 6+、Android 7+)
专利许可 成熟,费用明确 复杂,存在专利池争议

你看这个表格,H265 在压缩效率上明显领先。但为什么 WebRTC 里 H264 还是主流?

原因有两个:

  • 硬件兼容性:H264 的硬件编码器几乎覆盖了所有手机、电脑、摄像头。H265 的硬件支持还在普及中,很多老设备不支持。
  • 专利问题:H265 的专利授权非常混乱。有好几个专利池,收费也不透明。很多公司因为法律风险,不敢在商业产品里用 H265。

避坑指南:我曾经在一个项目中,为了追求画质,强行上了 H265。结果测试时发现,用户的旧款 Android 手机不支持 H265 硬编,只能用软编,CPU 直接跑满,手机烫得能煎鸡蛋。最后不得不回退到 H264。

不过,H265 的优势也是实打实的。在同等码率下,H265 的画面更清晰。对于带宽有限的场景(比如 4G/5G 移动网络),H265 能省下 30%-50% 的带宽。

下面这张图,展示了 H264 和 H265 在编码单元上的核心差异:

H264 vs H265 编码单元对比 H264:固定宏块 16×16 16×16 H265:编码树单元 CTU 最大 64×64 64×64 H265 的 CTU 可以递归分割为更小的 CU(32×32、16×16、8×8),灵活性更高

你看,H264 的宏块大小是固定的 16×16。而 H265 的 CTU 最大可以到 64×64,还能递归分割。这意味着什么?

对于平坦区域(比如天空、白墙),H265 可以用大块编码,省码率。对于细节丰富的区域(比如人脸、文字),H265 可以切小块,保留细节。这种灵活性,是 H265 压缩效率高的关键原因之一。