H264视频流 解析SEI信息

2023-09-20  本文已影响0人  空空小僧

1. SEI的介绍

补充增强信息(Supplemental Enhancement Information)是码流范畴里面的概念,提供了向视频码流中加入信息的办法,是H.264/H.265 视频压缩标准的特性之一。SEI 有基本的特征:

  1. 并不是解码过程的必须项;

  2. 有可能对解码过程(容错、纠错)有帮助;

  3. 集成在视频码流中;

这意味着视频编码器在输出视频码流的时候,可以不提供SEI信息 。同时我们也要清楚:视频传输过程、解封装、解码环节,都可能因为某种原因丢弃SEI 。 在视频内容的生成端、传输过程中,都可以插入SEI 信息。插入的信息,和其他视频内容一起经过传输链路到达了消费端。那么在SEI 中可以添加哪些信息呢?这里举几个例子,用户场景可以任意扩展:

  1. 传递编码器参数;

  2. 传递视频版权信息;

  3. 传递摄像头参数;

  4. 传递内容生成过程中的剪辑事件(引发场景切换);

1.1 NAL unit类型

网络抽象层(Network Abstract Layer)简称为NAL。在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(Video Coding Layer - VCL)和网络抽象层面(Network Abstraction Layer - NAL)。VCL负责表示有效视频数据的内容,NAL 负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL unit是NAL的基本语法结构,它包含一个字节的头信息(NAL header)和一系列来自VCL的原始数据字节流(RBSP),

为了方便从字节流中提取出 NALU,协议规定,在每个 NALU 的前面加上起始码(StartCode): 0x000001 或 0x00000001。

NALU 组成结构

NALU(NAL Unit)= 一组对应于视频编码的 NALU 头部信息(NAL header)+ 一个 RBSP(Raw Byte Sequence Payload,原始字节序列负荷)

74f31f05c68776da6bf8fcfb43904dba.png

NALU Header 组成结构

NALU Header 由 8 bit 组成,其中最后的 5 bit 表示 NAL Unit Type,具体结构⻅下图:

6f2cd955867ac568552bd6ee5ff9ed55.png
NAL Unit Type NAL Unit Content
1 非 IDR 图像,且不采用数据划分的片段
5 IDR 图像
6 补充增强信息(SEI)
7 序列参数集(SPS)
8 图像参数集(PPS)
11 流结束符

SEI payload type 计算方式

当开始解析类型为 SEI 的 NAL 时,在 RBSP 中持续读取 8 bit,直到非 0xff 为止,然后把读取的数值累加,累加值即为 SEI payload type。


08175421_634148cdbf89335366.jpeg

SEI RBSP 结构图如下:

b007b85fffa3ef9d42fd0228cdda1c37.png

SEI payload size 计算方式

读取 SEI payload size 的逻辑与 SEI payload type 类似,即读取到非 0xff 为止,这样可以支持任意⻓度的 SEI payload 添加。假设 SEI payload type 后面的字符序列是 FF FF AA BB ….,则 FF FF AA 将会解析成 SEI payload size,为 255 + 255 + 170 = 680。


08175421_634148cdd390698099.jpeg

SEI payload代表的不同含义

其中SEI payload类型值为5时,指定的处理方法叫user_data_unregistered(),字面含义为未注册的用户数据,常用于存储编码器的编码参数信息,是比较常见的payload类型


image2023-9-14_20-33-38 (1).png

通过user_data_unregistered()语法解析可以看出,当使用SEI payload type为5时,注意事项如下:

  1. payload size应该大于16;

  2. uuid可能出现0x000000/0x000001/0x000002,需要插入0x03做防竞争处理;

实践 视频片段:以m3u8的视频片段ts文件为例

资源地址: https://github.com/yangfangkuo/CommonFile/raw/master/test_SEI_-1694589490969.ts
https://github.com/yangfangkuo/CommonFile/raw/master/test_SEI_-1694589490969.ts

image2023-9-14_20-22-57.png

通过查找字节位为 0x000001或者0x00000001 开头的为每一个NALU模块的开头,后面跟着0x06的为SEI信息单元

所以找到图片中红色区域的片段,0x00000106代表当前是一个SEI的NALU模块

然后从RSBP里面读取SEI的payLoadType, 读取到第一个非0xFF的字节,读取到05,表示payLoadType为5,常见的还有242,代表不同的SEI解析方法,然后继续计算payload的size,读取到第一个非0xFF的字节,当前读取到的为0x1A,转换为10进制为26,表示当前的payload内容的size为26个字节

payload为5,表示从payloadContent开始,前16个字节为当前SE的uuid,后面为SEI的信息,获取10个字节,获得二进制内容转换为文本内容为“yifantest” ,字符串有结束符0x00,

image2023-9-14_20-28-0.png

参考文档:https://blog.51cto.com/u_12127193/5739423
https://blog.csdn.net/Lucky_wu24/article/details/130618228

上一篇下一篇

猜你喜欢

热点阅读