余温|SEI那些事儿,FFmpeg从入门到精通——进阶篇

作者:阿曾
前言在直播应用的开发过程中 , 如果把主播端消息事件传递到观众端 , 一般会以InstantMessaging(即时通讯)的方式传递过去 , 但因为消息分发通道和直播通道是分开的 , 因此消息与直播音视频数据的同步性就会出现很多问题 。 那么有没有在音视频内部传递消息的方法呢?答案是SEI 。
金山云目前推出的直播问答解决方案中 , 就用到了SEI , 阿曾作为一名视频云架构资深开发工程师 , 对于与视频相关的技术有着深刻的实践经验 , 今天给大家分享一下关于SEI的技术细节 。
流媒体是采用流式传输方式在网络上播放的媒体格式 , 视频网站内容、短视频、在线直播这些视频形态 , 均属于流媒体的不同分支 。 流媒体大致包含三个层级:码流、封装和协议 。 从音视频编码器输出的码流 , 经过某种封装格式后 , 经过特定的协议传输、保存 , 构成了流媒体世界的基础功能 。
SEI即补充增强信息(SupplementalEnhancementInformation) , 属于码流范畴 , 它提供了向视频码流中加入额外信息的方法 , 是H.264/H.265这些视频压缩标准的特性之一 。 SEI的基本特征如下:
1.并非解码过程的必须选项
2.可能对解码过程(容错、纠错)有帮助
3.集成在视频码流中
也就是说 , 视频编码器在输出视频码流的时候 , 可以不提供SEI信息 。 虽然在视频的传输过程、解封装、解码这些环节 , 都可能因为某种原因丢弃SEI内容 , 但在视频内容的生成端和传输过程中 , 是可以插入SEI信息的 。 这些插入的信息 , 和其他视频内容一同经过传输链路到达消费端 。 举例来说 , 当前火爆的直播问答模式 , 就是通过SEI传递较多和答题业务相关的信息 , 通过SEI承载的信息 , 极大地优化了题目显示和观众音视频观看的同步性 。
那么在SEI中可以添加哪些信息呢?以下是一些用户场景可任意扩展的例子:
1.传递编码器参数
2.传递视频版权信息
3.传递摄像头参数
4.传递内容生成过程中的剪辑事件(引发场景切换)
对于SEI如何应用 , 我们先以H.264/AVC这一视频编码标准为例 。 在这一标准中 , 整个系统框架分为两层:视频编码层面(VideoCodingLayer , 简称VCL)和网络抽象层面(NetworkAbstractionLayer , 简称NAL) 。 VCL负责表示有效视频数据的内容 , NAL负责格式化数据并提供头信息 , 以保证数据适合各种信道和存储介质上的传输 。 NALunit是NAL的基本语法结构 , 它包含一个字节的头信息(NALheader)和一系列来自VCL的原始数据字节流(RBSP) 。
H.264/AVC中的情况NALunittype储存在NALheader中 , 在H.264/AVC标准中 , 可用的NALunittype一共有17种 , 作用是告诉解码器 , 承载的数据是视频关键帧 , 还是视频解码器的配置参数信息 。 其中值为6时表征SEI内容 。 比较常见的类型如下表所示:
如上图所示 , 在8bits的NALheader中:
1.第0位是禁止位0 , 值为1时表示语法出错
2.第1~2位是参考级别(NRI , NALrefidc)
3.第3~7位是NALunittype
需要注意的是 , 当NRI取值为"00"(二进制)时 , 表征NALunit不参与重建参考图像 , 这时的NALunit是可以丢弃的 。 大于"00"(二进制)时 , NALunit不能被丢弃 。