H264/SVC Temporal Scalability

在多人远程会议或直播系统中,参与的用户可能处于不同的网络环境(有线、wifi、3G、4G)中,网络质量各不一致,为了所有用户可进行远程会议或者直播的观看,简单的做法就是降低发送端的视频码流,这样不管网络质量好坏,参与的用户都将观看低码率的视频流。这种方案缺点在于大部分网络较好的用户会被少数的网络较差的用户给拖累。这里介绍 H264 编码器中的 Temporal Scalability 机制来优化该方案。

Temporal Scalability 是 H264/SVC 编码器中的概念,意思为时间上可伸缩的,在实际编码中编码器进行了分层编码,可简单的理解为 编码器对同一组输入的数据进行编码,可以输出不同帧率的码流,例如当前编码器输入帧率为 30fps 的流,编码器可同时输出多个码流,例如同时输出 3 层码流,从而可以得到不同帧率的码流。

这里的 3 层码流是有依赖关系,比如输出有 A、B、C 3 层码流,单独的发送 A 层则得到低帧率的码流例如 5fps,如果同时发送 A 和 B 两层码流,则能得到相对较高的码流例如 15fps,如果同时发送 ABC ,则能得到最高的码流例如 30fps。

在具体应用中便可以根据用户的网络质量来分配不同码率的视频流,这样网络质量较好的用户能看到高帧率的视频流,而网络较差的用户则看到低帧率的视频流。如下图所示:

Alt text

编码器进行了分层编码,例如上图描述编码端同时将所有的码流层发送至服务器,如果用户网络质量非常好,服务器将所有层的码流数据转发至该用户例如 Receiver2;如果用户网络非常差,则只需要将低层级码流数据转发给该用户例如 Receiver1。

编码器的支持

Temporal Scalability 机制并不是所有的编码都支持的,Apple 平台下(包括iOS和MacOS)的硬件编解码框架 VideoToolbox 是不支持的该特性的,因为没有看到任何的可设置的参数或者 API 接口。Android 平台下硬件编解码框架 MediaCodec 在 API 21 一下是不支持的,在 API 21 时添加了对 KEY_TEMPORAL_LAYERING 编码属性的配置,但只支持 VP8 编码格式 H264 编码格式不支持(毕竟 Android 和 VPx 都是属于 Google 的产品)。Android 下有需要了解详情的可以查看 MediaFormat 类的说明。

在两大主流的移动平台上,硬件编码器都是不支持 H264/SVC Temporal Scalability 特性,如果要在移动平台上使用该特性只能使用软编码器,可以使用开源的 openh264 编解码库,代码托管在 GitHub 上对应的地址为 openh264 ,其中有该项目的介绍和使用方法。

x264 编码器当前还不支持 Temporal Scalability 特性。

在 openh264 中使用 SEncParamExt 结构体来对编码进行参数的配置,Temporal Scalability 的特性使用 iTemporalLayerNum 字段来配置,用来指定输出多少层最大只支持 4 层。

使用 EncodeFrame 方法进行 H264 的编码后可以得到 SFrameBSInfo 的输出结果,该结构体以及关联的结构体的定义如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

typedef struct {

int iLayerNum;

SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];

EVideoFrameType eFrameType;

int iFrameSizeInBytes;

long long uiTimeStamp;

} SFrameBSInfo, *PFrameBSInfo;

typedef struct {

unsigned char uiTemporalId;

unsigned char uiSpatialId;

unsigned char uiQualityId;

EVideoFrameType eFrameType;

unsigned char uiLayerType;

int iSubSeqId;

int iNalCount;

int* pNalLengthInByte;

unsigned char* pBsBuf;

} SLayerBSInfo, *PLayerBSInfo;

在 SLayerBSInfo 结构体的 uiTemporalId 字段用来描述当前编码后的数据流属于哪一层。openh264 的使用可查看其它文档。

openh264 对 H264/SVC 的支持,不仅在时间维度上,并且也在空间和质量维度上都有支持。

openh264 中 temporal layer 的输出顺序与帧率

在 openh264 的内部,存在一张表,用来记录每一层的输出顺序,可以在 encoder_data_tables.cpp 中找到内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

const uint8_t g_kuiTemporalIdListTable[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE + 1] = {

{

0, 0, 0, 0, 0, 0, 0, 0,

0

}, // uiGopSize = 1

{

0, 1, 0, 0, 0, 0, 0, 0,

0

}, // uiGopSize = 2

{

0, 2, 1, 2, 0, 0, 0, 0,

0

}, // uiGopSize = 4

{

0, 3, 2, 3, 1, 3, 2, 3,

0

} //uiGopSize = 8

};

解析如下:

  • iTemporalLayerNum 的值为 1 时,使用 uiGopSize = 1 的配置,即每一帧为一组,每一组的 uiTemporalId 值为 0
  • iTemporalLayerNum 的值为 2 时,使用 uiGopSize = 2 的配置,即每两帧为一组,每一组中对应的
    uiTemporalId 为 [0, 1]
  • iTemporalLayerNum 的值为 3 时,使用 uiGopSize = 4 的配置,即每四帧为一组,每一组中对应的
    uiTemporalId 为 [0, 2, 1, 2]
  • iTemporalLayerNum 的值为 4 时,使用 uiGopSize = 8 的配置,即每 8 帧为一组,每一组中对应的
    uiTemporalId 为 [0, 3, 2, 3, 1, 3, 2, 3]

根据上述描述以及输入的帧率可计算每一层的帧率是多少,例如在 30fps 下分两层输出,则 T0 帧率为 15fps;分 3 层时,每 4 帧组则有完整 7 组,则 T0 的帧率有 7 + 1 = 8fps,T1 的帧率有 8 + 7 = 15fps,T2 则有 30fps;分 4 层的情况可按相同的方法计算每一层的帧率。

RTP 数据包的封装

Temporal Scalability 属于 H264/SVC 的范畴,在封装成 RTP 包时也有对应的标准做法,但流程相对复杂,有兴趣的同学可以了解以下资料:

  • SVC的RTP封装算法及其应用
  • 可伸缩视频编解码SVC技术介绍应用分析

大致的思想是将基本层(低帧率)和增强层(高帧率)的层通过不同的 payload 分开传输,同时两个通道分别使用不同的 QoS 机制来保证传输的质量。

除了上述的较为复杂的做法外也可以使用 RTP 的扩展头来实现,在 RTP 头后面添加一个扩展头用来描述当前数据包的 temporal layer id,这样服务器就能区分 RTP 包分别属于哪个层级,从而根据客户端的网络质量来转发不同的帧率的码流。具体的做法可参考其他资料。

总结

H264/SVC 是以 H264/AVC 为基础,利用了AVC 编解码器的各种高效算法工具,在语法和工具集上进行了扩展,所以 H264/SVC 时间可扩展性完全向后兼容 H.264/AVC,即当使用 SVC 编码出多层的码流时,AVC 的编码器也是可以正常解码的。当 Temporal Scalability 帧率降低一半时,比特率通常不会降低一半,因为低层级的帧可能是其他高层级帧的参考帧,编码器会为其分配更多的码流。

由于编码端到服务器以及服务器到接收端的码流有了更灵活的传输方式,结合网络上其他的优化方案,可以衍生出更多的优化方案,例如针对低层级的丢包重传、缓存低层级的帧等。

可惜的是在 iOS 和 Android 两大主流移动平台上,对应的硬件编码器都不支持该特性,不过在分辨率不高的场景下还是可以尝试使用软编码器来实现的。一些时候用户更偏向于接受低分辨率的图像而需要更流畅的画面,这时候 Temporal Scalability 机制并不能达到要求,后续将介绍 H264/SVC 中的空间分层来解决该问题。

参考资料

  • The Scalable Video Coding Amendment of the H.264/AVC Standard
  • Rate Control Optimization for Temporal-LayerScalable Video Coding
  • Chrome’s WebRTC VP9 SVC Layer Cake: Sergio Garcia Murillo & Gustavo Garcia

H264/SVC Temporal Scalability相关推荐

  1. 音视频技术开发周刊 53期

    『音视频技术开发周刊』由LiveVideoStack团队出品,专注在音视频技术领域,纵览相关技术领域的干货和新闻投稿,每周一期.点击『阅读原文』,浏览本期内容,祝您阅读愉快. 策划 / LiveVid ...

  2. 音视频开发(42)---H.264 SVC 简介

    H.264 SVC 简介 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/CrystalShaw/article/details/81184531 一 ...

  3. webrtc之SVC实现(十)

    一.概念 SVC(可适性视频编码或可分级视频编码)是传统H.264/MPEG-4 AVC编码的延伸,可提升更大的编码弹性,并具有时间可适性(Temporal Scalability).空间可适性(Sp ...

  4. 音视频技术开发周刊 60期

    『音视频技术开发周刊』由LiveVideoStack团队出品,专注在音视频技术领域,纵览相关技术领域的干货和新闻投稿,每周一期.点击『阅读原文』,浏览第60期内容,祝您阅读愉快. 架构 Twitch ...

  5. HEVC(H.265) 基础知识

    最近由于工作需求,需要学习HEVC(High Efficiency Video Coding).最初一头雾水,都不了解这是视频压缩标准的一种.此文章,主要是为了笔者初步学习HEVC而写的学习笔记. 本 ...

  6. 【网络通信 -- 直播】视频流编码 -- H.264 编码的一般概念

    [网络通信 -- 直播]视频流编码 -- H.264 编码的一般概念 [1]色彩空间 -- RGB YUV YCbCr RGB 依据人眼识别的颜色定义出的空间,可表示大部分颜色: YUV " ...

  7. WebRTC 的现状和未来:专访 W3C WebRTC Chair Bernard Aboba

    WebRTC 无疑推动和改变了互联网视频,而这仅仅是刚刚开始,除了大家熟悉的 WebRTC-PC.Simulcast 和 SVC,有太多的新技术和新架构出现在 WebRTC 新的标准中,比如 WebT ...

  8. H263H264MPEG4

    1.H263  H.263历史  H.263是国际电联ITU-T的一个标准草案,是为低码流通信而设计的.但实际上这个标准可 用在很宽的码流范围,而非只用于低码流应用,它在许多应用中可以认为被用于取代H ...

  9. 2021 技术展望 | AV1 在 RTC 应用实践中的现状与展望

    线上会议.在线教育.电商直播等多个场景的兴起,也使得实时互动技术从幕后走到台前,得到了更多人的关注.编解码.网络传输.计算机视觉等 RTE 相关的一系列技术也正焕发出更强的生命力.2021 年,在深度 ...

最新文章

  1. 阅读代码和修改别人代码的一些技巧以及注意事项
  2. POJ1149 PIGS(最大流)
  3. 假笨说-类初始化死锁导致线程被打爆!打爆!爆!
  4. 高和父元素的高一致_首次:低温熔盐法合成菊花状三维高熵硼化物纳米花 (华南理工大学褚衍辉课题组最新研究成果)...
  5. html调用天气预报wsdl服务,webservice接口调用天气预报例程
  6. matlab画孔斯曲面,CAD CAM技术基础:第五讲 孔斯曲面
  7. 创建新DB和新用户DBeaver连接
  8. 分布式系统面试 - 常见问题
  9. android 前后同时预览_用上这些官方动态壁纸,让你的 Android 主屏简洁又优雅
  10. azure上传excel_使用MS Excel访问Azure中的关系SQL数据库
  11. 计算机教育杂志社投稿送样刊,电脑校园杂志征稿论文发表--期刊发表网网
  12. MySQL 数据库基础知识(系统化一篇入门)
  13. 汇编语言之DOSBox的安装和使用
  14. 饿了么UI库--Vue开发必备神器--让你轻松设计出好看的页面
  15. 昆仑通泰触摸屏与v20变频器uss通讯,控制变频器
  16. oracle之Number类型小数转字符串丢精度
  17. character not supported here
  18. 微信小程序组件、路由、组件通信、侦听器
  19. C\C++中头文件string与string.h的区别
  20. MySQL设置utf8mb4编码

热门文章

  1. python里order_volume_Python 基础知识:Method Resolution Order (MRO) 和 super
  2. 【openMV】霍夫变换---直线提取
  3. libevent源码深度剖析五
  4. 八皇后问题的非递归解法
  5. linux初始:命令行解释器(shell)、权限
  6. 从memcpy到memmove,内存函数拷贝与内存重叠问题(重点内容)
  7. java并发之CopyOnWriteArraySet
  8. HDU 2224 The shortest path
  9. Quartz.NET开源作业调度框架系列(二):CronTrigger-转
  10. 2017-2018-1 20155209 《信息安全系统设计基础》第一周学习总结