首页 > IT业界 > 国内 > 正文

FFmpeg从入门到精通:SEI那些事
2018-02-09 15:09        我要评论()
字号:T|T

流媒体是采用流式传输方式在网络上播放的媒体格式,视频网站内容、短视频、在线直播这些视频形态,均属于流媒体的不同分支。流媒体大致包含三个层级:码流、封装和协议。从音视频编码器输出的码流,经过某种封装格式后,经过特定的协议传输、保存,构成了流媒体世界的基础功能。

  在直播应用的开发过程中,如果把主播端消息事件传递到观众端,一般会以Instant Messaging(即时通讯)的方式传递过去,但因为消息分发通道和直播通道是分开的,因此消息与直播音视频数据的同步性就会出现很多问题。那么有没有在音视频内部传递消息的方法呢?答案是SEI(Supplemental Enhancement Information)。金山云目前推出的直播问答解决方案中,就用到了SEI,作为一名视频云架构资深开发工程师,今天就来和大家分享一下SEI的技术细节。
 
  SEI介绍
 
  SEI即补充增强信息,属于码流范畴,它提供了向视频码流中加入额外信息的方法,是H.264/H.265这些视频压缩标准的特性之一。SEI的基本特征如下:
 
  1.并非解码过程的必须选项
 
  2.可能对解码过程(容错、纠错)有帮助
 
  3.集成在视频码流中
 
  也就是说,视频编码器在输出视频码流的时候,可以不提供SEI信息。虽然在视频的传输过程、解封装、解码这些环节,都可能因为某种原因丢弃SEI内容,但在视频内容的生成端和传输过程中,是可以插入SEI信息的。这些插入的信息,和其他视频内容一同经过传输链路到达消费端。举例来说,当前火爆的直播问答模式,就是通过SEI传递较多和答题业务相关的信息,通过SEI承载的信息,极大地优化了题目显示和观众音视频观看的同步性。
 
  那么在SEI中可以添加哪些信息呢?以下是一些用户场景可任意扩展的例子:
 
  1.传递编码器参数
 
  2.传递视频版权信息
 
  3.传递摄像头参数
 
  4.传递内容生成过程中的剪辑事件(引发场景切换)
 
  对于SEI如何应用,我们先以H.264/AVC这一视频编码标准为例。在这一标准中,整个系统框架分为两层:视频编码层面(Video Coding Layer,简称VCL)和网络抽象层面(Network Abstraction Layer,简称NAL)。VCL负责表示有效视频数据的内容,NAL负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL unit是NAL的基本语法结构,它包含一个字节的头信息(NAL header)和一系列来自VCL的原始数据字节流(RBSP)。
 
  H.264/AVC中的情况
 
  NAL unit type储存在NAL header中,在H.264/AVC标准中,可用的NAL unit type一共有17种,作用是高速解码器,承载的数据是视频关键帧,还是视频解码器的配置参数信息。其中值为6时表征SEI内容。比较常见的类型如下表所示:

121

 
  H.264/AVC中完整的NAL unit类型定义请参考《ISO/IEC 14496-10:2014》,这是MPEG专家组为AVC编解码器制定的标准,H.264/AVC中NAL unit类型完整定义都在该标准的7-1表中,标准一共预留了32种类型,在NAL header里面,用5 bits表征NAL unit type。

122

  H.264/AVC中的NAL unit type
 
  如上图所示,在8 bits的NAL header中:
 
  1.第0位是禁止位0,值为1时表示语法出错
 
  2.第1~2位是参考级别(NRI,NAL ref idc)
 
  3.第3~7位是NAL unit type
 
  需要注意的是,当NRI取值为"00"(二进制)时,表征NAL unit不参与重建参考图像,这时的NAL unit是可以丢弃的。大于"00"(二进制)时,NAL unit不能被丢弃。

123

  H.265/HEVC中的情况
 
  《ISO/IEC 23008-2:2015》是MPEG专家组为HEVC编解码器制定的标准,H.265/HEVC中NAL unit类型完整定义都在该标准的7-1表中,可用的NAL unit type一共有40种之多,其中39和40都表征SEI内容。因为标准一共预留64种类型,所以在NAL header里面,用6 bits表征NAL unit type。

124

  H.265/HEVC中的NAL unit type
 
  如上图所示,在16 bits的NAL header中:
 
  1.第0位是禁止位0,值为1时表示语法出错
 
  2.第1~6位是NAL unit type
 
  3.第7~12位是NUH layer id
 
  4.第13~15位是temporal_id
 
  SEI类型
 
  在H.264/AVC视频编码标准中,并没有规定SEI payload type的范围,所以表征payload type的字节数是浮动的。
 
  语法分析如下所示,当开始解析类型为SEI的NAL时,持续读取8bit,直到非0xff为止,然后把读取的数值累加,累加值即为SEI payload type。
 
  sei_message(){
 
  payloadType = 0
 
  while( next_bits(8) == 0xFF){
 
  ff_byte
 
  payloadType += 255
 
  }
 
  last_payload_type_byte
 
  payloadType += last_payload_type_byte
 
  }
 
  读取SEI payload size和payload type逻辑类似,仍然是读取到0xff为止,这样可以支持任意长度的SEI payload添加。
 
  sei_message(){
 
  payloadSize = 0
 
  while( next_bits(8) == 0xFF){
 
  ff_byte
 
  payloadSize += 255
 
  }
 
  last_payload_size_byte
 
  payloadSize += last_payload_size_byte
 
  }
 
  当获取了SEI payload类型和大小后,就进入了实际的SEI内容读取。
 
  当前《ISO/IEC 14496-10:2014》Annex D.1.1提供了最大到181的payload类型处理规范,由于类型可以指定任意大小,给SEI的添加、处理创造了很大的自由空间。
 
  其中SEI payload类型值为5时,指定的处理方法叫user_data_unregistered(),字面含义为未注册的用户数据,常用于存储编码器的编码参数信息,是比较常见的payload类型。
 
  读取payload type为5时,具体的语法解析流程如下:
 
  user_data_unregistered(payloadSize){
 
  uuid_iso_iec_11578
 
  for( i=16; i< payloadSize; i++)
 
  user_data_payload_byte
 
  }
 
  其中uuid_iso_iec_11578的详细定义在《ISO/IEC 11578:1996》 Annex A中,大致规定了使用128 bits(16个字节)来指定UUID。此处UUID可以表征写入SEI payload的角色ID,或者表征其他业务用途。剩下的payloadSize -16字节,即是业务层传递的具体内容了。
 
  通过user_data_unregistered()语法解析可以看出,当使用SEI payload type为5时,注意事项如下:
 
  1.payload size应该大于16;
 
  2.uuid可能出现0x000000/0x000001/0x000002,需要插入0x03做防竞争处理;
 
  构成RBSP时,都需要做RBSP拖尾处理。拖尾处理对所有SODB方式都一致。rbsp_trailing_bits()语法逻辑如下:
 
  rbsp_trailing_bits( ){
 
  rbsp_stop_one_bit
 
  while( !byte_aligned( ) )
 
  rbsp_alignment_zero_bit
 
  }
 

联系电话:13811959286

IT频道纠错邮箱:erjuner@163.com

责任编辑:新闻中心

我要评论

已有位网友参与评论

关于我们 | 新闻投稿 | 软件发布 | 版权声明 | 意见建议 | 网站地图 | 友情连接 | RSS订阅 | 总编信箱 | 诚聘英才 | 联系我们

苏ICP备11016551号-2  苏公网安备 32132202000111号 本站特聘法律顾问:于国富律师

Copyright (C) 1997-2018 newhua.com 江苏奥蓝德软件有限公司 版权所有