2023 年 9 月论文笔记

博士生涯正式开始了,首先先看看论文吧。

Nebula - Reliable Low-latency Video Transmission for Mobile Cloud Gaming

Introduction

云游戏(Mobile Cloud Gaming / MCG)系统的目标是高质量传输游戏内容,一般而言具有下列特征:

  • 轻量级的客户端(手机等终端)
  • 相对重量级的云端服务器
  • 分布广泛但是具有不可预测性的移动网络

现行的云游戏系统往往针对家用定点游戏(原文是 sedentary gaming at home,我猜是类似主机游戏或者用户一般不会到处走动的手游),这类云游戏系统往往通过 WebRTC 等协议实现较低传输延迟,然而可能会导致较低的画质,从而影响 QoE。但是移动网络的带宽不确定性、丢包率高、公网传输不稳定等问题也是一大挑战。

目前,ABR 算法常用于应对带宽波动,FEC(Forward Error Correction,前向纠错)算法常用于应对丢包。然而,ABR 受限于难以精确预测可用带宽,FEC 受限于较高的成本。此外,这两类算法也较少同时使用。

然后就是本文:

In this paper, we introduce Nebula, the first end-to-end framework combining (1) video distortion propagation modelling with (2) adaptive frame-level FEC and (3) joint video encoding bitrate and (4) FEC redundancy control for MCG over mobile networks (see Figure 1).

说实话四层 buff 确实让人看得有点迷糊。

Nebula 的基础是对误差在多个游戏帧之间的传播情况建模,以考虑视频信号的失真情况。这种方案相较于直接在整组图片(Group of Pictures / GoP)上应用 FEC,Nebula 使用了帧级别的 FEC,从而 GoP 中的帧将会按照时间顺序的接近程度被不同程度地保护。这是显然的,因为 Nebula 毕竟考虑的是错误传播,越远的帧上的错误传播情况自然更加难以把握。这样的操作可以尽可能压缩端到端传输延迟,并且显著减少错误在 GoP 之中的传播。此外,Nebula 显然也采用了一些用来应对带宽波动的算法,但是这显然不是文章的重点。

采用的 baseline 有标准 TCP Cubic based、标准 WebRTC based、BO 和 ESCOT。具体的一些评估还是看后面具体叙述吧。

这一部分不局限于云游戏,还一并叙述了实时视频传输场景的一些工作(Question #1 - 实时视频传输是不是指的是直播场景呢?)。

首先是简单讲了一下实时视频传输场景的工作,首先讨论了聚焦于 FEC 算法的工作。本文指出这些工作虽然成功通过 FEC 实现了较为可靠的传输,但是难以满足低延迟的要求。在 FEC 算法之外,本文讨论了常见的实时视频传输场景中的常用算法架构。首先 WebRTC 偏好降低延迟以实现实时传输而非提高画质,此外 TCP Cubic 等方法并不将延迟纳入考虑,这些算法或多或少的偏颇考量导致了这些方法难以做到两全。

而和云游戏相关的工作本文似乎并没有介绍很多,但是点出了这么一句话:

A few works target specifically MCG due to its novelty.

感觉和学长和我说的“现在云游戏相关的论文好发表”有一种异曲同工之妙。

文章之中所有和云游戏相关的工作都是采用了 GoP-level FEC,这虽然保证了较为正确的传输,但是也使得 MTP latency 很高。MTP latency 就是 Motion to Photon Latency,指的是游戏中玩家作出操作后反映到画面变化上所产生的延迟。显然,过重的纠错负担会使得构建新的视频帧和解码新视频帧耗时增加,明显加重了 MTP latency。在这之后,自然是吹一下自己使用的 frame-level FEC 在降低延迟上具有相当的实力。

Modelling the Joint Source/FEC Rate Problem

这一章主要讲解了如何针对现有问题建模。云游戏为了保证实时性,或多或少依赖于有损压缩和传输,然而云游戏对 MTP latency 有着相当高的要求。

FEC 算法虽然能一定程度上抑制传输失真,但是由于 FEC 的冗余带来了新的传输成本,这导致了可用带宽降低。另外一方面,网络拥塞可能导致连续大量的丢包(文中描述为 burst of losses),此时 FEC 也很难做到恢复原有信号,而这种拥塞也有可能是 FEC 自身导致的。当前的工作也基本都将 FEC 应用在整个 GoP 上,导致 MTP latency 大幅上升(原因似乎是在展示某个 GoP 的任何一张图片前,必须完整解码整个 GoP,和我之前想的有一些不同),并且导致在有限带宽条件下画质降低。

本文首先提出了一个误差函数。对于 \(K\) 个分辨率为 \(M \times N\) 的帧,对 \(1 \leq m \leq M, 1 \leq n \leq N, 1 \leq k \leq K\),定义函数 \(f_k(m, n)\) 表示传输前第 \(k\) 帧在 \((m, n)\) 坐标上的像素值,\(\hat f_k(m, n)\) 则是传输后解码得到的像素值。使用均方差的方式定义传输误差:

\[ {\rm MSE} := \frac{1}{MNK} \sum_{k = 1}^K \sum_{m = 1}^M \sum_{n = 1}^N [f_k(m, n) - \hat f_k(m, n)]^2 \]

下面我们需要考虑全过程中可能产生失真的地方,这里主要考虑三处。

第一是编码失真 \(D_e\)。对于编码率 \(R_e\),编码失真描述为:

\[ D_e := \frac{\theta_1}{R_e - R_0} \]

这里 \(\theta_1, R_0\) 均为适当的参数,事实上这就描述了编码失真和编码率大致成反比例函数关系。

第二是传输失真 \(D_c\)。传输失真的衡量较为简单,记丢包率为 \(\Pi\),则:

\[ D_c := \theta_2\Pi \]

这里 \(\theta_2\) 是适当的参数,传输失真与传输丢包率成正比例关系。

第三是解码失真 \(D_d\)。在以往的工作中,将 FEC 应用在 GoP level 时,由于在不考虑 burst package loss 的条件下 GoP 内部丢包时均能正确解码,所以这里不需要考虑错误传播。然而将 FEC 应用在 frame level 时,就需要考虑 GoP 内部丢失帧导致的错误传播。若将 I 帧出现频率记为 \(\beta\),那么解码失真描述为:

\[ D_d := \frac{\theta_3\Pi}{\beta} \]

这里 \(\theta_3\) 是适当的参数,这表明丢包率越高,解码失真越高,并且 I 帧率越高,其恢复能力越强,从而使得解码失真越低。

综合得到全过程失真为:

\[ D := D_e + D_c + D_d = \frac{\theta_1}{R_e - R_0} + \theta_2\Pi + \frac{\theta_3\Pi}{\beta} \]

那么可以得到这一套系统的峰值信噪比(即 PSNR)为:

\[ {\rm PSNR} = 20\log_{10}({\rm MAX}_I) - 10\log_{10}\left(\frac{\theta_1}{R_e - R_0} + \left(\theta_2 + \frac{\theta_3}{\beta}\right)\Pi\right) \]

PSNR 的定义是:

\[ {\rm PSNR} := 10\log_{10}\left(\frac{\mathrm{MAX}_I^2}{\mathrm{MSE}}\right) = 20\log_{10}({\rm MAX}_I) - 10\log_{10}(\mathrm{MSE}) \]

这里 \({\rm MAX}_I\) 指的是每个像素点可能的最大取值。具体而言,如果某一类图像中每个像素均使用 \(B\) 位二进制表示,那么 \({\rm MAX}_I = 2^B - 1\)

而这里 \({\rm MSE}\) 就是上面提到的传输前后的均方差误差,在这一篇文章中就是三重失真叠加得到的 \(D\)

综上所述,本文对失真所采用的建模方式可以展现为:

但这里有个比较奇妙的地方就是,图的注释里面说了 \(\Pi = 0.1\%\),每一张图也都给定了 \(\beta\),那么为何 \(D_c, D_d\) 还会跟随 \(R_e\) 变化而线性变化呢?我找了一下原论文,里面也说 \(\theta_{1, 2, 3}\) 都是常数,理应不变化的,这里就有点不太理解了。


在此基础上,云游戏系统的目标应当是在满足实时性的约束下最小化失真,所以可以使用有约束优化问题的方式建模云游戏问题。我们能获取到客户端测量的部分网络参数,如往返时延 \({\rm RTT}\)、丢包率 \(\Pi\)、最大可用带宽 \(\mu\)、MTP latency \({\rm MTP}\),此外,我们还知晓编码率 \(R_e\) 和最大容忍延迟 \(T_d\)

云游戏最重要的一项指标就是 MTP latency,而 MTP latency 与发送速率 \(R = R_e + R_r\)(这里 \(R_r\) 是冗余率)以及可用带宽 \(\mu\) 均不成反比,和排队延迟 \(Q_d = {\rm RTT} - {\rm RTT}_{\rm min}\) 成正比。

基于此,每一帧都可以有以下建模。首先定义优化目标为:

\[ \{R_e, R_r\} = \mathop{\rm argmin}(D + \varphi{\rm MTP}) \]

其中:

\[ \begin{aligned} D &= \frac{\theta_1}{R_e - R_0} + \theta_2\Pi + \frac{\theta_3\Pi}{\beta} \\ {\rm MTP} &= \frac{\alpha_1}{\mu} + \frac{\alpha_2}{R_e + R_r} + \alpha_3Q_d + \alpha_4 \\ \end{aligned} \]

优化约束则为:

\[ \begin{cases} {\rm MTP} \leq T_d \\ R_e + R_r \leq \mu \\ \end{cases} \]

这里 \(\varphi\) 是超参数,\(\theta_{1, 2, 3}, R_0\) 都是根据编码器设定的,而 \(\alpha_{1, 2, 3, 4}\) 则是根据回归方式得到的有 95% 置信度的参数,回归所使用的数据集涵盖了有线和 WiFi 等多种网络环境。

在给定帧位置 \(k\) 和丢包率 \(\Pi(t)\) 的条件下,在发送到该帧时需要发送的总包数为:

\[ n := \begin{cases} k & \Pi(t) = 0 \\ \max(k + 1, \lceil k(1 + \omega(F - f)\Pi(t))\rceil) & \Pi(t) > 0, {\rm cut}\ D_d \\ \max(k + 1, \lceil k(1 + \Pi(t))\rceil) & {\rm otherwise} \\ \end{cases} \]

这个公式实际上是冗余率的控制公式,也就是在给定 \(\Pi\) 的条件下,为了发送 \(k\) 个有效包,需要总共发送多少个包。

这里需要说明第二项之中的 \(\omega, F, f\) 参数。首先我们能够注意到,当 I 帧率 \(\beta\) 降低的时候,由于错误传递的链条增长,解码失真会更加严重。这里本文提出的方法是对 GoP 中的帧做不均匀保护,这也就是这些参数的来源。其中 \(f\) 是该帧在 GoP 之中的位置,\(F\) 则是总帧数,针对该帧的冗余率则是 \(k\omega\Pi(F - f)\),其中 \(0 < \omega < 0.4\) 是一个经验参数,根据丢包率 \(\Pi\) 调节。可以发现,离 I 帧越近的帧(即更小的 \(f\)),会带来更多的冗余以及保护。


综上所述,本文将云游戏的问题建模为一个带约束的优化问题,即在满足即时性(MTP latency 用上界限制)和预防网络过载(发送速率用上界限制)的条件下尽可能地降低失真,通过在每个离散时间点求解该优化问题即可得到下一段时间使用的编码率 \(R_e\) 和冗余率 \(R_r\)

Distortion Minimization Framework

然后就是系统架构了:

系统架构中主要的部分是 parameter tuner 和 controller。parameter tuner 接受网络环境的测量值,输出 \(R_e, R_r\) 等参数,之后提供给 controller 来控制编码器和 FEC 编码。上述部分是服务端的结构,而这一系统在客户端还包括一个 network performace monitor,其用于检测网络信息上传到服务端供决策。

Encoder & Decoder (Control Redundancy Rate)

系统中的 FEC Coder 采用了 RLNC 编码方法,该方法生成 \(r = n - k\) 个冗余数据包,其中 FEC 块的大小为 \(n\) 个数据包(\(n\) 的公式在先前有叙述)。如果在块中收到任意随机 \(k\) 个数据包,解码器即可恢复帧。paramerter tuner 从客户端的报告中提取数据包丢失信息,并根据 GoP 中的帧位置来调整冗余(参见方程式5)。GoP 帧的可变 FEC 编码确保了较低的错误传播,因为导致较高传播的帧会获得更高的保护。

将编解码器结构单独列出,得到:

这里 FEC 解码器在接收到超过 \(k\) 个帧的时候就开始解码。

Adaptive Bitrate (Control Encode Rate)

之前提到过 FEC 并不能应对 burst package loss,所以类似 ABR,需要控制编码率 \(R_e\)。当然,和 ABR 不同的地方是这一套系统还需要控制捕捉渲染帧的频率(说白了就是云游戏并不是所有帧都会渲染,在资源比较紧张的时候,会减小渲染频率,这也应该是导致丢帧的一个因素,只不过这里是主动丢帧)。

但是似乎带宽波动最终一般导致的是延迟波动,一般不会导致丢包。原文大概是:

The resulting video dynamically changes resolution with minimal distortion as few packets are lost due to the bandwidth variations.

这一套系统也在上一幅图中有所体现,即 Source Rate Control。

Implementation

编码器的实现就不管了,总之就是讲了一下用了些什么库之类不是很重要的事情,具体结构之前也已经说过了,没什么新的。

客户端的网络性能检测器(Network Performance Monitor)主要是计算可用带宽:

\[ \mu := \frac{\sum_{f = 1}^{F_s}\sum_{p = 2}^kS(p)}{\sum_{f = 1}^{F_s}t(f)} \]

丢包率 \(\Pi\) 定义为丢失的数据包数量与成功恢复帧之前接收到的数据包中丢失的序列号数量 \(k\) 之比。此外,NPM 还会计算 MTP latency。

最后,这些值会通过近五次测量取平均的方式完成平滑。

之后还有一些代码细节,这里就不管了,本文还把 Nebula 实现为 C++ 库供 WebAPP 通过 JavaScript 调用。

Evaluation

baseline 算法已经叙述过了,这里不再叙述。有些实验参数设置这里也不再抄录,直接去原文找吧。

Nebula 系统的时延各部分占比情况如下,这里忽略了传输延迟:

文章的意思是,虽然这里视频编解码时延还是较大,但是通过硬件编解码应当可以压缩到合适的范围内。所以,本文认为 Nebula 可以在不显著增加时延的基础上实现更高的纠错能力。

在进一步的模拟实验中,本文模拟了一个带宽变化的无线网络,并在其上传输 60 秒的 1080p 视频。几种算法的表现如图:

可见只有 BO 具有较低的 MTP latency,然而 Nebula 至少保持了和 WebRTC 持平。此外,ESCOT 由于使用 GoP level FEC,展现了较高的 MTP latency。从画质(以 PSNR 衡量)的角度,BO 通过保持低画质才实现了低延迟。TCP Cubic 具有最高的画质,这是因为没有集成变化视频编码质量的机制,始终保持高画质。综合来看,只有 Nebula 和 WebRTC 做到了平衡画质和 MTP latency。

如果观察具体的发包速率,则可以解释这些现象:

  • BO 始终保持对带宽的低估,所以保持了低画质和低延迟
  • WebRTC 相对较为保守,但已经足够完成画质和延迟的均衡
  • TCP Cubic 始终选择较为激进的超额策略
  • ESCOT 和 Nebula 选用了相同的方式估算带宽,但是 ESCOT 一次发出一个 GoP,Nebula 通过优化带宽使用实现了均衡

后面还有用户实验,这里就跳过了。

Conclusion

总而言之,我看下来觉得这篇文章的贡献主要是:

  • 将 FEC 降低到 frame level
  • 结合了 FEC 和类似 ABR 的系统,实现了时延和画质的平衡
  • 在更极端的条件下(这些条件令 baseline 算法崩溃)表现较好

但我觉得这里的一些建模还是有点语焉不详,或许是我太菜看不懂罢了。

QARC - Video Quality Aware Rate Control for Real-Time Video Streaming based on Deep Reinforcement Learning

又看到自己组的论文了,这下该逮着黄老师一顿狂问了。

Introduction

简而言之就是一个直播 ABR,用 DRL 来做码率决策。然而如果直接把原始图片作为模型的输入,那么状态空间可能会过大,所以本文最主要的是将这一个模型拆为 VQPN 和 VQRL 两部分。其中,VQPN 用来预测未来的视频质量,VQRL 则基于 VQPN 的预测和网络状态做出码率决策。为了训练 VQRL,本文还提出了一个离线模拟器。

主要贡献为:

  • 重新定义了 QoE,似乎指的是将以往基于码率的 QoE 改成了从整个视频会话的角度思考
  • Quality aware,但我还是不是很懂这个名词的含义,Google 的解释为:Quality awareness is the way to promote quality activities by emphasizing quality at all stages of the business
  • 将庞大的模型拆为两部分,有效控制了状态空间的大小

Motivation

这里主要是说明码率并不能完全反映视频质量,一个静态场景的视频,高码率并不能有效提高用户感知的质量,反而会过分占用带宽导致拥堵。这里使用基于支持向量机的 VMAF 算法作为视频质量评估算法,其分别评估了静态背景视频、动态背景视频和混合背景视频在不同码率、不同编码器下的 VMAF 得分,数据显示大部分情况下在较高码率区域,码率的增长对视频质量提高的作用十分有限。所以,单纯依靠提升码率或者换用编码器都不足以有效提升视频质量。

System Architecture

系统结构还是比较直观的:

整体上的话和 ABR 结构类似,但是由于码率和视频质量的不成比例,所以需要有 VQPN 来学习前一帧、网络状态和码率之间的关系,然后通过 VQRL 做出码率决策。

这里提出 VQPN 的必要性在于,根据本文的 motivation,制约视频质量(以 VMAF 衡量)的因素过多(视频种类、亮度、物体数量等),导致难以简单地通过启发式等方法预测未来的码率和视频质量的关系。基于此,通过神经网络来完成这一任务就是自然的了。

神经网络的设计是先通过 CNN 提取图像信息,然后预测部分则是一般的 RNN。首先定义视频质量指标,对某一个给定的时间槽 \(t\) 以及其中的帧 \(f_i\),本文先在给定码率 \(b\) 下将该帧编码后传入 VMAF 算法计算得到 \(V(f_i, b)\),定义时间槽内的 VMAF 分数为时间槽内各帧的平均值:

\[ V(t, b) := \frac{1}{F}\sum_{i = 1}^F V(f_i, b) \]

最终这些分数会被归一化到 \([0, 1]\) 区间中。

该模型接受的输入是时间槽 \(t\) 中的各个帧,先通过 CNN 提取图像特征,再通过 RNN 提取时序特征,模型的输出则是不同码率下下一时间槽 \(t + 1\) 的视频质量(VMAF 分数)。

损失函数是简单的均方差,下述公式中 \(\hat V\) 是 ground truth。另外为了防止过拟合,增加了二次正则:

\[ \mathcal{L} := \frac{1}{B}\sum_{b = 1}^B |V(t + 1, b) - \hat V(t + 1, b)|^2 + \lambda \|\theta\|^2 \]


之后是 VQRL,一个经典的 RL 算法。状态空间主要包括先前发送的视频质量、VQPN 预测的未来视频质量、过去视频发送速率、过去视频接收速率、过去视频延迟梯度、过去视频丢包率。但是这里和黄老师之前处理状态空间的区别有两个,一个是多了个延迟梯度,一个是莫名其妙引入了 FFT 算法,目前还不是很清楚这样做的原因。决策空间显然是码率,这没有什么好说的。QoE 使用了和以往不同的定义,这里先忽略。

具体算法是 A3C,策略梯度部分为:

\[ \nabla\mathbb{E}_{\pi_\theta}\left[\sum_{t = 0}^{+\infty} \gamma^t r_t\right] = \mathbb{E}_{\pi_\theta}\left[\nabla_\theta \ln\pi_\theta(s, a)A^{\pi_\theta}(s, a)\right] \]

在此基础上,为了更好平滑策略,在具体更新的时候还增加策略熵项:

\[ \theta\leftarrow\theta + \alpha\sum_t \nabla_\theta \ln\pi_\theta(s_t, a_t)A(s_t, a_t) + \beta\nabla_\theta H(\pi_\theta(\cdot\mid s_t)) \]

此外,为了计算 \(A\),需要在策略网络之外设定值网络。值网络采用 Q learning 训练,这里就忽略掉了。

在具体训练阶段,VQRL 因为采用了 A3C 所以使用了多智能体可以理解,但是有关模拟器的部分可能还有点不是那么看得懂(这里悄悄偷懒不看了,真的缺失太多基础知识了,再说)。

Evaluation

首先是实现算法,这里数据集啥的也都先跳过,主要要说 QoE 指标设定:

\[ {\rm QoE} := \sum_{n = 1}^N(V_n - \alpha B_n - \beta D_n) - \gamma\sum_{n = 1}^{N - 1}|V_{n + 1} - V_n| \]

这里 \(V_n\) 表示时间 \(n\) 的视频质量,\(B_n\) 是发送方选择的视频比特率,\(D_n\) 代表接收方测量的延迟梯度,最后一项则表现了视频质量的平滑性。

之后就是系统实现,一样的,网络结构和超参数这里就不抄了。不过本文最有意思的是其不是直接给出网络结构和超参数的选择,而是详细写了选择这些超参数的实验结果。比如在选择网络结构、是否加入 FFT 和序列长度的时候,就有这些实验结果:

另外的一些实验结果这里就跳掉了,基本上就是吊打 baseline。

讲了一下有关实时流量控制、视频质量评估和强化学习的一些基础工作。主要批评了一下用丢包事件调控发送速率的 TCP 拥塞控制(你都已经丢包了才开始降速率,早就已经晚了),然后批评了一下 PSNR、SSIM 不能很好形容视频质量,然后吹了一下 VMAF。

SQP - Congestion Control for Low-Latency Interactive Video Streaming

云游戏原来更官方的说法叫互动视频流。当然,这不是个等价的说法,毕竟远程桌面啥的也叫互动视频流。但是,至少以后介绍自己在干什么的时候就可以:“我做互动视频流传输优化的”。

Introduction

本文是做一个拥塞控制算法(Congestion Control Algorithm / CCA),一个对互动视频流友好的 CCA 需要满足:

  • 低排队延迟。CCA 需要探测带宽,那么就需要发送探测数据包,但是过度的探测会导致带宽被浪费在测量行为上,所以 CCA 需要尽可能少占用带宽而能够获取尽可能精准的带宽测量。此外,CCA 在带宽降低的时候,需要迅速撤回发送以减少排队。Cubic 和 PCC 在这方面就不足够好
  • 公平性。不是很懂这篇文章里面对公平性的定义,但是我自己认为就是要公平对待每一个流?不管了,先看后面的
  • 友好型。就是不能饿死其他流
  • 视频感知。这里也没怎么看得懂,还是后面慢慢看吧

感觉 CCA 的一些基础可以看:https://www.fanyamin.com/blog/yong-sai-kong-zhi-ji-zhu-de-bi-ji-yi-li-lun-pian.html

然后就是说,现在通用的 CCA 可能不能满足互动视频流的需求,言下之意就是我们得专门设计一个 CCA。本文提出了 SQP,其主要特点在于:

  • 优先考虑低延迟而非链路利用率。总而言之就是优化目标的重新排序,SQP 首先考虑的是低延迟,即使并不能高强度压榨网络带宽
  • 应用特定的权衡。似乎指的是如果延迟过高或者可用带宽过低,会允许终止视频流通话
  • 帧关注式操作。网络排队是侦测网络参数的重要现象,部分不通过网络排队侦测网络的 CCA 可能无法充分利用网络带宽,即使其延迟较低。而 SQP 通过有节奏的突发传输将带宽测量值附加到帧信息中
  • 直接码率控制。SQP 似乎会通过调整帧级别的码率来响应拥塞,似乎又是一个 ABR 类似的东西
  • 竞争吞吐量。没太看懂,总之是比较猛的意思。此外似乎提到了自适应这一个属性,但 CCA 里面什么是自适应,还真的不知道

直接把 ChatGPT 的翻译贴过来吧:

适用于低延迟互动式视频流媒体的拥塞控制算法必须满足在第 1 节中讨论的四个关键特性。各种拥塞控制算法总结在表 1 中。像 TCP-Lola [27]、TCP-Vegas [28] 和 Sprout(Salsify3)[21, 29] 这样使用数据包延迟作为信号的低延迟拥塞控制算法存在一个关键缺点:它们在与排队建立的交叉流量竞争时无法实现高吞吐量。一些模式切换算法(例如 Copa [14])可能会误解自引发的排队为竞争流,导致高延迟,而其他拥塞控制算法如 Nimbus [15] 和 GoogCC(WebRTC)[17, 18] 收敛速度较慢,在与排队建立的流量竞争时吞吐量不稳定。

算法的比较表如下:

用数据包延迟做信号的 CCA 无法实现高吞吐的原因我猜测是因为这类算法一般也不会太激进,一旦遇到竞争就会导致包延迟加大,这就导致这类算法往回缩,直接退出竞争。模式切换算法不是很懂什么意思,后面还有攻击收敛速度慢导致不稳定的,这些就不再说了。

此外还有些算法,如 BBR 通过定期限制传输来做测量,这显然不适用于对实时性有高要求的互动视频流(毕竟做测量的时候就不能发包,这太恐怖了)。PCC 算法目标是较为精准地测量网络,结果就是收敛速度慢。

最后贴一个总结:

拥塞控制算法使用基于速率或基于窗口的机制来在拥塞情况下控制传输速率。基于速率的拥塞控制算法更适合视频流媒体,因为数据包传输是无突发的,而基于窗口的机制可能会在发送端阻塞帧传输,使编码器速率控制变得复杂(例如,Salsify-Sprout)。基于速率的拥塞控制算法的另一个好处是它们的内部带宽估算可以直接用于设置视频比特率,而基于窗口的机制需要额外的机制来设置视频比特率。

Preliminary Study

这里就直接开始拿实验结果攻击之前的算法了。

大概就是让带宽从 20 Mbps 突降到 5 Mbps 然后拉回来,主要观察算法能不能觉察到带宽突降并保持低延迟,并且在带宽恢复的时候能够觉察到资源恢复并尽快拉高传输。

可以看到 Cubic 几乎打满了带宽利用,基本上就是猛猛参与竞争,但相应的就是延迟很高。其余的算法基本上能保持较低延迟,其中 Sprout 和 Copa 0.1 保持最好,但是利用率并不理想。PCC Vivace、GoogCC、BBR 适应较慢,基本上还是出现了延迟峰值。PCC 和 Copa Auto 则直接爆了,在低带宽时期保持了很高的延迟。

后面就从算法原理的角度批判了一下 BBR 的设置很容易导致延迟(对在途包数量有限制),之后批判 Copa 容易误判现象导致延迟。

之后是比较收敛性,显然 PCC 和 GoogCC 是不理想的,明显注意到在带宽恢复的时候这两个算法耗费了很长时间恢复。

综上,互动视频流对 CCA 的要求为:“拥塞控制算法必须能够快速识别链路容量,而不引起排队延迟,并在延迟是自引发的情况下迅速退避”。

Short Timescale Variations

这一部分主要是观察各个算法在时间微观尺度上的行为。

Copa 的延迟波动极大,可以注意到其各个帧的发送率波动相当之大。BBR 则更为离谱,其由于在途包数量限制和阻塞发送测量网络的行为,其中间直接出现了极低的数据包发送率。相比较之下,Vivace 这一类基于速率的算法更适合互动视频流,其内部对发送速率的估算显然可以作为码率决策的参考。与其他类型的 CCA 相比,其他算法做码率决策的时候需要用其他参数七弯八拐得到决策,不如基于速率的算法直观和简单。

Design

SQP 目标是:

  • 提供实时带宽估算
  • 在竞争条件下提供有竞争的吞吐量

整体结构为:

这里直接进入各个组成部分细节的讨论。

Bandwidth Sampling

做带宽侦测,目标就是精确掌握当前可用的带宽大小,以尽可能利用并且减少排队、避免传输暂停(显然 BBR 的神奇设计给本文作者留下了深刻的印象)。SQP 的逻辑是,将某一个帧的各个数据包以略大于网络承载量的速率发送,以形成小范围的排队。如果视频的平均码率小于瓶颈链路可用流量,就意味着先前的队列可以在下一帧到达前排空。

此外,SQP 的特点在于其测量链路可用流量的粒度为子帧(在 60FPS 下粒度最大为 16.66 毫秒)

假定某视频的帧间隔时间为 \(I\)(这是固定的,60FPS 下就是 16.66 毫秒),并且假定此时帧在给定码率下大小为 \(F\),那么 SQP 会以高于 \(F / I\) 的速率发送这些数据包。如果没有竞争流,这些包的到达时间将会反映当前的可用链路带宽(如上图的红色点)。我们有以下公式:

\[ S = \frac{F}{R_{\rm end} - S_{\rm start} - \Delta_{\rm min}} \]

这里 \(R_{\rm end}\) 是最后一帧到达时间,\(S_{\rm start}\) 是第一帧发出时间,\(\Delta_{\rm min}\) 是最小单向延迟(在第一次发送的时候就已经测量,之后不再变化),通过上图我们可以看出,这实际计算出了红色点所在直线的斜率,从而构成了对当前链路可用带宽的估计。

可以注意到,上述计算成立是基于没有充分利用链路,因为两帧之间依然存在链路空闲(前一帧已经完全发送,但是后一帧还没编码完毕,称为无跨帧排队),这也就是图 (a) 所显示的。这个时候第二帧的第一个数据包出现的单向延迟 \(\Delta\) 等于第一帧的第一个数据包 \(\Delta_{\rm min}\),此时 SQP 会试图提高码率,尝试提高视频质量。

但如果过分估计了可用带宽,则可能出现图 (b) 的现象,此时出现了跨帧排队。这个时候第二帧的第一个数据包出现的单向延迟 \(\Delta\) 会大于第一帧的第一个数据包 \(\Delta_{\rm min}\)。此时使用先前的公式计算出的 \(S\) 是图中虚红线的斜率,这个计算值会小于先前的计算,这意味着 SQP 需要降低码率以排空队列。

现在我们需要思考,SQP 对带宽的估算是基于短时爆发流量而非视频平均码率。此时如果出现了较小的帧(例如游戏中打开了静态菜单界面等相对信息量较少的页面,此时编码器并不会完全遵守所请求的码率,而是会编码出一个小帧),如图 (c) 所示。若按照原先的公式,这里的带宽估计值将会被计算为图中较短的虚红线的斜率,这显然过低了。所以我们需要做出修正:

\[ S = \frac{F\gamma}{R_{\rm end} - S_{\rm start} - \Delta_{\rm min} + (R_{\rm end} - R_{\rm start})(\gamma - 1)} \]

这里 \(\gamma\) 是帧的大小比例。该式子在数学上成立是显然的。

Tracking Minimum One-way Delay

这里主要探讨了 \(\Delta_{\rm min}\) 的计算,SQP 里面应该有一个时间窗口一直计算每一帧的最小单向延迟,并取窗口中的最小值作为 \(\Delta_{\rm min}\)。这里主要是窗口的大小应当如何设定,如果窗口过小,则由于记忆的延迟数据过少,很有可能无法感知到之前自引发的排队,导致一味降低码率。如果窗口过大,虽然可以让 SQP 更快从自引发排队中恢复,但是 SQP 也更容易受到其他流量的影响,降低吞吐量份额。

SQP 采取的窗口大小为 \(2 \times {\rm sRTT}\),这是一个动态的窗口设置。这一设置的好处在于,如果出现了自引发排队,那么随着 \({\rm sRTT}\) 上升,窗口大小也随之上升,从而促进排空队列。另外似乎还有一个和竞争流相关的东西,但这里暂且没有看懂,先跳过。这之后还不忘攻击一下 BBR 的机制,虽然 BBR 能够更准确地测量延迟,但是代价是近 200 毫秒的传输暂停,这在交互视频流中几乎是不可接受的。

Bandwidth Estimate Update Rule

从采样器那里获得的带宽估计将被送到这里处理为传送给编码器决定码率的平滑带宽,具体而言,我们希望平滑后的带宽越大越好,但是也需要惩罚不精准的平滑。本文采用的方式是求解一个优化目标,其中第一项是对数增长的,用来给平滑带宽的增长提供奖励,而第二项则较为严格地使用了平方项来给不精准估计以惩罚:

\[ \max\varphi(B) = \max\left[\log(1 + \alpha B) - \beta(B - e)^2\right] \]

这里 \(B\) 是我们需要求的平滑带宽,\(\alpha, \beta\) 是超参数。由于 \(B = S\) 显然是最佳平滑(\(S\) 为采样器提供的估计),这里 \(e\) 就是用于调节函数极值点,使得上述函数最大的时候 \(B = S\)。为了求解这个 \(e\),我们观察这个函数的导数:

\[ \varphi'(B) = \frac{\alpha}{1 + \alpha B} - 2\beta(B - e) \]

得到:

\[ \frac{\alpha}{1 + \alpha S} = 2\beta(S - e) \iff e = S - \frac{\alpha}{2\beta(1 + \alpha S)} \]

在实际平滑操作的时候,其显然采用了类似梯度下降的逻辑来平滑。即,维护一个当前估计 \(B\),并每次沿着导数方向前进一定步长来完成平滑:

\[ B \leftarrow B + \delta\varphi'(B) \]

这里 \(\delta\) 是类似学习率的步长参数。我们做一些数学简化:

\[ \begin{aligned} \varphi'(B) &= \frac{\alpha}{1 + \alpha B} - 2\beta\left(B - S + \frac{\alpha}{2\beta(1 + \alpha S)}\right) \\ &= \frac{\alpha}{1 + \alpha B} - \frac{\alpha}{1 + \alpha S} - 2\beta(B - S) \\ &= \frac{\alpha^2(S - B)}{(1 + \alpha B)(1 + \alpha S)} + 2\beta(S - B) \\ \end{aligned} \]

这里似乎推不出来论文里的更新表达式,找时间问问学长吧。

Pacing and Target Multipliers

这一段似乎提到了公平性和友好性,但是实在是不是很懂,还是等到后面慢慢聊吧。

这篇文章暂且就看到这里了,笔记也就到此为止了。

Enabling High Quality Real-Time Communications with Adaptive Frame-Rate

Introduction

随着网络条件优化、游戏帧率提高,云游戏系统的解码器总是能快速接收到帧数据。另外一方面,游戏分辨率的提高也增加了解码器的解码时长。综上所述,解码器排队已经是一个不可忽略的延迟,经分析,延迟超过 100 毫秒的帧有过半数在解码器队列中等待了 50 毫秒以上。本文基于“仅仅调整码率并不能有效缓解队列延迟”,主要引入了自适应帧率控制器(AFR),通过控制编码器的帧率来控制解码器的队列压力。

需要注意的是,以往是有过调整帧率的相关工作的,但是随着解码硬件的发展渐渐失去了效用。然而随着高性能 RTC、高帧率和更高的延迟要求,这一需求又凸显出来。另外,我们发现了部分当下方案的问题。首先,现有的控制机制基于反馈速度较慢的延迟或队列长度,所以需要等待队列建立才能做出调整。AFR 相反,其依赖于到达和服务过程以及队列长度来调整帧率。其次,并非所有解码排队延迟的增加都需要降低帧率。例如,当由于瞬时的到达数据包突增而导致排队延迟增加。

总之就是,AFR 可以较快地通过调节帧率实现极低的延迟。

Background - High Quality RTC

首先背景就是 RTC 传输越来越猛了。首先是帧率大幅度提高,现在达到了 60FPS 甚至 240FPS。其次是分辨率大幅度提高,已经开始出现默认 1080p 乃至 4K 的应用。最后是延迟容忍度大幅降低,视频会议阈值大约为 150 毫秒,云游戏则为 100 毫秒。

之后看一下现在的高质量 RTC 结构:

这里全流程优化里面,本文主要关注尾延迟,基本上也就是解码器排队。另外,出现次数较少的长时间延迟(称为延迟时间分布长尾)也需要考虑,本文甚至关注 99% 或 99.9% 百分位数的尾部延迟。例如,在 60FPS 的帧率下,即使是 99.9% 百分位数的延迟也可能每 16 秒发生一次。所以控制长尾也是重要的优化目标。

Motivation and Challenges

Motivation - Drastic Queuing Delay

首先是调研了一下云游戏中的延迟来源,基本上确定了最主要延迟来源为解码器排队、解码、网络延迟(也就是图上面的红色字显示的部分)。记 \(N, Q, D, T\) 分别为网络、解码器排队、解码、总延迟,数据统计时本文计算了 \(\mathbb{P}(X > X_{\rm th} \mid T > T_{\rm th})\),其中 \(X \in \{N, Q, D\}\),这里下标 \({\rm th}\) 为给定的统计阈值。统计如下:

符合直觉的是,在总延迟大于 200 毫秒的时候,网络延迟往往占据了大部分。然而如果考虑 100 毫秒左右的延迟,解码器排队延迟反而是占主要部分的延迟。

这也是符合直觉的,这一切的根本原因就是高帧率和高分辨率的要求。如下图所示,这里展现了不同分辨率、帧率下视频流传输服务中 99 分位数解码器排队延迟的占比(即只关注尾部数据),可以看到在右上角的 VR/AR 服务中解码器排队延迟相当严重。即使尾部数据很有可能受到 CPU 发热等随机因素影响,但是通过更换更好的硬件,依然无法有效解决这一问题。此外,根据排队论,小幅度的排队波动都可能导致延迟的幅度增加,这些都是影响因素:

从硬软协同的角度上,软件上视频应用甚至已经开始提供 8K 视频服务,然而编解码器的能力却完全没能跟进。另外一方面,大量的用户依然保持了大量的中低端设备,完全无法流畅运行如此庞大的视频软件。

Choice - Controlling Proper Parameters

总之就是要调节编码器了,编码器主要参数就是帧率、码率、分辨率。从解码器队列的角度,该队列的入队速率取决于编码帧率,出队速率取决于解码效率,即分辨率。

本文需要分别控制各个参数以减少不同的延迟。作为响应,我们调整帧率来控制高质量 RTC 的排队延迟。当解码器和网络的波动导致排队延迟增加时,有必要调整编码参数以减少排队延迟。在这种情况下,经过从客户端和网络收集测量数据后,服务器上的编码器可以相应地调整以下帧的帧率。我们可以动态指定新帧被编码的特定时间戳。

这里为什么选择调节帧率而非分辨率等参数似乎我并没有看得太懂,这里还是等等学长来讲解吧。

Challenges

实现超短队列延迟事实上是很困难的,因为一般的探测信号只有在队列已经建立的时候才会有所反馈。简而言之,大部分算法只有已经堵车了才能察觉到拥堵,而做不到预测将来会堵车而下调帧率。为了预测潜在的排队延迟增加,本文采用的方式是探测解码器队列的出队速率。另外,为了应对长尾,本文似乎提出了一整套基于排队论的延迟控制方法,更详细的叙述看来在后面了。

此外,由于队列积累的原因多种多样。解码器的突发退化和无线网络的爆发发包,这些情况很难通过测量出入队速率来做出反应。这里本文提出了根据不同原因在不同尺度下处理排队的系统。其中一个用来防止高负载下的队列积累(稳态控制器),一个用来防止突发条件下的排队延迟(瞬时控制器)。

Design - Adaptive Frame Rate

算法结构:

总而言之,稳态控制器根据出入队情况尽可能将延迟控制在极低范围内,而瞬时控制器则通过队列状态计算折扣因子,在突发条件下需要折扣稳态控制器计算的帧率以响应突发条件。

Stationary Controller

这里基于排队论中的 Kingman 公式设计了稳态控制器,可以得到排队时间的期望为:

\[ \mathbb{E}[\tau_{\rm queue}] \approx \left(\frac{\rho}{1 - \rho}\right)\left(\frac{c_a^2 + c_s^2}{2}\right)\mu_s \]

这里:

\[ c_a = \frac{\sigma_a}{\mu_a}, c_s = \frac{\sigma_s}{\mu_s}, \rho = \frac{\mu_a}{\mu_s} \]

其中:

\[ \mu_a = \mathbb{E}[A_n], \sigma_a = \sqrt{\mathop{\rm var}[A_n]}, \mu_s = \mathbb{E}[S_n], \sigma_s = \sqrt{\mathop{\rm var}[S_n]} \]

这里 \(\rho\) 即为队列利用率,\(\rho \to 1\) 表示队列超载,此时排队时长增加。\(c_a, c_s\) 则分别代表了入队和出队的波动程度。

这篇文章暂且就看到这里了,笔记也就到此为止了。

这四篇文章主要还是引出目前在腾讯那边想做的画质感知相关工作的基本思路:

采用和 Nebula(实际上就是传统 WebRTC 云游戏)系统类似的架构,所要做的提升的 motivation 和 QARC 比较类似,即用户体验和码率并不完全对等,然而由于云游戏对低延迟的强大需求,类似 QARC 的基于 learning 的方法并不能很好适用,所以需要做一些其他的设计。目前的想法是通过 encoder 的一些编码信息来推测画质,例如如果一个帧之中独立编码的部分过多(大部分帧都会参照先前的帧做相对编码,而先前帧不能成为参考则会独立编码),就可以推测这一帧发生了较大的场景切换,从而需要调高码率来高清显示。

此外,码率决策也很难通过 RL 等方式来完成,所以采用了 reactive 的方法,即所谓的“面多了加水,水多了加面”的调整方法。然而现在面对画质闪烁等问题依然还有一些需要改进的地方。

SQP 这篇论文则是主要学习一下 CC 算法和云游戏的不同要求,其中 CC 要求打满网络,通过排队信息来获得网络测量数据,而云游戏做不到,其对低延迟要求很高。

AFR 这篇论文则主要是学习一下 writing,现在论文上面比较偏好提出新颖的问题,解决方案平凡、粗糙一点都可能不会太有影响。

FlashBack - Immersive Virtual Reality on Mobile Devices via Rendering Memoization

之前试着用了一下腾讯现在的云游戏系统,然后发现在新场景加载上有很长的延迟,然而这些场景虽然对我而言是新场景,对其他用户却不一定。所以我就猜应该可以加入一些缓存来加速这些场景的渲染,至少可以尝试做一下用户无关信息的缓存。学长和我说确实有道理,然而这已经是实践中的想法了,然后给我扔了个论文让我学学,结果我一看,2016 年的论文。

Introduction

2016 年的 VR 论文了,这里的背景部分就随便看看吧。简而言之,2016 年的 VR 方案(特指头戴式的 HMDs)大概有两种:

  • 有线方案:主要算力为主机,VR 设备通过数据线连接到主机,也就是说 VR 设备基本上起到显示屏的作用。这类方案的问题在于,数据线限制了用户的移动范围。并且,由于 VR 对低延迟、高帧率、高分辨率的要求,主机本身的算力要求也相当之高
  • 移动渲染方案:即算力集成在头戴式设备之中,然而由于硬件设计的限制,这类设备的算力往往不足以满足 VR 的需求。所以低画质、低电池续航、热辐射成为了这类方案的问题

另外,这两种方案事实上都成本高昂,很难做到成规模的商业化消费,乃至深入应用到生活的各个方面。

FLASHBACK 的设计思路很简单,就是通过增加缓存的方式,将场景提前渲染好后供 VR 设备索引。而如果出现缓存缺失,则通过快速求取近似值的方式完成这一任务。

然而即使如此,要在 VR 这种互动性极强的视频形式上直接运用缓存也是很困难的,所以 FLASHBACK 还在 VR 如何在移动端设备上部署这一问题上做出了创新成果。FLASHBACK 在 GPU 视频内存(VRAM)、系统 RAM 和辅助存储之间构建了三级帧缓存,用来存放提供给 VR 设备的帧。这一部分缓存的索引是玩家在场景中的三维坐标和姿势,当玩家移动的时候系统都会索引该缓存,使用最近邻算法快速搜索三维空间。

此外,为了处理动态场景(估计指的是 NPC 的移动等问题),FLASHBACK 为每一个动态物品创立动态帧,通过将各个动态帧和表示场景的静态帧叠加的方式完成动态场景的处理。

这里感觉就是说了一下技术上的细节,本质上还是在重复说明 FLASHBACK 的核心思路是构建帧缓冲区。

Background

大概说了一下什么是 VR,然后主要说明了现在商用的 VR 场景创建的流程,也就是 Unity 或者虚幻引擎。本文认为现在商用引擎的工作逻辑是通过工程中预设的各种对象和场景来渲染最终图像,这种工作逻辑的好处在于其清晰地划分出了静态场景和动态对象,使得 FLASHBACK 处理动态的逻辑变得可能。其次,这些引擎渲染结果中的摄像机在概念上是独立的,所以将其替换也是简单的。

这里有点似懂非懂,感觉技术细节很多。动态场景那里倒是大概明白,意思就是商用引擎暂且还没傻到渲染出来的结果就是一堆像素点,是有办法获得具体一个物体的信息的。然而摄像机就不是很懂了,虽然知道摄像机是个什么东西,但是这玩意和文章里面说的“以此建立缓存索引”是什么关系一概不知。

然后又大概强调了一下高分辨率、低延迟、高帧率的要求有多么多么高(但是实际上的 VR 产品失真感还是太离谱了,完全做不到沉浸感,至少 2016 年前后的产品实在是这样,所以我在听闻到元宇宙的时候只觉得离谱)。

System Overview

整个系统概括并没有带来什么新的信息,只是另外多提到了:

  • 缓存未命中的时候使用网格扭曲处理近似,这种方法的处理速度与场景复杂度无关,只和屏幕分辨率有关
  • 最后会使用桶形扭曲来将场景投射到 HMD 设备上

这篇文章感觉没那么重要,所以就不再多看了。