H.264基础知识总结

2023-05-16

H264是视频编解码格式;学习H264之前首先要搞明白一个问题,视频为什么要编码,编码传输不行吗?视频就是一堆图片按时间顺序播放,在编码标准出现之前,不经过编码的原始码流,可以这么理解成就是携带时间戳的图片。可以随便找个图片看下他的大小小则几十K,比较清晰的甚至需要十几M。这么大的数据量造成了,视频在存储时会耗费大量的存储空间,网络传输时占用大量带宽和流量,而编码就是为了减少视频的数据量,减少存储和网络中浪费的资源,在发送端做压缩在接收端做解压;接收端播放时将压缩后的数据量依据编解码算法和编解码规则,解码出来的视频和不经过压缩后传输的效果做到几乎一样;编码的本质是压缩

在这里插入图片描述

H264基础概念

  • 序列
    H264编码标准中所遵循的理论依据个人理解成:参照一段时间内相邻的图像中,像素、亮度与色温的差别很小。所以当面对一段时间内图像我们没必要去对每一幅图像进行完整一帧的编码,而是可以选取这段时间的第一帧图像作为完整编码,而下一幅图像可以记录与第一帧完整编码图像像素、亮度与色温等的差别即可,以此类推循环下去。什么叫序列呢?上述的这段时间内图像变化不大的图像集我们就可以称之为一个序列。序列可以理解为有相同特点的一段数据。但是如果某个图像与之前的图像变换很大,很难参考之前的帧来生成新的帧,那么久结束删一个序列,开始下一段序列。重复上一序列的做法,生成新的一段序列。
  • GOP(画面组)
    GOP我个人也理解为跟序列差不多意思,就是一段时间内变化不大的图像集。GOP结构一般有两个数字,如M=3,N=12。M指定I帧和P帧之间的距离,N指定两个I帧之间的距离。上面的M=3,N=12,GOP结构为:IBBPBBPBBPBBI。在一个GOP内I frame解码不依赖任何的其它帧,p frame解码则依赖前面的I frame或P frame,B frame解码依赖前最近的一个I frame或P frame 及其后最近的一个P frame。
  • 帧类型
    H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由4x4-16x16的yuv数据组成。宏块作为H264编码的基本单位。 在H264协议内定义了三种帧,分别是I帧、B帧与P帧。I帧就是之前所说的一个完整的图像帧,而B、帧与P帧所对应的就是之前说的不编码全部图像的帧。P帧与B帧的差别就是P帧是参考之前的I帧而生成的,而B帧是参考前后图像帧编码生成的。
    在这里插入图片描述
  • IDR帧(关键帧)
    在编码解码中为了方便,将GOP中首个I帧要和其他I帧区别开,把第一个I帧叫IDR,这样方便控制编码和解码流程,所以IDR帧一定是I帧,但I帧不一定是IDR帧;IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始算新的序列开始编码。I帧有被跨帧参考的可能,IDR不会。

  • 宏块
    宏块是H264编码的关键,H264默认是使用 16X16 (像素点)大小的区域作为一个宏块,也可以划分成 8X8 大小。 视频中相邻的两个图片之间的数据不大,两张图片中有大量的重复数据,对于这些以不同的只是宏块的位置,所以第二章图片只要记录这些相似图片的矢量位移就可以。
    在这里插入图片描述

  • 编码算法(帧内压缩和帧间压缩)
    帧内(Intraframe)压缩也称为空间压缩(Spatialcompression)。当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,这实际上与静态图像压缩类似。帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩本质是对宏块的压缩和预测。
    帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。也即连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。帧间压缩也称为时间压缩(Temporalcompression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧差值(Framedifferencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。帧间压缩本质是记录宏块的运动信息。

    H264码流格式

    总体来看H264的结构如下图
    在这里插入图片描述
    细分到每个图像序列,(GOP,也就是上面视频序列中的一个节点)它的文件结构如下
    在这里插入图片描述
    我们可以看到,H264码流是由一个个的NAL单元组成,其中SPS、PPS、IDR和SLICE是NAL单元某一类型的数据;实际的网络数据传输过程中H264的数据结构是以NALU(NAL单元)进行传输的,传输数据结构组成为[NALU Header]+[RBSP]
    一个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成,
    其中 Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”
    在这里插入图片描述
    NAL单元的头部是由forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)三个部分组成的,组成如图6所示:
    1、F(forbiden):禁止位,占用NAL头的第一个位,当禁止位值为1时表示语法错误;
    2、NRI:参考级别,占用NAL头的第二到第三个位;值越大,该NAL越重要。
    3、Type:Nal单元数据类型,也就是标识该NAL单元的数据类型是哪种,占用NAL头的第四到第8个位;
    在这里插入图片描述

其中nal_unit_type是比较重要的,所以记录一下

在这里插入图片描述
每种类型都有代表一种数据类型,比较重要的以下几种做个简单的介绍:
1、非VCL的NAL数据类型:
1)、SPS(序列参数集):SPS对如标识符、帧数以及参考帧数目、解码图像尺寸和帧场模式等 解码参数进行标识记录。
2)、PPS(图像参数集):PPS对如熵编码类型、有效参考图像的数目和初始化等解码参数进行标志记录。
3)、SEI(补充增强信息):这部分参数可作为H264的比特流数据而被传输,每一个SEI信息被封装成一个NAL单元。SEI对于解码器来说可能是有用的,但是对于基本的解码过程来说,并不是必须的。

@:先标记一下,SPS、PPS内容是编码器给的。(出处的话,慢慢研究)

2、VCL的NAL数据类型
1)、 头信息块,包括宏块类型,量化参数,运动矢量。这些信息是最重要的,因为离开他们,被的数据块种的码元都无法使用。该数据分块称为A类数据分块。
2)、 帧内编码信息数据块,称为B类数据分块。它包含帧内编码宏块类型,帧内编码系数。对应的slice来说,B类数据分块的可用性依赖于A类数据分块。和帧间编码信息数据块不通的是,帧内编码信息能防止进一步的偏差,因此比帧间编码信息更重要。
3)、 帧间编码信息数据块,称为C类数据分块。它包含帧间编码宏块类型,帧间编码系数。它通常是slice种最大的一部分。帧间编码信息数据块是不重要的一部分。它所包含的信息并不提供编解码器之间的同步。C类数据分块的可用性也依赖于A类数据分块,但于B类数据分块无关。
以上三种数据块每种分割被单独的存放在一个NAL单元中,因此可以被单独传输。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H.264基础知识总结 的相关文章

  • rxjava2源码解析(二)线程切换分析

    使用方法 还是先从最基本的使用开始看 xff1a Observable create new ObservableOnSubscribe lt String gt 64 Override public void subscribe Obse
  • rxjava2源码解析(三)observeOn线程池原理分析

    observeOn 还是先说observeOn 直接看源码 xff1a public ObservableObserveOn ObservableSource lt T gt source Scheduler scheduler boole
  • RxJava 2.x 源码分析 之 FlatMap

    FlatMap 官方定义 xff1a 把被观察者发射出去的事件转化成新的子被观察者 xff0c 然后把这些发射量展开平铺后统一放到一个被观察者中 官方文档 简单来讲就是把被观察者每次发射的事件转化成一个子被观察者 xff0c 然后通过合并
  • Transformer 在RxJava中的使用

    Transformer 用途 Transformer xff0c 顾名思义是转换器的意思 早在 RxJava1 x 版本就有了Observable Transformer Single Transformer和Completable Tra
  • 彻底理解kubernetes CNI

    kubernetes各版本离线安装包 CNI接口很简单 xff0c 特别一些新手一定要克服恐惧心里 xff0c 和我一探究竟 xff0c 本文结合原理与实践 xff0c 认真读下来一定会对原理理解非常透彻 环境介绍 我们安装kubernet
  • 将本地项目上传到远程Git服务器

    1 先进入项目文件夹 通过命令 git init 把这个目录变成git可以管理的仓库 git init 2 把文件添加到版本库中 xff0c 使用命令git add 添加到暂存区里面去 xff0c 小数点 34 34 意为添加文件夹下的所有
  • 解决Manifest merger failed : Attribute application@appComponentFactory

    在将butterknife升级到10 0 0的时候遇到问题 xff0c 编译无法通过 Manifest merger failed Attribute application 64 appComponentFactory value 61
  • bindService不能触发onServiceConnected方法的原因

    在android项目中用到AIDL xff0c bindService service connection BIND AUTO CREATE 之后一直不调用 connection中的onServiceConnected方法 可能原因1 1
  • Android应用被浅杀和深杀

    onTaskRemoved 方法在当用户移除应用的一个Task栈时被调用 也就是当用户在最近任务界面把该应用的一个task划掉时 xff0c 或者在最近任务界面进行清理时 这两种情况下onTaskRemoved 都会被调用 xff0c 但在
  • java.lang.OutOfMemoryError: Could not allocate JNI Env

    最近有一些OOM的错误上报 java lang OutOfMemoryError Could not allocate JNI Env 极少量的 java lang OutOfMemoryError pthread create 1040K
  • RecycleView4种定位滚动方式演示

    概述 相信大家在项目中使用RecyclerView时 xff0c 经常会遇到这样的需求 xff1a 将RecyclerView滑动到指定位置 xff0c 或者检索RecyclerView的某一项 xff08 各个项的高度不确定 xff09
  • Java/Android中的引用类型及WeakReference应用实践

    一 背景 一般意义上而言 xff0c Java Android中的引用类型包括强引用 软引用 弱引用 虚引用 不同的引用类型具有各自适用的应用场景 xff0c 并与JVM的GC直接相关 作为Java Android中的引用类型之一 xff0
  • Android 网络切换 发送多次广播问题

    最近发现做项目监听网络切换广播 xff0c 根据网络条件切换一些设置 测试发现每次3G WIFI 或者WIFI到3G xff0c 网络切换的广播都会发出多次 比如3G gt WIFI 会发送三个广播 1 连接wifi 2 关闭手机网络 3
  • 在draw.io中创建容器形状

    draw io中的任何形状都可以变成容器 包含其他多个形状的形状 在绘图区域上移动容器时 xff0c 位于其中的形状将随容器移动 容器可用于指示流程图中的步骤或子过程组 xff0c 数据集合 xff0c 树形图或任何其他具有层次结构的图中的
  • H264基础及RTP分包解包

    一 H 264基础概念 SODB 数据比特串 xff0d xff0d xff1e 最原始的编码数据 RBSP 原始字节序列载荷 xff0d xff0d xff1e 在SODB的后面填加了结尾比特 xff08 RBSP trailing bi
  • Mac App Store中的开发预览版软件更新如何关闭(如Safari 12.0 seed)

    这段时间莫名其妙App Store中出现Safari 12 0 seed开发预览版更新 xff0c 这个是针对开发者提供的 xff0c 作为普通用户 xff0c 不希望接触到这种bug不断的产品 xff0c 那么 xff0c 该如何关闭呢
  • 在VMware-player中安装 VMware Tools的步骤

    1 用root身份登录ubuntu后 xff0c player 管理 安装VMware Tools 3 把上述文件复制到 home 用户为名的文件夹中 例如本人把上述文件复制到 home tgl tglFile中了 4 xff09 首先我进
  • ubuntu18.04编译问题

    1 没有安装curl fantasy 64 fantasy All Series my dev android AOSP prebuilts sdk tools jack admin start server prebuilts sdk t
  • VMware 扩展Ubuntu虚拟机的磁盘空间

    1 准备工作 使用 df h 指令查看一下磁盘空间的使用情况 可以看到 xff0c 现在挂载的磁盘空间为40G xff0c 用了16G xff0c 还剩22G 下面开始扩展磁盘空间 2 编辑虚拟机设置 打开虚拟机 xff0c 找到待扩展的虚
  • 解决Android Studio 无法通过gradle 下载https://dl.google.com/android/repository/addons_list-3.xml 解决办法

    安卓gradle的时候 xff0c 会弹出来这样报错 Task prepareKotlinBuildScriptModel UP TO DATE IOException https dl google com android reposit

随机推荐

  • libGL error: MESA-LOADER: failed to open vmwgfx (search paths /usr/lib/x86_64-linux-gnu/dri)

    使用emulator use system libs 命令 Using the libstdc 43 43 so 6 that is available in your system instead of the one bundled w
  • Java内部类详解

    一 内部类基础 在Java中 xff0c 可以将一个类定义在另一个类里面或者一个方法里面 xff0c 这样的类称为内部类 广泛意义上的内部类一般来说包括这四种 xff1a 成员内部类 局部内部类 匿名内部类和静态内部类 下面就先来了解一下这
  • 使用Ubuntu18.04编译android8.1

    使用虚拟机中的Ubuntu18 04编译android8 1 1 软硬件要求 1 1 硬件 16G的内存 xff1b 200G的存储盘 1 2 软件 Ubuntu18 04 这样的软硬件要求并非必须 xff0c 但是经过测试这样的配置刚好能
  • Android 8 细分版本 分支 以及支持的设备

    Android 8 细分版本 分支 以及支持的设备 细分版本分支版本支持的设备OPM8 181005 003android 8 1 0 r48OreoPixel COPM7 181005 003android 8 1 0 r47OreoNe
  • Android 打印堆栈日志的几种方法

    在Android调试过程中经常会出现程序出现的结果不是我们预期的结果 xff0c 那就需要加Log打印调试 xff0c 看调用过程是否正确 xff0c 此时就需要打印程序的调用栈 xff0c 特别是Android代码相当庞大 xff0c 打
  • 在 Ubuntu 18.04 上安装 SmartGit

    在开始安装之前 xff0c 很有趣 确保我们系统中的所有软件包都是最新的 为此 xff0c 在终端 Ctl 43 Alt 43 T 中 xff0c 我们只需编写 xff1a 1 sudo apt update sudo apt upgrad
  • 复工第一事:干掉 Notepad++

    点击上方 芋道源码 xff0c 选择 设为星标 管她前浪 xff0c 还是后浪 xff1f 能浪的浪 xff0c 才是好浪 xff01 每天 10 33 更新文章 xff0c 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之
  • Ubuntu18.04编译Android8.0系统源码

    首先 需要一个台式电脑 xff0c 有个i7处理器 xff0c 有一个1T的机械 43 500G的固态 xff0c 如果条件允许改一个服务器也可以 我这里是一个台式电脑 在台式电脑上安装一个虚拟机 xff0c 基本是使用的VMware xf
  • m, mm以及mmm编译命令以及make snod的使用

    1 xff09 编译指定Package Android源码目录下的build envsetup sh文件 xff0c 描述编译的命令 croot 切到Android源码树的根目录 当你深入Android源码树的子目录 xff0c 想回到根目
  • 复杂条件逻辑的梳理

    为什么会感觉有些需求无从下手 在产品需求梳理或者业务逻辑调研阶段 xff0c 有时会遇到产品需求无从下手的问题 xff0c 分析下来 xff0c 一般情况如下 xff1a 需求边界不明确 xff0c 输入和输出的界定不清晰 xff0c 无法
  • Android源码刷机步骤

    打开OEM开关 xff1a 先点击设置 关于手机 版本号七次 开发者选项 打开OEM解锁 xff08 这步必须可以上网 xff0c 否则打不开 xff09 进入bootloader页面 使用方法1必须安装adb platform tools
  • Android Studio导入和调试Android8.0源码

    生成IDE相关文件 idegen专门为IDE环境调试源码而设计的工具 xff0c 依次执行如下命令 xff1a source build envsetup sh mmm development tools idegen developmen
  • make snod注意事项-刷机后启动异常

    1 正确执行顺序 需要执行 source build envsetup sh lunch 2 单独编译 xff0c 刷机后运行异常 全编andorid后 xff0c 单独修改编译一个framwork模块 xff0c make snod会有如
  • adb remount 系统提示只读文件系统Read-only file system,解决用adb disable-verity

    在Android6 0 xff08 Android M xff09 userdebug版本上 eng版本不存在该问题 xff0c 发现使用adb remount 系统之后 xff0c 还是不能对system分区进行操作 xff0c 提示没有
  • 枚举 switchcase 标签必须为枚举常量的非限定名称

    enum switch case label must be the unqualified name of an enumeration constant 或 错误 枚举 switchcase 标签必须为枚举常量的非限定名称case Co
  • VMware为什么会越用占用的内存越大?该如何清理?

    现象描述 xff1a VMware用了一段时间后发现原来刚开始只占5G左右的内存 xff0c 慢慢的会占用几十个G xff0c 甚至更多 xff0c 磁盘空间占用越来越大 解决办法 xff1a 虚拟机内部执行cat dev zero gt
  • H264中的时间戳(DTS和PTS)

    xff08 1 xff09 Ffmpeg中的DTS 和 PTS H264里有两种时间戳 xff1a DTS xff08 Decoding Time Stamp xff09 和PTS xff08 Presentation Time Stamp
  • UEFI/Legacy两种启动模式下安装Win10/Ubuntu双系统

    文章目录 更多操作细节请移步到 UEFI Legacy两种启动模式下安装Win10 Ubuntu双系统 http www aigrantli com archives uefilegacy E4 B8 A4 E7 A7 8D E5 90 A
  • H264视频编码原理

    一 为什么要对视频编码 视频是由一帧帧的图像组成 xff0c 就像gif图片一样 一般视频为了不会让人感觉到卡顿 xff0c 一秒钟至少需要16帧画面 一般30帧 加入该视频是一个1280x720的分辨率 xff0c 那么不经过编码一秒钟传
  • H.264基础知识总结

    H264是视频编解码格式 xff1b 学习H264之前首先要搞明白一个问题 xff0c 视频为什么要编码 xff0c 编码传输不行吗 xff1f 视频就是一堆图片按时间顺序播放 xff0c 在编码标准出现之前 xff0c 不经过编码的原始码