H264和H265的学习笔记

 

H264和H265的学习笔记记录分享

一、H264的组成:

二、H265的组成:

三、H264和H265由es打包为pes再打包为ps的代码思路如下:

四、补充说明


一、H264的组成:

1.H264 = SPS(序列参数集)+PPS(图像参数集)+SEI(补充增强信息)+1个I帧+若干P帧。

2.H264的NALU结构 = 开始码+NALU头+NALU数据

        H264常见帧头数据为:00 00 00 01为开始码

        00 00 00 01 67(SPS)序列参数集

        00 00 00 01 68(PPS)图像参数集

        00 00 00 01 06(SEI)补充增强信息

        00 00 00 01 65(IDR)关键帧

        00 00 00 01 61(P帧)

3.什么是I帧、P帧、B帧:

        (1)I帧:帧内压缩,可以通过视频解压算法解压成一张完整的图片,它是一帧画面的完整保留,也被成为关 键帧,一般在检测到丢包时,我们会立即向对方强求一个I帧。

        (2)P帧:帧间压缩,前向预测编码帧,其表示的是这一帧与前一帧的差别,即预测差值与运动矢量。

        (3)B帧:双向预测编码帧,记录的是本帧与前后帧的差别,其压缩率较高,但是解码对性能要求较高,一 般不使用。

4.H264五种类型的NALU:

        (1)SPS(序列参数集):NALU头值为0x67(十六进制),NALU头type位值为7(十进制)。

        (2)PPS(图像参数集):NALU头值为0x68(十六进制),NALU头type位值为8(十进制)。

        (3)SEI(补充增强信息):NALU头值为0x06(十六进制),NALU头type位值为6(十进制)。

        (4)I帧:NALU头值为0x65(十六进制),NALU头type位值为5(十进制)。

        (5)P帧:NALU头值为0x61(十六进制),NALU头type位值为1(十进制)。

5.H264的NALU打包成RTP包的模式(下面是用到的两种模式):

        (1)一个NALU打包成一个RTP包,只需要在一个12字节的RTP包头后添加去掉开始码的NALU即可(这种模式在一个NALU的大小小于MTU时使用)。

        (2)一个NALU打包成几个RTP包(FU_A模式),在12个字节的RTP头后面加上一个字节的FU indicator和一个字节的FU header。FU indicator前3位是NALU头的前3位,后5位是28(十进制), FU header第1位标记RTP包是否为NALU的第一片,第2位标记RTP包是否为NALU的最后一片。第3位是保留位,后5位是NALU头的type位。

6.H264的PS打包流程:

        将ES(基本流)打包成PES(将ES流分组、打包、加入包头信息),最后将多个PES包打包成PS包。

7.PS封装结构:

        (1)PS包包含PS Header,PES Header,PS system header,PS system map等。

        (2)在每个IDR关键帧前都会有SPS,PPS,等NALU,因此将SPS,PPS,IDR的NALU封装成一个PS包,其包 结构如下:PS包 = PS header + PS system header + PS system map + PES header + h264 raw data。

        (3)对于非关键帧的PS包,则变得简单了,其PS封包结构如下:

PS包 = PS header + PES header + h264 raw data。

        (4)若对视音频进行PS封装,则PS封包结构如下:

PS包 = PS头 + PES(video) + PES(audio)。

二、H265的组成:

1.H265 = VPS(视频参数集)+SPS(序列参数集)+PPS(图像参数集)+SEI(补充增强信息)+1个I帧+若干P帧。

2.H265的NALU结构 = 开始码(00 00 00 01)+NALU头+NALU数据

        H265常见帧头数据:

        00 00 00 01 40(VPS)视频参数集

        00 00 00 01 42(SPS)序列参数集

        00 00 00 01 44(PPS)图像参数集

        00 00 00 01 4e(SEI)补充增强信息

        00 00 00 01 26(IDR)关键帧

        00 00 00 01 02(P帧)

3.H265六种类型的NALU:

        (1)、VPS(视频参数集):NALU头值为0x40 01(十六进制),NALU头type位值为32(十进制)。

        (2)、SPS(序列参数集):NALU头值为0x42 01(十六进制),NALU头type位值为33(十进制)。

        (3)、PPS(图像参数集):NALU头值为0x44 01(十六进制),NALU头type位值为34(十进制)。

        (4)、SEI(补充增强信息):NALU头值为0x4e 01(十六进制),NALU头type位值为39(十进制)。

        (5)、I帧:NALU头值为0x26 01(十六进制),NALU头type位值为19(十进制)。

        (6)、P帧:NALU头值为0x02 01(十六进制),NALU头type位值为1(十进制)。

三、H264和H265由es打包为pes再打包为ps的代码思路如下:

1.由PsMux.AddStream(stream_type)函数将ES(基本流)经第一次打包形成PES流并分配流id;

        1.1并且通过psmux_stream_id_info_init()函数对流id进行初始化设置(一般将id_mpgv(也就是video_id)设置 为0xe0);

        1.2通过psmux_create_stream()函数创建pes流(pes打包es流),并分配流id;

2.通过MuxH26(4/5)SingleFrame()函书将(关键帧和非关键帧)pes流按不同方式封装成ps流;

        2.1通过psmux_mux_frame()函数多路复用帧调用ps中的各种头以及map(程序流映射)进行循环写入对其 pes流进行ps封装;

     2.2例如psmux_write_pack_header()函数作用写入包头,其他函数与之相似,通过psmux_stream_mux_frame() 流复用帧重复对pes流进行封装;

3.接下来就是调用OnPsFrameOut通过jrtplib库将ps包以RTP包的形式进行打包分片推流。

4.接下来两个if语句选择相应的流类型调用相应的解码sps函数获取相应的frame_rate(帧速率),width(宽度), heigh(高度)。

四、补充说明

1.H264/H265的开始码00 00 00 01 和 00 00 01的区别如下:

        答:如果NALU对应的Slice片为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001。

2.PS中各种包头的起始码如下:

        (1)、Pack start code:PS header(PS包头)起始码:00 00 01 ba;

        (2)、System header start code:PS system header(系统头部)起始码:00 00 01 bb;

        (3)、PS system map(节目流映射)起始码:00 00 01 bc;

        (4)、PES header:结构为起始码(00 00 01)+stream id(流id);

如:视频流起始码00 00 01 e0;音频流起始码00 00 01 c0;

        (5)、h264 raw data:h264原始数据以SPS(序列参数集)00 00 00 01 67开始,其中包括SPS(67)、PPS(68)、SEI(06)、 IDE(65)、P帧(61)等。

 

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值