h264结构与码流

news2024/11/18 3:35:51

h264基本概念结构图

在这里插入图片描述
在这里插入图片描述

  H264视频压缩后会成为一个序列帧,帧里包含图像,图像分为很多片,每个片可以分为宏块,每个宏块由许多子块组成
H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。
在这里插入图片描述

场和帧:

  视频的一场或者一帧可以用来产生一个编码图像。在PAL电视中,每个电视帧都是通过扫描屏幕两次而产生的,第二个扫描的线条刚好填满第一次扫描所留下的缝隙。每个扫描即称为一个场(顶场底场)。因此 30 帧/秒的电视画面实际上为 60 场/秒
I帧 P帧 B帧,引用斯巴克兄弟的博客,图文并茂
  举个简单的例子,网络上的电影很多采用了B帧,因为B帧记录的是前后帧的差别,比P帧能节约更多的空间。但是如果遇到不支持B帧的播放器就会很尴尬,因为虽然文件通过B帧压缩确实缩小了非常多,但是在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面。如果B帧丢失,就会用之前的画面简单重复,就会造成画面卡,B帧越多,画面越卡。
  一般来说,I 帧的压缩率是7(跟JPG差不多),P 帧是20,B 帧可以达到50。
在这里插入图片描述

  在如上图中,GOP (Group of Pictures)长度为13,S0 ~ S7 表示 8个视点,T0~T12 为 GOP的 13个时刻。每个 GOP包含帧数为视点数 GOP 长度的乘积。在该图中一个 GOP 中,包含94 个 B帧。B 帧占一个 GOP 总帧数的 90.38%。GOP 越长,B 帧所占比例更高,编码的率失真性能越高

I帧只包含I宏块
P帧包含I宏块和P宏块
B帧包含I宏块、P宏块、B宏块

当帧内slice全部为I像片时,则此帧为I帧
当全部为P slice或和I slice的组合时,则为P帧
当为B slice或和I、P slice的组合时,则为B帧。

片(slice):

  每个图像中,若干个宏块被排列成片。片的目的:为了限制误码的扩散和传输,使编码片相互间保持独立。片共有5种类型:I片(只包含I宏块)、P片(P宏块和/或I宏块)、B片(B宏块和/或I宏块)、SP片(用于不同编码流之间的切换,包含P宏块和/或I宏块)和SI片(特殊类型的编码宏块,包含SI宏块)。
在这里插入图片描述

I slice只包含I宏块
P slice包含P宏块和/或I宏块
B sliceB宏块和/或I宏块。

宏块:

  一个编码图像首先要划分成多个块(4x4 像素)才能进行处理,显然宏块应该是整数个块组成,通常宏块大小为16x16个像素。宏块分为I、P、B宏块,I宏块只能利用当前片中已解码的像素作为参考进行帧内预测;P宏块可以利用前面已解码的图像作为参考图像进行帧内预测;B宏块则是利用前后向的参考图形进行帧内预测
在这里插入图片描述

  序列(切片slice)和宏块的关系如下
在这里插入图片描述
  切片头:包含了一组片的信息,比如片的数量,顺序等等

H264编码分层

  NAL层:(Network Abstraction Layer,视频数据网络抽象层): 关心压缩后如何进行传输,它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。
  VCL层:(Video Coding Layer,视频数据编码层): 关心如何进行压缩,对视频原始数据进行压缩

H.264编码原理

  H.264采用的编码算法就是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。

  视频中一般会存在一段变化不大的图像画面,我们可以先编码出一个完整的图像帧t1,之后的图像帧t2就可以不编码全部图像,而只写入与t1帧的差别,之后的图像帧参考t3帧仍旧可以参照这种方式继续进行编码。这样循环下去就可以得到一个序列(slice)。如果下一个图像帧t4与之前的图像变化很大,无法参考前面的图像帧,就结束上一序列,并开始下一序列。

  序列就可以定义为一段图像编码后的数据流,以I帧开始,到下一个I帧结束,H.264中图像就是以序列为单位进行组织的。

码流的具体分析

码流的整体结构如下
在这里插入图片描述

SODB:(String of Data Bits,原始数据比特流):

  由VCL层产生,数据长度不一定是8的倍数,所以处理起来比较麻烦

RBSP:(Raw Byte Sequence Payload,SODB+trailing bits,编码后的数据流):

  相当于去掉附加03字节之后的数据,同原始的相比,算法是在SODB最后一位补1,不按字节对齐补0,如果补齐0,不知道在哪里结束,所以补1,如果不够8位则按位补0

EBSP:(Encapsulate Byte Sequence Payload):

  生成编码后的数据流之后,我们还要在每个帧之前加一个起始位,需要开发者人为添加。起始位一般是十六进制的0001。但是在整个编码后的数据里,可能会出来连续的2个0x00。那这样就与起始位产生了冲突.那怎么处理了? H264规范里说明如果处理2个连续的0x00,就额外增加一个0x03 。这样就能预防压缩后的数据与起始位产生冲突
在这里插入图片描述
举个例子:
在这里插入图片描述

NALU: (NAL Header(1B)+EBSP)

.NALU就是在EBSP的基础上加1B的网络头.

H.264原始码流(又称为“裸流”)是由一个一个的NALU组成的,结构是这样的:
在这里插入图片描述
  首先NALU是H.264编码数据存储或传输的基本单元,一般H.264码流最开始的两个NALU是SPS和PPS,第三个NALU是IDR。而SPS、PPS、SEI这三种NALU不属于帧的范畴,它们的定义如下:

SPS(Sequence Parameter Sets):序列参数集,作用于一系列连续的编码图像。
PPS(Picture Parameter Set):图像参数集,作用于编码视频序列中一个或多个独立的图像。
SEI(Supplemental enhancement information):附加增强信息,包含了视频画面定时等信息,一般放在主编码图像数据之前,在某些应用中,它可以被省略掉。
IDR(Instantaneous Decoding Refresh):即时解码刷新。
HRD(Hypothetical Reference Decoder):假想码流调度器。

起始码

  每个NALU之间通过起始码进行分隔,起始码分成两种:0x000001(3Byte)或者0x00000001(4Byte)。NALU对应的Slice为一帧的开始就用0x00000001,否则就用0x000001。H.264码流解析的步骤就是首先从码流中搜索0x000001和0x00000001,分离出NALU;然后再分析NALU的各个字段 。
  起始码很容易被忽视但是有很重要,博主在遇见清空保存码流需求的时候曾直接cat /dev/null/ 定向了码流文件,重新保存码流时看见文件大小增加,但是重新保存后的文件就打不开了,原因就在重定向原大小的区域全部变成了00,播放器搜索了很久也没有找到起始码,可能就判定文件格式不对了
在这里插入图片描述
  在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。在实际的H264数据帧中,往往帧前面带有00 00 00 01 或 00 00 01分隔符,一般来说编码器编出的首帧数据为PPS与SPS,接着为I帧……

一个H.264文件如下:
在这里插入图片描述
  在H264码流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"为起始码的,找到起始码之后,使用起始码之后的第一个字节的低 5 位判断是否为 7(sps)或者 8(pps), 及 data[4] & 0x1f == 7 || data[4] & 0x1f == 8。然后对获取的 nal 去掉开始码之后进行 base64 编码,得到的信息就可以用于 sdp。 sps和pps需要用逗号分隔开来。

  上图中,00 00 00 01是一个NALU的起始标志。后面的第一个字节,0x67,是NALU的类型,type &0x1f0x7表示这个NALU是SPS,type &0x1f0x8表示是PPS。

NAL Header:

在这里插入图片描述
NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit):第1位为禁位,默认固定为0,如果接收到的为1,那么就需要丢弃该单元;第2-3位表示重要性,00表示最不重要,11表示最重要,我们可以在解码来不及的情况下舍弃一些不重要的单元,比如在网传的时候,如果网络卡,那么就需要适当丢掉一些数据,丢掉哪些数据就是根据重要性来进行选择;第4-8位用来表示NALU的类型

    • 0 没有定义
    • 1-23 NAL单元 单个 NAL 单元包
    • 24 STAP-A 单一时间的组合
    • 25 STAP-B 单一时间的组包
    • 26 MTAP16 多个时间的合包
    • 27 MTPA24 多个事件组合包
    • 28 FU-A 一帧单包传输
    • 29 FU-B 一帧分多包传输
    • 30-31 没有定义
      h264仅用1-23,24以后的用在RTP H264负载类型头中

  RBSP + RBSP trailing bits + SODE = RBSP
  NAL header(1byte) + RBSP = NALU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/654615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis系列--布隆过滤器(Bloom Filter)

一、前言 在实际开发中,会遇到很多要判断一个元素是否在某个集合中的业务场景,类似于垃圾邮件的识别,恶意ip地址的访问,缓存穿透等情况。类似于缓存穿透这种情况,有许多的解决方法,如:redis存储…

Python 自动化测试五种自动化测试模型实战详解

目录 前言: 自动化测试模型都有哪些? 线性模型 模块化驱动模型 数据驱动模型 关键字驱动模型 行为驱动模型 扩展知识 前言: Python是一种流行的编程语言,广泛应用于自动化测试领域。自动化测试可以帮助测试人员更快、更准确地发…

人脸识别4:Android InsightFace实现人脸识别Face Recognition(含源码)

人脸识别4:Android InsightFace实现人脸识别Face Recognition(含源码) 目录 人脸识别4:Android InsightFace实现人脸识别Face Recognition(含源码) 1. 前言 2. 项目说明 (1)开发版本 (2)依赖库说明(O…

uniapp微信开发者工具效果正常,真机上显示不出效果

1.问题描述 如上图,我需要给页面加入两个icons,页面属于分包内页面,icons使用的uni-icons组件,微信开发者工具中显示效果一切正常,但是在真机上预览页面显示错乱,没有图标,其他数据也显示不出来…

DJ3-7 TCP:拥塞控制

目录 一、拥塞控制概述 二、TCP 拥塞控制算法 1. 慢启动 2. 拥塞避免 3. 快速恢复 4. 状态转换图 5. 拥塞窗口的变化举例 一、拥塞控制概述 1. 如何限制发送方发送速率 TCP 拥塞控制设置 拥塞窗口 变量,表示为 cwnd: 它对发送方向网络中发送流…

A+CLUB管理人支持计划第五期 | 鸣熙资产

免责声明 本文内容仅对合格投资者开放! 私募基金的合格投资者是指具备相应风险识别能力和风险承担能力,投资于单只私募基金的金额不低于100 万元且符合下列相关标准的单位和个人: (一)净资产不低于1000 万元的单位&a…

init与zygote的启动流程

文章目录 1.init进程启动过程1.1init进程的入口函数1.1.1创建和启动所需要的文件目录1.1.2对属性进行初始化与启动属性服务1.1.3子进程信号处理函数1.1.4.重启死去的进程1.1.5.解析init.rc配置文件 1.2解析init.rc配置文件1.3解析Service语句1.4init启动Zygote1.4.1start方法 1…

Android kotlin 实现仿淘宝RecyclerView和对应下的指示器功能

文章目录 一、实现效果二、引入依赖三、源码实现1、指示器样式(自定义类)2、RecyclerView适配器3、主视图实现一、实现效果 指示器样式,第二个gif是用模拟器的,gif有小问题,第三个截图没问题 二、引入依赖 在app的build.gradle在添加以下代码 1、implementation com.githu…

数字电路基础---组合逻辑

目录 数字电路基础---组合逻辑 1、简介 2、实验任务 3、程序设计 4、仿真验证 数字电路基础---组合逻辑 FPGA 或者 IC 内部的逻辑一般包括组合逻辑和时序逻辑,组合逻辑一般指的是一些门电路或者选择器、比较器一起组成的逻辑。 1、简介 数字电路根据逻辑功能的…

程序员必备超好用下载器IDM(Windows下载)

程序员必备现役最强下载器IDM(Windows下载) 1 介绍 IDM,全称Internet Download Maneger,在下载界可谓是大名鼎鼎,不仅仅是其强大的32线程下载,还因为其无与伦比的资源嗅探功能,Internet Downlo…

监听关闭浏览器触发事件

关闭和刷新页面都会触发,一般都不用来做弹窗提示,一般用来做数据操作 // 监听页面关闭 清除本地缓存 window.onbeforeunload function (e) { localStorage.removeItem("statement"); }; // 监听页面关闭 提醒是否关闭 现在不允许自定义内容了…

生命周期监听的使用和源码解析

定义SpringApplicationRunListener来监听springApplication的启动 1.通过实现springApplicationRunListener来实现监听。 2.在 META-INF/spring.factories 中配置 org.springframework.boot.SpringApplicationRunListener自己的Listener。 在默认的springboot配置中就有给我…

主数据概念过时了吗,在这些大数据技术背景下,数据平台等新技术的出现,我们还需要主数据吗?

当企业信息化发展到一定程度时, 数据管理必然会被提升为企业的一个重要管理领域。数据管理的好坏程度, 很大程度上影响着企业信息化进程, 决定着企业信息化最终的成效。 企业信息化建设基本上都是从部门级开始的, 从部门的实际业务需要出发独立建设信息系统, 随着这些信息系统…

2023年地图产业研究报告

第一章 行业概况 地图行业是一个快速发展且关键的信息技术领域,通过收集、处理和可视化地理信息,为用户提供导航、位置服务、地理信息系统和地图数据分析等应用。地图行业的发展受益于全球定位系统(GPS)技术的进步和移动设备的普…

K-verse 合作伙伴访谈|Dalgomz 将韩国旅游体验带入元宇宙

■ 请向我们介绍 Dalgomz 。 你好!我是 Yong-Min Park,Dalgomz 项目的首席执行官。我们的项目专注于通过使用区块链技术创建旅游福利会员计划来促进韩国江原道雪岳地区的旅游业。从雪岳地区开始,Dalgomz NFT 持有者在韩国各地旅行时可以获得现…

基于局部自适应滤波器的双边滤波器matlab完整代码分享

双边滤波(Bilateral filter)是一种可以保边去噪的滤波器。其输出像素的值依赖于邻域像素的值的加权组合。从效果来说,双边滤波可产生类似美肤的效果。皮肤上的皱纹和斑,与正常皮肤的差异,远小于黑白眼珠之间的差异,因此前者被平滑,而后者被保留。如图所示(右图为经过处…

Oracle 查询优化改写(第五章)

第五章 使用字符串 1.遍历字符串 SELECT 天天向上 内容&#xff0c;level&#xff0c;substr(天天向上, LEVEL, 1) 汉字拆分FROM Dual CONNECT BY LEVEL < Length(天天向上);2.计算字符在字符串中出现的次数 3.从字符中删除不需要的字符 若员工姓名有元音字母AEIOU&#x…

pikachu靶场-敏感信息泄露

敏感信息泄漏简述 攻击方式 常见的攻击方式主要是扫描应用程序获取到敏感数据 漏洞原因 应用维护或者开发人员无意间上传敏感数据&#xff0c;如 github 文件泄露 敏感数据文件的权限设置错误&#xff0c;如网站目录下的数据库备份文件泄露 网络协议、算法本身的弱点&#xff…

阿里云ACK worker节点硬盘扩盘

1、在控制台选择要扩盘的服务器&#xff0c;进入硬盘并选择扩盘 2、进入盘后点击已备份扩盘 3、选择扩盘方式以及要扩盘的最后大小 4、确认是否按我们的要求扩盘的 5、扩盘分区和文件系统 6、手动扩盘操作 ACK扩盘文档 查看分区情况 [rootiZj6caed975ouwzuyu564vZ ~]# ls…

C++技能 ( 1 ) - 使用Lambda表达式【详解】

系列文章目录 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 C技能系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream w…