Skip to content

Latest commit

 

History

History
417 lines (291 loc) · 33.8 KB

音视频基本原理.md

File metadata and controls

417 lines (291 loc) · 33.8 KB

音视频基本原理

流媒体收发过程

流媒体收发过程

视频技术

视频主要概念

视频基础

  • 视频码率kb/s,是指视频文件在单位时间内使用的数据流量,也叫码流率。码率越大,说明单位时间内取样率越大,数据流精度就越高。
  • 视频帧率fps,通常说一个视频的25帧,指的就是这个视频帧率,即1秒中会显示25帧。帧率越高,给人的视觉就越流畅。
  • 视频分辨率:分辨率就是我们常说的640x480分辨率、1920x1080分辨率,分辨率影响视频图像的大小。
  • Stride:跨距,是图像存储的时候有的一个概念。它指的是图像存储时内存中每行像素所占用的空间。 跨距
  • I 帧(Intra coded frames):
    • I帧不需要参考其他画面而生成,解码时仅靠自己就重构完整图像;
    • I帧图像采用帧内编码方式;
    • I帧所占数据的信息量比较大;
    • I帧图像是周期性出现在图像序列中的,出现频率可由编码器选择;
    • I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
    • IDR 帧是帧组GOP的基础帧(第一个(I)帧),在一组GOP中只有一个IDR帧;
    • I帧不需要考虑运动矢量;
  • P 帧(Predicted frames)根据本帧与相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据,同时利用了空间和时间上的相关性。
  • P帧属于前向预测的帧间编码。它需要参考前面最靠近它的 I 帧或 P 帧来解码。
  • B 帧(Bi-directional predicted frames)采用双向时间预测,可以大大提高压缩倍数。

视频编码基础

编码算法

  • 先通过 帧内预测 或者 帧间预测 去除 空间冗余时间冗余 ,从而得到一个像素值相比编码块小很多的 残差块
  • 再通过 DCT 变换将低频和高频信息分离开来得到变换块,然后再对变换块的系数做 量化。由于高频系数(变化频率大)通常比较小,很容易量化为0,同时 人眼对高频信息不太敏感 ,这样我们就得到了一串含有很多个0,大多数情况下是一串含有连续0的“像素串”,并且人的观感还不会太明显。
  • 最后 熵编码 就能把图像压缩成比较小的数据,以此达到视频压缩的目的。

数据冗余

图像一般都是有数据冗余的,主要包括以下4种:

  • 空间冗余 比如说将一帧图像划分成一个个 16x16 的块之后,相邻的块很多时候都有比较明显的相似性,这种就叫空间冗余。
  • 时间冗余 一个帧率为 25fps 的视频中前后两帧图像相差只有 40ms,两张图像的变化是比较小的,相似性很高,这种叫做时间冗余。
  • 视觉冗余 我们的眼睛是有视觉灵敏度这个东西的。人的眼睛对于图像中高频信息的敏感度是小于低频信息的。有的时候去除图像中的一些高频信息,人眼看起来跟不去除高频信息差别不大,这种叫做视觉冗余。
  • 信息熵冗余 我们一般会使用 Zip 等压缩工具去压缩文件,将文件大小减小,这个对于图像来说也是可以做的,这种冗余叫做信息熵冗余。

视频帧预测

图像内部相邻宏块之间有很多 相似性 ,并且两张图像之间也有很多 相似性 。因此,根据图像的这个特点,我们可以在编码的时候进行 帧内预测帧间预测 。 通过预测得到的 残差块 的像素值相比 编码块 的像素值,去除了大部分 空间冗余 信息和 时间冗余 信息,这样得到的像素值更小。如果把这个残差块做扫描得到的像素串送去做行程编码,相比直接拿编码块的像素串去做编码更有可能得到更大的 压缩率

  • 帧内预测

    帧内预测 帧内预测类型

    • 在当前编码图像内部已经编码完成的块中找到与将要编码的块相邻的块。一般就是即将编码块的左边块、上边块、左上角块和右上角块,通过将这些块与编码块相邻的像素经过多种不同的算法得到多个不同的预测块。然后再用 编码块 减去每一个 预测块 得到一个个 残差块 。最后,取这些算法得到的残差块中像素的绝对值加起来最小的块为预测块。而得到这个预测块的算法为 帧内预测模式
    • 一幅图像中相邻像素的亮度和色度信息是比较接近的,并且亮度和色度信息也是逐渐变化的,不太会出现突变。也就是说,图像具有 空间相关性 。帧内预测通过利用已经编码的相邻像素的值来预测待编码的像素值,最后达到减少空间冗余的目的。已经编码的块会解码成像素用来做参考像素。
    • 在H264标准里面,块分为宏块和子块。宏块的大小是16x16(YUV420图像亮度块为16x16,色度块为8x8)。
    • 一个16x16的亮度块,我们可以不划分,直接使用4种16x16的帧内预测模式,最多得到4种预测块;也可以划分成16个4x4的子块,每一个子块最多有9种帧内预测模式。
  • 帧间预测

    • 在前面已经编码完成的图像中,循环遍历每一个块,将它作为预测块,用当前的编码块与这个块做差值,得到 残差块 ,取残差块中像素值的绝对值加起来最小的块为 预测块 ,预测块所在的已经编码的图像称为 参考帧 。预测块在参考帧中的坐标值(x0, y0)与编码块在编码帧中的坐标值(x1, y1)的差值(x0-x1, y0-y1)称之为 运动矢量 。而在参考帧中去寻找预测块的过程称之为 运动搜索
    • 前后两帧图像往往变化比较小,这就是视频的 时间相关性 。帧间预测就是利用这个特点来进行的。通过在已经编码的帧里面找到一个块来预测待编码块的像素,从而达到减少时间冗余的目的。
    • 只参考前面图像的帧我们称为 前向参考帧,也叫 P帧 ;参考后面的图像或者前面后面图像都参考的帧,我们称之为 双向参考帧 ,也叫做B帧 。B帧相比P帧主要是需要先编码后面的帧,并且B帧一个编码块可以有两个预测块,这两个预测块分别由两个参考帧预测得到,最后加权平均得到最终的预测块。
    • 在H264标准中,P帧最多支持从16个参考帧中选出一个作为编码块的参考帧,但是同一个帧中的不同块可以选择不同的参考帧,这就是 多参考
  • 运动搜索

    • 用运动矢量来表示编码帧中编码块和参考帧中的预测块之间的位置的差值。使用运动矢量就可以在参考帧中找到预测块。
    • 从参考帧中第一个像素开始,将一个个16x16大小的块都遍历一遍。总是可以找到差距最小的块,这种方法称之为 全搜索算法
    • 亚像素精度运动搜索
      • 先通过 快速搜索算法 进行整像素运动搜索算法得到整像素的运动矢量。
      • 对参考帧进行半像素和1/4像素插值。以整像素运动矢量指向的整像素为起点,进行钻石搜索算法,分别求得中心点以及上、下、左、右四个半像素点对应预测块的残差块,得到SAD值。取SAD值最小的点为最佳匹配点;以半像素运动搜索的最佳匹配点为起点,分别求得中心点以及上、下、左、右四个1/4像素点对应预测块的残差块,得到SAD值,并取最小的点为最佳匹配点。
    • 运动矢量跟编码块一样不是直接编码进去的,而是先用周围相邻块的运动矢量预测一个预测运动矢量,称为MVP。将当前运动矢量与MVP的残差称之为MVD,然后编码到码流中去的。解码端使用同样的运动矢量预测算法得到MVP,并从码流中解码出运动矢量残差MVD,MVP+MVD就是运动矢量了。
    • P帧中的静止部分,前后两帧不会变化,运动矢量直接为0,而且残差块像素值本身因为几乎没有变化基本为0,只有少部分噪声引起的比较小的值,量化后更是全部变成了0。这种图像中的静止部分或者是图像中的背景部分大多数时候都是 SKIP 模式。这种模式非常省码率,且压缩效率非常高。
    • RTC 场景中我们一般选择 单参考 ,并且一般选择当前编码图像的前一帧作为参考帧。运动矢量是用来表示参考帧中预测块与编码帧中编码块位置的相对距离的
    • 运动矢量是通过运动搜索得到的,而 运动搜索 是在 参考帧 中进行的。通常会使用 钻石搜索六边形搜索快速运动搜索 算法。一般不会使用全搜索算法。其中钻石搜索算法更简单,步骤更少,所以如果需要编码速度快,一般选择钻石搜索。六边形搜索步骤更多,更精细,要求编码质量高,同时对速度要求不高的时候,可以选择六边形搜索。
    • 为了能够更准确的找到预测块,我们可以将16x16的宏块继续划分成更小的子块来做运动搜索。因为图像有的地方静止的背景画面或者平坦的区域可以直接选用最大的块来搜索预测块;而有的地方细节很多,图像中的物体运动方向也各不相同,可能就需要划分成更小的块来做运动搜索。这样每一个块都拥有自己独立的运动矢量,并且得到的预测块更接近于编码块,从而有利于提高压缩效率。
    • 光做整像素运动搜索不太能够准确的处理连续运动场景。为了能够处理好这种连续运动的问题,对参考帧进行亚像素插值得到半像素和1/4像素图像。然后在整像素搜索的基础上在亚像素图像上做亚像素精度的运动搜索。实验数据证明,半像素和1/4像素精度的运动搜索相比整像素精度的运动搜索可以明显地提高压缩效率。

DCT变换和量化

  • DCT变换,就是 离散余弦变换 。它能够将空域的信号(对于图像来说,空域就是平时看到的图像)转换到频域(对于图像来说,就是将图像做完DCT变换之后的数据)上表示,并能够比较好的去除相关性。其主要用于视频压缩领域。现在常用的视频压缩算法中基本上都有DCT变换。
  • 图片经过DCT变换之后,低频信息集中在左上角,而高频信息则分散在其它的位置。通常情况下,图片的高频信息多但是幅值比较小。高频信息主要描述图片的边缘信息。
  • 由于人眼的视觉敏感度是有限的,有的时候我们去除了一部分高频信息之后,人眼看上去感觉区别并不大。因此,可以先将图片DCT变换到频域,然后再去除一些高频信息。这样就可以减少信息量,从而达到压缩的目的。DCT 变换本身是无损的,同时也是可逆的。可以通过DCT变换将图片从空域转换到频域,也可以通过DCT反变换将图片从频域转回到空域。
  • 在视频压缩中,DCT变换是在帧内预测和帧间预测之后进行的 。也就是说,DCT变换其实是对残差块做的。我们在编码时会将图像划分成一个个宏块,而宏块又可以划分成一个个子块。
  • 让变换块的系数都同时除以一个值,这个值我们称之为量化步长,也就是QStep(QStep 是编码器内部的概念,用户一般使用量化参数 QP 这个值,QP 和 QStep一一对应),得到的结果就是量化后的系数。
  • 通常QStep值越大,DC系数和AC系数被量化成0的概率也就越大,从而压缩程度就越大,但是丢失的信息也就越多 。这个值太大了会造成视频出现一个个块状的效应,且严重的时候看起来像马赛克一样;这个值比较小的话,压缩程度也会比较小,从而图像失真就会比较小,但是压缩之后的码流大小就会比较大。
  • 量化其实就是一个除法操作。通过除法操作就可以将幅值变小,而高频信息幅值比较小,就比较容易被量化成0,这样就能够达到压缩的目的。
  • 在H264标准中,我们不会直接使用标准的DCT变换和量化。为了减少多次浮点型运算在解码端产生漂移的问题,H264使用整数变换代替DCT变换。DCT变换中的浮点运算部分跟量化过程进行合并,将两次浮点型运算变成一次,从而减少误差。

图像缩放

图像的缩放就是将原图像的已有像素经过 加权 运算得到目标图像的目标像素。

放大 缩小

插值算法

插值算法

  • 最近邻插值

    最近邻插值

    最近邻插值有一个明显的缺点 -- 结果图像变化不平滑,就是它直接使用离插值位置最近的整数位置的像素作为插值像素,这样会导致相邻两个插值像素有很大的概率是相同的。这样得到的放大图像大概率会出现块状效应,而缩小图像容易出现锯齿。这是最近邻插值的缺点。但是它也有一个优点,就是不需要太多的计算,速度非常的快。

  • 双线性插值

    双线性插值

    双线性插值需要将周围4个像素值通过一定的运算得到最后的插值像素。

    线性插值计算

    线性插值是一种以距离作为权重的插值方式,距离越近权重越大,距离越远权重越小。

    双线性插值计算

    双线性插值本质上就是在两个方向上做线性插值,是三次线性插值的过程。

  • 双三次插值(BiCubic)

    双三次插值 双三次插值计算

    双三次插值需要计算16个点的权重再乘以像素值求和。

    BiCubic基函数

    周围像素的权重计算是使用一个特殊的BiCubic基函数来计算的。

AI超分算法

音频技术

音频主要概念

  • 采样频率:1秒内采集到的采样点的个数,一般用赫兹Hz来表示。根据奈奎斯特采样定理在进行模拟/数字信号的转换过程中,当采样频率fs大于信号中最高频率fmax的2倍时,采样之后的数字信号才可以完整地保留原始信号中的信息。也就是说采样率和保留的声音频率基本上是2倍的关系。
  • 位深:振动幅度的表达精确程度或者说粒度。
  • 通道数:同一时间采集或播放的音频信号的总数。
  • 比特率:每秒传输的bit数,间接衡量声音质量的一个标准。没有压缩的音频数据的比特率 = 采样频率 * 采样精度 * 通道数。
  • 码率:压缩后的音频数据的比特率。
    • 码率越大,压缩效率越低,音质越好,压缩后数据越大。
    • 码率 = 音频文件大小 / 时长。
  • 帧:每次编码的采样单元数,比如MP3通常是 1152 个采样点作为一个编码单元,AAC通常是 1024 个采样点作为一个编码单元。
  • 帧长:可以指每帧播放持续的时间。每帧持续时间(秒)= 每帧采样点数 / 采样频率(HZ)。比如:MP3 48k,1152个采样点,每帧则为24毫秒,1152/48000 = 0.024秒 = 24毫秒;也可以指压缩后每帧的数据长度。
  • 交错模式:数字音频信号存储的方式。数据以连续帧的方式存放,即首先记录帧1的左声道样本和右声道样本,再开始帧2的记录...
  • 非交错模式:首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本。
  • 数字音频压缩编码在保证信号在听觉方面不产生失真的前提下,对音频数据信号进行尽可能大的压缩,降低数据量。数字音频压缩编码采取去除声音信号中冗余成分的方法来实现。所谓冗余成分指的是音频中不能被人耳感知到的信号,它们对确定声音的音色,音调等信息没有任何的帮助。

音频质量测评方法

主观评价方法

  • MUSHRA
    • 在测试语料中混入无损音源作为参考(上限),全损音源作为锚点(下限),通过双盲听测试,对待测音源和隐藏参考音源与锚点进行主观评分。
  • MOS
  • ABX Test

客观评价方法

  • 有参考音频质量评价
    • PESQ 语音质量感知评价,该算法主要用来评估窄带(8kHz采样率)及宽带(16kHz采样率)下的编解码损伤。
    • POLQA 可评估的带宽更广,对噪声信号和延时的鲁棒性更好,其语音质量评分也更接近于主观的评分。
    • ViSQOL
  • 无参考音频质量评价
    • ITU-T P.563
    • ANIQUE+
    • E-model
    • ITU-T P.1201

音频处理

音频降噪

音频降噪

  • 在降噪这个领域,模型的输入是带噪的语音信号,模型的输出是纯净的语音信号,通过大量的这样成对的带噪和纯净的语音数据,来训练AI模型,使其具有降噪的能力。
  • AI模型常用的结构包括DNN、CNN和RNN等。AI降噪模型在结构设计时,可以选择其中一种,也可以把这些结构组合使用。
  • AI降噪模型一般采用有监督的训练方式,并以带噪语音作为模型的输入、纯净语音作为训练的目标。利用反向传播结合梯度下降的方法不断提升模型预估和纯净语音的相似程度。

回声消除

回声消除

  • 常见的回声消除(AEC)流程包括双讲检测、延迟估计、线性回声消除、非线性回声消除等步骤。
  • AEC需要对回声路径做估计,如果有别的模块放在AEC之前就会导致回声路径无法收敛到正确的位置。

音视频流媒体

封装

  • 音视频封装其实就是将一帧帧视频和音频数据按照对应封装的标准有组织地存放在一个文件里面,并且再存放一些额外的基础信息,比如说分辨率、采样率等信息。
  • 一般来说,视频文件的后缀名就是它的封装格式。

音视频同步

  • DTS(Decoding Time Stamp):解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
  • PTS(Presentation Time Stamp):显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
  • 音视频同步方式:
    名称 实现
    Audio Master 同步视频到音频
    Video Master 同步音频到视频
    External Clock Master 同步音频和视频到外部时钟
    • 一般情况下选择:Audio Master > External Clock Master > Video Master

带宽预测

带宽预测

  • 带宽预测,就是实时预测当前的网络带宽大小。预测出实际的带宽之后,就可以控制音视频数据的发送数据量。
  • 现在的网络中,大多存在两种类型的网络设备:一种是有较大缓存的;一种是没有缓存或者缓存很小的。
    • 前者在网络中需要转发数据过多的时候,会把数据先缓存在自己的缓冲队列中,等待前面的数据发送完之后再发送当前数据。这种情况就会在网络带宽不够的时候,需要当前数据等一段时间才能发送,因此表现出来的现象就是网络不好时,延时 会加大。
    • 后者在网络中需要发送的数据过多的时候,会直接将超过带宽承受能力的数据丢弃掉。这种情况就会在网络带宽不够的时候,出现高 丢包 的现象。

基于延时的带宽预测算法

  • 基于延时的带宽预测算法主要是通过计算一组RTP包的发送时长和接收时长,来判断当前延时的变化趋势,并根据当前的延时变化趋势来调整更新预测的带宽值。

发送时长和接收时长

  • 计算延时
    • 计算延时的时候是将RTP包按照发送时间来分组的,并且要求当前组中的第一个包和最后一个包的发送时间相差不能大于5ms,而大于5ms则是新的一组的开始。
    • 由于UDP会出现包乱序到达的情况,可能导致后面包的发送时间比前面包的还小。为了防止这种情况的发生,要求乱序的包不参与计算。
    • 发送端在发送每一个RTP包的时候会记录每一个包的包序号和实际发送时间,并把这些信息记录到一个发送历史数据里面方便之后计算使用。
    • 接收端收到每一个包的时候也会记录包的包序号和实际的接收时间。每隔一段时间就会将这些统计信息(通过RTCP协议的Transport-CC报文反馈)发送到发送端。
    • 发送端可以根据发送历史数据中各个包的发送时间和Transport-CC报文中计算得到的各个包的接收时间,来计算出前后两组包之间的发送时长和接收时长了。
  • 需要通过当前延时和历史延时数据来判断延时变化的趋势,来平滑掉网络噪声引起的单个延时抖动。
  • 延时变化的趋势计算
    • Trendline Filter中保存了20个最近的延时数据。
    • 包含了两个部分:一个是当前这个RTP包组所属的Transport-CC报文到达发送端的时间;另一个是经过平滑后的累积延时,它是通过前面计算得到的延时和历史累积延时加权平均计算之后得到的。这样也可以一定程度上防止延时波动太大的问题。
  • 过载检测器有两个主要的工作:一个是通过当前的延时趋势和延时阈值来判断当前网络是处于过载、欠载还是正常状态;一个是通过当前的延时趋势来更新延时阈值,延时阈值不是静态不变的,阈值是跟着延时趋势不断自适应调整的。

延时判断

  • WebRTC认为欠载主要发生前面因为过载了在网络设备中缓存了一定数据,之后网络状况变好了的时候,网络设备可以快速的发送完缓存中的数据,从而排空缓存。这个时候不要提高发送码率,等缓存排空之后,因为缓存带来的延时就会接近于0了,这对于降低端到端延时是很有用的,而过载检测器自然就会进入到正常状态。这样状态机就可以切换到上升状态,从而也就可以调高预估带宽值了。
  • 发送码率可能会超出网络承受能力,不一定能很好的反映真实的网络带宽,接收端的接收码率更能够表示真实的网络带宽。

基于丢包的带宽预测算法

  • 根据Transport-CC报文反馈的信息计算丢包率,然后再根据丢包率的多少直接进行带宽调整更新。

最大带宽探测算法

  • 一般是在程序刚开始启动的时候使用并在程序运行的过程中进行周期性的探测(发送倍数于当前带宽的数据并根据反馈判断调整),每隔一段时间定时探测一下。
  • 也可以在实际发送带宽很小的时候探测一下,防止出现因为实际发送码率很小,而无法准确预测网络当前最大带宽值的问题。

码率控制

码率控制

  • 码控就是为每一帧编码图像选择一个合适的QP值的过程。

VBR

  • VBR指的是编码器输出码率随着原始视频画面复杂度的变化不断的变化。
  • 通常当画面复杂或者说运动比较多的时候使用的码率会比较高;而当画面比较简单的时候使用的码率会比较低。
  • VBR主要的目标是保证视频画面质量,因此比较适合视频点播和短视频场景使用。

CQP

  • CQP就是从头到尾每一个画面都是用同一个QP值去编码。
  • CQP一般用来衡量编码算法的性能,在实际工程当中不会使用。

CRF

  • CRF是x264默认的码控算法,它的QP是会变化的。
  • 在画面运动大的时候,它会根据具体算法提高QP值;在画面运动小的时候,它会降低QP值。

CBR

CBR

  • CBR需要设置一个目标码率值给编码器。编码器在编码的时候不管图像画面复杂或简单、运动多或运动少的时候,都尽量使得输出的码率接近设置的目标码率。
  • CBR根据一段时间内前面已经编码的结果来调节还未编码帧的QP,从而来达到一组帧的输出大小尽量接近目标码率的。
  • CBR非常适合RTC场景,因为RTC场景希望编码的码率跟实际预测的带宽值接近,不能超出目标码率太多,也希望能够尽量有效地利用可用带宽,不能太低于目标码率,从而尽量保证编码后图像画面清晰。

丢包补偿

  • 丢包补偿包括基于发送端补偿和基于接受端补偿。
  • 基于发送端补偿包括前向差错纠正、交织和重传技术;基于接受端补偿包括了多种错误隐蔽算法。

前向差错纠正

与媒体无关前向差错纠正

  • 与媒体无关前向差错纠正
    • 每n个媒体数据包附带k个校验包。
    • 校验包的每个比特都是由相关的数据包的同位置比特产生的。
    • 补偿与具体的媒体内容无关,计算量小,易于实施。
    • 不能立即解码,引入延时,带宽增加。

媒体相关前向差错纠正

  • 媒体相关前向差错纠正
    • 采用多个包传送同样的音频单元。一旦丢了一个,信息可以从另外一个包含该单元的恢复出来。
    • 第一个传输的复本称为主要编码,第二个传输的复本称为次要编码。次要编码可以是和第一个相同,但是大部分采用较低码率和较低音质的编码技术。编码器的选择取决于带宽需求和计算复杂度需求。

交织

交织

  • 长时间的丢包给听觉带来不舒适和难以理解,但是短时间的单元丢失是更易被听觉接受的,也容易理解。
  • 错误隐藏比较容易处理短时间的单元丢失,因为时间短语音的变化小。
  • 交织的不足就是也会引入延时,只适合非交互式的应用。交织的另外一大好处就是不会引起带宽需求的增加。

丢包重传

丢包重传

  • 丢包重传请求策略是在Jitter Buffer里面实现的。当接收端接收到视频RTP包之后,会检查RTP序列号。
  • 因为UDP经常会出现乱序到达的情况,如果中间的包后面到来了,也就是说RTP包序号小于收到的最大RTP包序号,Jitter Buffer就将这个包序号从丢包列表中删除,防止重复传输。
  • 如果接收端等待一个RTT的时间后还没有收到对应序号的RTP包,则再次将该序号加入到重传请求中,不能每次NACK请求都把所有丢包列表中的序号加入到报文中,防止重传重复发送,加重网络负担。
  • 重传也是有次数限制的。如果一个包重传请求发送了好几次,还没有收到,那就不再将该包加入到NACK报文中了。

强制I帧

  • 如果前面策略都用上了,还是出现了有包没有收到,导致帧不完整,继而导致没有帧可以解码成功的话,那么就需要使出关键帧请求,强制I帧请求。

  • 帧完整性判断

    帧完整性判断

    • 找到帧的第一个Slice,而Slice也判断了是完整的,再通过RTP头的M标志位判断了帧的最后一个包。如果第一个Slice的第一个包到帧的最后一个包之间的RTP包都收到 了,那就代表帧完整了。

    WebRTC帧完整性判断

    • WebRTC中在使用的方法,就是将每一个收到的包都排好序放在队列里面。Jitter Buffer收到了当前帧的最后一个包(RTP头的标志位M为 1)之后,从这个包往前遍历,要求RTP序列号一直连续,直到RTP时间戳出现一个跳变,代表已经到了前面帧的包了。

基于接收端的丢包补偿

  • 当发送端不能做到较好的丢包补偿或发送端不能参与丢包补偿时,需要在接受端进行丢包补偿。错误隐蔽算法就是接受端的丢包补偿技术,它产生一个与丢失的语音包相似的替代语音。这种技术的可能性是基于语音的短时语音相似性,它可以处理较小的丢包率(<15%)和较小的语音包(4-40ms)。当丢包的长度达到音素的长度(5-100ms),该技术就不适应了,因为整个音素都会丢失。
  • 基于插入的方法
  • 基于插值的方法
  • 基于重构的方法

SVC

  • SVC编码,也叫做可伸缩视频编码。可以实现在一个码流里面包含多个可解码的子码流,服务器可以根据接收端的网络状况,下发对应码率的码流,从而实现可伸缩性。

  • 根据是在帧率上做SVC还是在分辨率上做SVC,可以将SVC分为时域SVC和空域SVC两种。

    • 时域SVC

    时域SVC

    • 通过调整参考帧结构就能实现分层编码。低层的帧不会参考高层的帧。如果丢弃高层的帧,低层的帧也是可以顺利地完成解码而不会出现花屏的,只是帧率会降低。但是相比连续参考结构中丢失一帧就直接卡死的体验要好很多。
    • 因为只需要调整一下参考结构,本身常用的编码标准都支持这种参考帧选择的方式,是符合常规标准的。因此,解码器都支持,没有兼容性问题。
    • 一般自然运动是连续的,选择前一帧作为参考帧一般压缩率会比较高,因为前后相邻的两帧很相似。而时域SVC这种跨帧参考的方式会使得压缩率有一定的下降。两层 SVC编码效率大概下降10%,三层大概下降15%。
    • openh264已经实现了最大4层的时域SVC。
    • 空域SVC

    空域SVC

    • 空域SVC是在分辨率上做分层。
    • H264、H265、VP8这些常用的编码标准(除了扩展)都是不支持空域SVC的。市面上的绝大多数的解码器也都不支持空域SVC这种一个码流里面含有多种分辨率的视频码流解码。

常见问题

花屏卡屏

多人实时音视频聊天架构

  • Mesh

    Mesh

  • Mixer

    Mixer

  • Router

    Router