【知识点】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 刷新图像概念.
- 逐行扫描:每次扫描得到的信号就是一副图像,也就是一帧. 逐行扫描适合于运动图像
- 隔行扫描:扫描下来的一帧图像就被分为了两个部分,这每一部分就称为「场」,根据次序分为:「顶场」和「底场」.适合于非运动图像

帧与场.png2.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
NAL Header Type.png
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中 ...
随机推荐
- 路由信息相关 route 网卡
目录 route命令 1.查看路由表 2.管理路由 基本网络配置 添加网卡地址 修改网卡UUID route命令 路由表管理命令,路由表主要构成: Destination: 目标网络ID,表示可以到达 ...
- Java基础之第二章变量
1. 变量介绍 变量是程序的基本组成单位 概念 变量相当于内存中一个数据存储空间的表示,可以通过变量名可以访问到变量(值). 变量使用 声明变量 int a; 赋值 a = 20; public cl ...
- l初识CSRF(跨站请求伪造)
一 CSRF是什么 CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Click Attack"或者Session Riding,通常 ...
- 解决mysql无法远程连接的问题
前言 最近开发中遇到一个问题,mysql在服务器本地可以登录,但是远程通过3306端口却不可以.这个问题困扰了我一周之久,终于在今天解决了.在解决的过程中试了很多的方法,遂记录下来,希望能给大家一些提 ...
- Django(50)drf异常模块源码分析
异常模块源码入口 APIView类中dispatch方法中的:response = self.handle_exception(exc) 源码分析 我们点击handle_exception跳转,查看该 ...
- CUDA C++编程接口:编译
CUDA C++编程接口:编译 一.概述 CUDA C++为熟悉C++编程语言的用户提供了一个简单的路径,以方便地编写程序以执行该设备. 它由一组最小的扩展到C++语言和运行库. 在编程模型中引入了核 ...
- Pass Infrastructure基础架构(上)
Pass Infrastructure基础架构(上) Operation Pass OperationPass : Op-Specific OperationPass : Op-Agnostic De ...
- python2向python3移植问题
问题: payload = "A"*140 # padding ropchain = p32(puts_plt) ropchain += p32(entry_point) ropc ...
- JAVA复习题(一)基础知识
类的构造方法描述正确的是( )A. 类中的构造方法不能省略B. 构造方法必须与类同名,但方法不能与class同名C. 构造方法在一个对象被new时执行D. 一个类只能有一个构造方法我的答案:C正确答案 ...
- 137. 只出现一次的数字 II
2021-04-30 LeetCode每日一题 链接:https://leetcode-cn.com/problems/single-number-ii/ 方法1:使用map记录每个数出现的次数,再找 ...