首页 > 其他分享 >流媒体学习5

流媒体学习5

时间:2023-12-08 14:35:26浏览次数:25  
标签:编码 流媒体 FU 解码 NAL 学习 NALU 图像

五、H264编码

  H264在视频采集到输出中属于编解码层次的数据,如下图所示,是在采集数据后做编码压缩时通过编码标准编码后所呈现的数据。

/i/?i=20180516184837257?

  常用Nalu_type: 

0x67 (0 11 00111) SPS 非常重要 type = 7 

0x68 (0 11 01000) PPS 非常重要 type = 8 

0x65 (0 11 00101) IDR帧 关键帧 非常重要 type = 5 

0x61 (0 11 00001) 非IDR的I帧 或 P帧 非常重要 type = 1  非IDR的I帧 不大常见 【这个大概率是P帧,通过工具查看某个H264的P slice,开头为00 00 00 01 61】

0x41 (0 10 00001) 非IDR的I帧 或 P帧 重要 type = 1 【非IDR的I帧P帧都是有可能的,具体通过工具分析】

0x01 (0 00 00001) B帧 不重要 type = 1 

0x06 (0 00 00110) SEI 不重要 type = 6

  所以判断是否为I帧的算法为: (NALU类型  & 0001  1111) = 5  

  最简单的办法是找0x65或0x25(I frame启始位),

  或者去找0x67或0x27(SPS)

  和0x68或0x28(PPS)后面的完整包。

  SPS和PPS后面必然跟着I frame。(68之后,出现  000001 开始就是关键帧数据 )

好,对于H.264格式了解这么多就够了,我们的目的是想从一个H.264的文件中将一个一个的NALU提取出来,然后封装成RTP包,下面介绍如何将NALU封装成RTP包。一般程序中的定义。

enum {

NAL_IDR = 5,

NAL_SEI = 6,

NAL_SPS = 7,

NAL_PPS = 8,

NAL_AUD = 9,

NAL_B_P = 1,

};

3) H264 NAL RTP打包

NALU是H264用于网络传输的单元类型,一个完整的NALU单元一般是以0x000001或者0x00000001开始,其后跟的则是NALU头和NALU的数据;我们在网络传输的时候,会去掉开始的0x000001或者0x00000001的标志;一般需要将这些标志替换为RTP payload的头部(1个字节);

RTP载荷第一个字节

格式跟NALU头一样:【后面的格式与H264的RTP打包格式相关】

F:【1 bit】 forbidden_zero_bit, 占1位,在 H.264 规范中规定了这一位必须为 0

NRI:【2 bits】 nal_ref_idc, 占2位,取值从0到3,指示这个 NALU 的重要性,取值越大约重要。

Type:【5 bits】nalu是指包含在 NAL 单元中的 RBSP 数据结构的类型,其中0未定义,1-19在264协议中有定义,20-23为264协议指定的保留位。

单一NAL单元模式

即一个 RTP 包仅由一个完整的 NALU 组成. 这种情况下 RTP NAL 头类型字段和原始的 H.264的   NALU 头类型字段是一样的。【RTP载荷第一个字节 type=1-23】

      如有一个 H.264 的 NALU 是这样的:[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]

  这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容。

  封装成 RTP 包将如下:[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ],即只要去掉 4 个字节的开始码就可以了。

组合封包模式 

即可能是由多个 NAL 单元组成一个 RTP 包. 分别有4种组合方式: STAP-A, STAP-B, MTAP16, MTAP24。 【RTP载荷第一个字节 type=24-27

    【STAP-A   单一时间的组合包     24

       STAP-B   单一时间的组合包     25

       MTAP16   多个时间的组合包    26 

       MTAP24   多个时间的组合包    27】

如下图为一个包含sps、pps的包

第一个字节为0X18(即24),表示组合封包。0x00 0x15表示一个封包的长度21,后面的21个字节为一个封包,67(01100111,00111即7为sps帧)为NAL头;0x00 0x04表示一个封包的长度4,后面的4个字节为一个封包,68(01101000,01000即8为pps帧)为NAL头

分片封包模式

对于较大的NALU,一个NALU可以分为多个RTP包发送。存在两种类型 FU-A 和 FU-B.。【RTP载荷第一个字节 type=28-29】

    【FU-A     分片的单元   28

       FU-B     分片的单元  29  

      没有定义 30-31 】

/i/l/?n=20&i=blog/2293816/202110/2293816-20211021172227545-1860999992.png

注意,FU payload中并没有传送NALU的头部,
NALU的头部由FU indicator(前3位)和FU header(后五位)组成:nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f);

  • RTP载荷第一个字节位FU Indicator,其格式如下:

高三位:与NALU第一个字节的高三位相同

Type:28<----->0x1c,表示该RTP包一个分片,为什么是28?因为H.264的规范中定义的,此外还有许多其他Type,这里不详讲。

  • RTP载荷第二个字节位FU Header,其格式如下:

S:标记该分片打包的第一个RTP包

E:比较该分片打包的最后一个RTP包

R: 占1位,保留位,为0

Type:NALU的Type,后续才是NALU data)

注意,FU payload中并没有传送NALU的头部,NALU的头部由FU indicator(前3位)和FU header(后五位)组成:nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f);

  • 第一个包

    1. RTP header中的M为0.
    2. FU Indicator为3C,即00111100, 11100即为28,表示是分片分包。
    3. FU Header为81,即10000001,即s为1,第一个封包;type为1,即b帧。
  • 中间的包

    1. RTP header中的M为0.
    2. FU Indicator为3C,即00111100, 11100即为28,表示是分片分包。
    3. FU Header为01,即00000001,即s、e都为0,中前的封包;type为1,即b帧。
  • 最后的包

    1. RTP header中的M为1.
    2. FU Indicator为3C,即00111100, 11100即为28,表示是分片分包。
    3. FU Header为41,即0 1000001,即s为0、e为1,最后的封包;type为1,即b帧。

FU-A分包方式注意点

①关于时间戳,需要注意的是h264的采样率为90000HZ(被标准固定死的,为了方便转换成npt时间,见维基百科:https://en.wikipedia.org/wiki/RTP_audio_video_profile),因此时间戳的单位为1(秒)/90000,因此如果当前视频帧率为25fps,那时间戳间隔或者说增量应该为3600,如果帧率为30fps,则增量为3000,以此类推。

②关于h264拆包,按照FU-A方式说明:
        1)第一个FU-A包的FU indicator:F应该为当前NALU头的F,而NRI应该为当前NALU头的NRI,Type则等于28,表明它是FU-A包。FU header生成方法:S = 1,E = 0,R = 0,Type则等于NALU头中的Type。
        2)后续的N个FU-A包的FU indicator和第一个是完全一样的,如果不是最后一个包,则FU header应该为:S = 0,E = 0,R = 0,Type等于NALU头中的Type。
        3)最后一个FU-A包FU header应该为:S = 0,E = 1,R = 0,Type等于NALU头中的Type。

 ③FU payload中并没有传送NALU的头部,NALU的头部由FU indicator(前3位)和FU header(后五位)组成:nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f);

 ④FU-A 还原的时候,也是0x00 00 00 01 开始,不需要自己额外添加0x00 00 00 01
 ⑤FU-A 的的解析,start end等数据要解析好
 ⑥single nal unit 也是以0x00 00 00 01开始,也不需要自己添加分隔符

标签:编码,流媒体,FU,解码,NAL,学习,NALU,图像
From: https://www.cnblogs.com/zeliangzhang/p/17887099.html

相关文章

  • 流媒体学习3
    2)详探 应用程序appapp是application的缩写,代表客户端要链接到的,rtmp服务器的应用程序,这个一般我们在nginx服务器的配置选项中可以看到。对于该object,首先使用app来表示此object表示的名称,之后按照AMF0格式来表示具体的值。此处app的值为rtmp_live,是字符串类型,占用9个字节。正好,此......
  • 流媒体学习2
    四、RTMP详解RTMP是RealTimeMessagingProtocol(实时消息传输协议)的首字母缩写。该协议是应用层协议,基于TCP。RTMP是一种设计用来进行实时通信的网络协议,主要用来在Flash平台和支持RTMP协议的流媒体/交互服务器之间进行以视频和数据通信。直播场景中使用RTMP协议比较多。1.握手RT......
  • mini-spring 学习笔记—AOP
    切点表达式ClassFilter和MethodMatcher这两个接口都定义了一个叫做mathes的方法,用于匹配ClassFilter接口规范了类匹配器的行为booleanmatches(Class<?>clazz);MethodMatcher接口规范了方法匹配器的行为booleanmatches(Methodmethod,Class<?>targetClass);Poi......
  • nerf学习
    https://www.bilibili.com/video/BV1o34y1P7Md/?spm_id_from=333.337.search-card.all.click&vd_source=d68ed178f151e80fea1e02efd205802c       δ是不透光率. 先看C(r),里面t从tn积分到tf. 他里面每一个值表示这个点的颜色作用到tf上的显示效果.T(t)......
  • Vue学习计划-Vue2--Vue核心(五)条件、列表渲染、表单数据
    1.条件渲染v-ifv-if="表达式"v-else-if="表达式"v-else="表达式"适用于:切换频率较低的场景特点:不显示dom元素,直接被删除注意:v-if和v-else-if、v-else一起使用,但要求结构不能被打断v-if和template一起使用,v-show不可以v-showv-show="表达式"适用于:切换频......
  • 【机器学习】Django,余弦距离之基于用户,评分物品的推荐
    表设计#用户表classUserInfo(models.Model):username=models.CharField(max_length=32,unique=True,verbose_name="用户名")password=models.CharField(max_length=64)#物品表classMovies(models.Model):name=models.CharField(max_length=255,v......
  • Fiori WalkThrough学习-Step02.Bootstrap
    1.Index.html<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>UI5Walkthrough</title><scriptid="sap-ui-bootstrap"src="https://openui5.hana.ondemand.co......
  • Power BI - 5分钟学习拆分列
    每天5分钟,今天介绍PowerBI拆分列功能。什么是拆分列?有时导入PowerBI的数据表中,某列内容都包含同样的特殊字符如@/&/-/_等,可以利用这个特殊字符进行拆分列的操作,获得我们想要的信息。操作举例:首先,导入一张【Sales】样例表(Excel数据源导入请参考每天5分钟第一天)。样例列内容......
  • Power BI - 5分钟学习透视列
    每天5分钟,今天介绍PowerBI透视列功能什么是透视列?透视列就是把行数据转换成列数据,也就是大家在工作中常说的'行转列'。如何进行逆透视操作:1,导入的【Sales】表,样例内容如下:2,【Home】->【Transformdata】->【Transformdata】;3,选择要透视的列【Actual/Budget】;4,......
  • # 2023-2024-1 20231308 《计算机基础与程序设计》第十一周学习总结
    2023-2024-120231308《计算机基础与程序设计》第十一周学习总结作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第十一周作业这个作业的目标计算机网络,网络拓扑,云计算,网络安全,Web,HTML,CSS,Javas......