【知识点】H264, H265硬件编解码基础及码流分析
前言
1. 概览
1.1. 为什么要编码
1.2. 编码技术
1.3. 编码分类
- 软件编码(简称软编):使用CPU进行编码。
- 硬件编码(简称硬编):不使用CPU进行编码,使用显卡GPU,专用的DSP、FPGA、ASIC芯片等硬件进行编码。
- 软编:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。
- 硬编:性能高,低码率下通常质量低于硬编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。
1.4. 编码原理
- I帧:关键帧.完整编码的帧.可以理解成是一张完整画面,不依赖其他帧
- P帧:参考前面的I帧或P帧,即通过前面的I帧与自己记录的不同的部分可以形成完整的画面.因此,单独的P帧无法形成画面.
- B帧:参考前面的I帧或P帧以及后面的P帧
补充: I帧的压缩率是7(跟JPG差不多),P帧是20,B帧可以达到50. 但是iOS中一般不开启B帧,因为B帧的存在会导致时间戳同步较为复杂.
- 帧内压缩

- 帧间压缩: P帧与B帧的压缩算法

帧间压缩11.jpg
- 有损压缩: 解压缩后的数据与压缩前的数据不一致.在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复
- 无损压缩: 压缩前和解压缩后的数据完全一致.优化数据的排列等.
- DTS:主要用于视频的解码,在解码阶段使用.
- PTS:主要用于视频的同步和输出.在渲染的时候使用.在没有B frame的情况下.DTS和PTS的输出顺序是一样的。

1.dtspts
2. 编码数据码流结构
2.1 刷新图像概念.
- 逐行扫描:每次扫描得到的信号就是一副图像,也就是一帧. 逐行扫描适合于运动图像
- 隔行扫描:扫描下来的一帧图像就被分为了两个部分,这每一部分就称为「场」,根据次序分为:「顶场」和「底场」.适合于非运动图像


2.2. 重要参数
- 视频参数集VPS(Video Parameter Set)
- 序列参数集SPS(Sequence Parameter Set)
- 图像参数集PPS(Picture Parameter Set)
- 档次: 主要规定编码器可采用哪些编码工具或算法。
- 级别: 指根据解码端的负载和存储空间情况对关键参数(最大采样率、最大图像尺寸、分辨率、最小压缩比、最大比特率、解码缓冲区DPB大小等)加以限制。
2.3. 原始码流
- IDR
- 结构
RBSP = SODB + RBSP trailing bits
NALU = NAL header(1 byte) + RBSP
H.264 = Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU +…

- 组成
2.3.1. H.264码流

- StartCode : Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”(Annex B码流格式才必须是”00 00 00 01” 或”00 00 01”)
- NALU Header下表为 NAL Header Type


2.IDR
十六进制 | 二进制 |
0x67 | 0 11 00111 |
注意: 可以将start code理解为不同nalu的分隔符,header是某种类型的key,payload是该key的value.
2.3.2.码流格式
- Annex B
- AVCC
bits | line by byte | remark |
|
8 | version | always | 0x01 |
8 | avc profile | sps[0][1] |
|
8 | avc compatibility | sps[0][2] |
|
8 | avc level | sps[0][3] |
|
6 | reserved | all bits on |
|
2 | NALULengthSizeMinusOne |
|
|
3 | reserved | all bits on |
|
5 | number of SPS NALUs usually | 1 |
|
16 | SPS size |
|
|
N | variable SPS NALU data |
|
|
8 | number of PPS NALUs usually | 1 |
|
16 | PPS size |
|
|
N | variable PPS NALU data |
|
|
2.3.3. H.265码流
十六进制 | 二进制 |
0x4001 | 0 100000 000000 001 |
- forbidden_zero_bit = 0:占1个bit,与H.264相同,禁止位,用以检查传输过程中是否发生错误,0表示正常,1表示违反语法;
- nal_unit_type = 32:占6个bit,用来用以指定NALU类型
- nuh_reserved_zero_6bits = 0:占6位,预留位,要求为0,用于未来扩展或3D视频编码
- nuh_temporal_id_plus1 = 1:占3个bit,表示NAL所在的时间层ID
nal_unit_type | NALU类型 | 备注 |
0 | NAL_UNIT_CODE_SLICE_TRAIL_N | 非关键帧 |
1 | NAL_UNIT_CODED_SLICE_TRAIL_R |
|
2 | NAL_UNIT_CODED_SLICE_TSA_N |
|
3 | NAL_UINT_CODED_SLICE_TSA_R |
|
4 | NAL_UINT_CODED_SLICE_STSA_N |
|
5 | NAL_UINT_CODED_SLICE_STSA_R |
|
6 | NAL_UNIT_CODED_SLICE_RADL_N |
|
7 | NAL_UNIT_CODED_SLICE_RADL_R |
|
8 | NAL_UNIT_CODED_SLICE_RASL_N |
|
9 | NAL_UNIT_CODE_SLICE_RASL_R |
|
10 ~ 15 | NAL_UNIT_RESERVED_X | 保留 |
16 | NAL_UNIT_CODED_SLICE_BLA_W_LP | 关键帧 |
17 | NAL_UNIT_CODE_SLICE_BLA_W_RADL |
|
18 | NAL_UNIT_CODE_SLICE_BLA_N_LP |
|
19 | NAL_UNIT_CODE_SLICE_IDR_W_RADL |
|
20 | NAL_UNIT_CODE_SLICE_IDR_N_LP |
|
21 | NAL_UNIT_CODE_SLICE_CRA |
|
22 ~ 31 | NAL_UNIT_RESERVED_X | 保留 |
32 | NAL_UNIT_VPS | VPS(Video Paramater Set) |
33 | NAL_UNIT_SPS | SPS |
34 | NAL_UNIT_PPS | PPS |
35 | NAL_UNIT_ACCESS_UNIT_DELIMITER |
|
36 | NAL_UNIT_EOS |
|
37 | NAL_UNIT_EOB |
|
38 | NAL_UNIT_FILLER_DATA |
|
39 | NAL_UNIT_SEI | Prefix SEI |
40 | NAL_UNIT_SEI_SUFFIX | Suffix SEI |
41 ~ 47 | NAL_UNIT_RESERVED_X | 保留 |
48 ~ 63 | NAL_UNIT_UNSPECIFIED_X | 未规定 |
64 | NAL_UNIT_INVALID |
|
H.265的NALU类型是在信息头的第一个字节的第2到7位,所以判断H.265NALU类型的方法是将NALU第一个字节与0x7E进行与操作并右移一位,即:
NALU类型 = (NALU头第一字节 & 0x7E) >> 1
bits | line by byte | remark |
8 | configurationVersion | always 0x01 |
2 | general_profile_space |
|
1 | general_tier_flag |
|
5 | general_profile_idc |
|
32 | general_profile_compatibility_flags |
|
48 | general_constraint_indicator_flags |
|
8 | general_level_idc |
|
4 | reserved | ‘1111’b |
12 | min_spatial_segmentation_idc |
|
6 | reserved | ‘111111’b |
2 | parallelismType |
|
6 | reserved | ‘111111’b |
2 | chromaFormat |
|
5 | reserved | ‘11111’b |
3 | bitDepthLumaMinus8 |
|
5 | reserved | ‘11111’b |
3 | bitDepthChromaMinus8 |
|
16 | avgFrameRate |
|
2 | constantFrameRate |
|
3 | numTemporalLayers |
|
1 | tmporalIdNested |
|
2 | lengthSizeMinusOne |
|
8 | numOfArrays |
|
【知识点】H264, H265硬件编解码基础及码流分析的更多相关文章
- iOS8系统H264视频硬件编解码说明
公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...
- 【STM32H7教程】第57章 STM32H7硬件JPEG编解码基础知识和HAL库API
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第57章 STM32H7硬件JPEG编解码基础知识 ...
- Android硬件编解码与软件编解码
最近做了一个android项目用到编解码功能.大概需求是:通过摄像头拍摄一段视频,然后抽帧,生成一个短视频,以及倒序视频,刚开始直接用 H.264 编码格式,没有使用MP4容器封装.做了 ...
- FFmpeg编解码处理1-转码全流程简介
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584901.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- YUV/RGB与H264之间的编解码
1.源码下载 http://download.videolan.org/x264/snapshots/ 2.编译 ./configure --prefix=./_install --enable-sh ...
- RocketMq通信协议格式及编解码 (源码分析)
一.RocketMq broker服务器与客户端的网络通信是基于netty4.x实现的,重点分析 RocketMq设计的通信协议及对应的编解码 开发. 名字解释 ...
- h264码流分析及其工具
总的来说H264的码流的打包方式有两种,一种为annex-b byte stream format的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H264的start_co ...
- H265码流分析
H265相比较于H264,除了包含SPS.PPS外,还多包含一个VPS:在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节. 以OX4001为例,头信息 ...
- VideoToolbox硬件编解码H.264视频流错误码
如果你不能找到在VTD中的错误代码我决定只包括他们在这里. (同样,所有这些错误,并更可以在里面VideoToolbox在Project Navigator中找到.本身). 您将获得无论是在VTD中 ...
随机推荐
- Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用
写在前面 Api网关我们之前是用 .netcore写的 Ocelot的,使用后并没有完全达到我们的预期,花了些时间了解后觉得kong可能是个更合适的选择. 简单说下kong对比ocelot打动我的 ...
- win10家庭中文版CUDA+CUDNN+显卡GPU使用tensorflow-gpu训练模型安装过程(精华帖汇总+重新修改多次复现)
查看安装包 pip list 本帖提供操作过程,具体操作网上有好多了,不赘述.红色字体为后来复现出现的问题以及批注 题外话: (1)python 的环境尽量保持干净,尽量单一,否则容易把自己搞晕,不知 ...
- 使用shell脚本循环处理文本
公司是使用puppet来进行配置管理, 某天修改完puppet后领导回复: 我们有一个文档cabinet.txt记录了物理机器所在的机柜, 除了文档里的其他机器都是虚拟机或云服务器, 对虚拟机的pup ...
- 将HLSL射线追踪到Vulkan
将HLSL射线追踪到Vulkan Bringing HLSL Ray Tracing to Vulkan Vulkan标志 DirectX光线跟踪(DXR)允许您使用光线跟踪而不是传统的光栅化方法渲染 ...
- springMVC源码解读笔记
1: DispatcherServlet 的初始化流程(调用的init方法) a) 初始化spring高级容器,WebApplicationContext(容器初始化12个步骤) Servlet类的i ...
- 【NX二次开发】Block UI 集列表
属性说明 属性 类型 描述 常规 BlockID String 控件ID Enable Logical 是否可操作 Group ...
- Pytest学习笔记3-fixture
前言 个人认为,fixture是pytest最精髓的地方,也是学习pytest必会的知识点. fixture用途 用于执行测试前后的初始化操作,比如打开浏览器.准备测试数据.清除之前的测试数据等等 用 ...
- linux常用命令及一些静态动态库相关知识
1 查找然后grep,最后在复制到特定目录 find . -depth -name *.java | xargs grep -i lijiangtao | awk -F ":" ' ...
- Golang超时机制--2秒内某个函数没被调用就认为超时
Golang超时机制--2秒内某个函数没被调用就认为超时 需求描述 当一整套流程需要其他程序来调用函数完成时通常需要一个超时机制,防止别人程序故障不调你函数导致你的程序流程卡死 实现demo pack ...
- Docker笔记--镜像&基于GO项目创建Docker镜像
Docker笔记--镜像&基于GO项目创建Docker镜像 核心概念 Doker镜像--包含一个基本的操作系统运行环境和应用程序,镜像是创建Docker容器的基础. Docker容器--如果把 ...