简单理解H264编码

news/2024/11/17 19:26:16/文章来源:https://www.cnblogs.com/feixiang-energy/p/18350369

参考帖子:https://blog.csdn.net/go_str/article/details/80340564?spm=1001.2014.3001.5502

0、序言:
首先要弄明白编码的目的。当你此刻显示器正在播放一个视频,分辨率为1280*720,帧率为25,那么一秒所产生正常的数据大小为:1280*720(像素)*25(张)/8(1字节8位)(结果:B)/1024(结果:KB)/1024(结果:MB)=2.75MB。显然一秒这么大的数据是无法接受的,因此需要对数据进行压缩。
 
1、前言:
H264在视频采集到传输中属于编解码层次的数据,是在采集数据后做编码压缩时通过编码标准编码之后呈现的数据。

 

2、H264相关概念:

2.1序列:
        H264编码标准中所遵循的理论依据个人理解成:参照一段时间内相邻的图像中,像素、亮度、色温的差别很小,所以当面对一段时间内图像我们没必要对每一幅画面进行一次完整一帧的编码,而是选取这段时间内的第一帧图像作为完整编码,下一幅图像可以记录与第一帧完整编码图像像素、亮度、色温的差别即可,以此类推循环下去。
        什么是序列呢,上述的这段时间内图像变化不大的图像集我们称之为一个序列。序列可以理解为有相同特点的一段数据。但是如果某个图像与之前的图像变换很大,很难参考之前的帧来生成新的帧,那么就结束删除一个序列,开始下一段序列。
 
2.2帧类型:
        H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16*16的yuv数据组成。宏块作为H264编码的基本单元。
        在H264协议内定义了三种帧,分别是I帧、B帧和P帧。I帧就是之前说的一个完整图像帧,而B帧和P帧所对应的就是之前说的不编码全部图像的帧。P帧与B帧的差别是P帧是参考之前的I帧和P帧生成的,而B帧是参考前后图像帧编码生成的。
 
2.3GOP(画面组):
        GOP我理解为和序列差不多的意思,就是一段时间内变化不大的图像集。GOP结构一般有两个数字,如M=3,N=12。M指定I帧与P帧之间的距离,N指定两个I帧之间的距离。如上M=3,N=12,GOP的结构为:IBBPBBPBBPBBI。在一个GOP中I帧解码不依赖任何其它帧,P解码依赖前面的I帧或P帧,B帧解码依赖最近的I帧或P帧及其后最近的P帧。

 

2.4IDR帧:
        在编码解码中为了方便,将GOP中首个I帧要和其它I帧区别开,把第一个I帧叫IDR,这样方便控制编码和解码流程,所以IDR帧一定是I帧,但I帧不一定是IDR帧。IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始算新的序列开始编码。I帧有别跨越参考的可能,IDR帧不会。

作用:H264引入IDR帧是为了解码的重同步,当解码器解码到IDR帧时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参考集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会,IDR帧之后的图像永远不会参考IDR帧之前图像的数据来解码。

 

3、H264压缩方式:        
        H264采用的核心算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成P帧和B帧的算法。
        帧内压缩也称空间压缩。当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧的冗余信息,这实际上与静态图像压缩类似,帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩一般达不到很高的压缩,和编码jpeg差不多。
        帧间压缩也称时间压缩。相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小。即连续的视频帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步增加压缩量,减少压缩比。
 
3.1压缩方式说明:
        Step1:分组,将一系列变化不大的图像归为一个组,也就是一个序列,也可以叫GOP(画面组)
        Step2:定义帧,将每组的图像帧规分为I帧、P帧和B帧三种类型
        Step3:预测帧,以I帧作为基础帧,以I帧预测P帧,以I帧和P帧预测B帧
        Step4:数据传输,最后将I帧数据和预测的差值信息进行存储和传输。
 
4、H264分层结构:

  H264的主要目标是为了有较高的压缩比和良好的网络亲和性,为了达到这个目标,H264的解决方案是将系统框架分为两个层面,分别是视频编码层(VCL)和网络抽象层(NAL)。如图:

 

        VCL层是对核心算法引擎、块、宏块及片的语法级别的定义,负责有效表示视频数据的内容,最终输出编码完的数据SODB
        NAL层定义了片级以上的语法级别(如序列参数集参数和图像参数集),负责以网络所要求的恰当方式去格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL层将SODB打包成RBSP然后加上NAL头组成一个NALU单元。
        这里说一下SODB与RBSP的关联。SODB:数据比特串,是编码后的原始数据;RBSP:原始字节序列载荷,是在原始编码数据后面添加了结尾比特,一个bit"1"和若干bit"0",用于字节对齐。
 
5、H264码流结构:
        经过编码之后的H264码流如图所示,H264码流是由一个个的NAL单元组成,其中SPS、PPS、IDR和SLICE是NAL单元某一类型的数据。

 

6、H264的单元:

6.1 H264的NAL结构
        在实际的网络数据传输中,H264的数据结构是以NALU进行传输的,传输数据结构组成为【NALU Header】+【RBSP】。

 

  从之前的分析我们知道,VCL层编码后的视频帧数据,帧有可能是I/B/P帧,这些帧也可能是属于不同的序列之中,同一序列也还有不同的序列参数集(SPS)和图像参数集(PPS)。综上所述,想要准确无误进行视频的解码,除了需要VCL层编码出来的视频帧数据,同时还需要传输序列及和图像参数集等等,所以RBSP不单纯只保存I/B/P帧的数据编码信息,还有其它信息也可能出现在里面。
        上面知道NAL单元是作为实际视频数据传输的基本单元,NALU头是用来标识后面RBSP是什么类型的数据,同时记录RBSP数据是否会被其他帧参考以及网络传输是否有错误。
6.2 NAL头
一、NAL头的组成
        NAL单元的头部是由forbidden_bit(1bit),nal_reference_bit(优先级)、nal_unit_type(5bit)(类型)三个部分组成的。
        F:禁止位,占用NAL头的第一位,当禁止位值为1时表示语法错误
        NRI:参考级别,占用NAL头的第二到第三位,值越大,该NAL越重要
        Type:NAL单元的数据类型,也就是标识该NAL单元的数据类型是哪种,占用NAL头的第四到第八位

 

一、NAL单元数据类型:
        NAL类型主要就是下面图中所有这些类型,每个类型都有其特殊的作用:

 

在具体介绍NAL数据类型之前,有必要知道NAL分为VCL和非VCL的NAL单元。其中SPS、PPS、SEI等非VCL的NAL参数集对解码和显示视频都是很有作用的。
        另一个需要了解的概念就是参数集(Parameter sets),参数集是携带解码参数的NAL单元,参数集对于正确解码是非常重要的,在一个有损的传输场景中,传输过程中比特列或包有可能丢失或损坏,在这种网络环境下,参数集可以通过高质量的服务来发送,比如向前纠错机制和优先级机制。Parameter sets与其之外的语法元素之间的关系图如下:

 

每种类型都有代表一种数据类型,比较重要的以下几种做个简单介绍:
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类数据分块无关。
    
6.3 H264的NAL单元与片、宏之间的联系
        通过剖析这么多的小零件,是时候展示一个世界地图了。

 其实H264的码流结构并没有大家想象的那么复杂,编码后视频的每一组图像(GOP、图像组)都给予了传输中的序列(SPS)和本身这个帧的图像参数(PPS)。所以我们的整体结构,应该如此:

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET 8 + Blazor 多租户、模块化、DDD框架、开箱即用

前言 基于 .NET 8 的开源项目,主要使用 WebAPI + Blazor 支持多租户和模块化设计,DDD构建。可以帮助我们轻松地搭建起一个功能完善的Web应用程序。除了帮助你快速构建应用程序之外,项目也可以当做学习资料。我们可以从中了解到多租户、CQRS、DDD架构、云部署、Docker容器化等…

日程表-获取当前周,点击切换上一周和下一周

获取本周的开始日期和结束日期(本周周一到周日):var currentTime = new Date() this.getThisWeekData(currentTime, 0)点击切换上周的周历(把当前周的周一的时间传进去就行,如“2024-08-05”): this.getThisWeekData(currentData.startData, -7)点击切换下周的周历(把当前…

「代码随想录算法训练营」第三十三天 | 动态规划 part6

322. 零钱兑换题目链接:https://leetcode.cn/problems/coin-change/ 文章讲解:https://programmercarl.com/0322.零钱兑换.html 题目难度:中等 视频讲解:https://www.bilibili.com/video/BV14K411R7yv/ 题目状态:略微有点思路,但还是有点转不过来。思路: 这次是找最小的…

工序汇报保存时提示“汇报数量大于领料数量”

1、配方单没有下推生产领料,生产订单的领料套数为0 2、该校验和领料套数基于配方单”是否关键件”的物料下推生产领料的情况。

09 DMA配合ADC多通道

[TOG] 前言 前面介绍了ADC数模转换,得到了内部的温度值和外部电压值,我感觉这样太消耗CPU的资源了,所以我准备用DMA来帮我从AD的数据寄存器中拿出数据出来,就不用再去读取AD的数据寄存器了。 一、什么是DMA DMA叫做直接存储器存取,就不需要我们CPU通过软件将外部寄存器或者…

快速基于 ClickHouse + Grafana 搭建可观测性解决方案 - 分布式链路追踪篇(ClickHouse 官方博客)

引言 在 ClickHouse,我们认为可观测性仅仅是另一个实时分析问题。作为一款高性能的实时分析数据库,ClickHouse 被用于多种场景,包括时间序列数据的实时分析。其应用场景的多样性推动了大量分析函数的发展,这些函数有助于查询大多数数据类型。这些查询特性和高压缩率使得越来…

使用 defineNuxtComponent`定义 Vue 组件

title: 使用 defineNuxtComponent`定义 Vue 组件 date: 2024/8/9 updated: 2024/8/9 author: cmdragon excerpt: 摘要:本文介绍了在Nuxt 3中使用defineNuxtComponent辅助函数定义类型安全的Vue组件的方法,适用于习惯Options API的开发者。defineNuxtComponent支持asyncData…

点亮童梦思考之光,神秘伙伴震撼登场!

本文由 ChatMoney团队出品介绍说明 咱们来聊聊“十万个为什么”机器人,这对小朋友来说,好处可多了去啦! 小朋友们天生好奇,满脑子都是问号。 这个机器人就像个啥都懂的知识达人,不管他们问啥,都能给出答案。从天上的星星为啥发光,到水里的鱼儿为啥游来游去,统统都能讲清…

安装windows11系统跳过微软账号登录,使用本地账号登录方法

在安装win11系统,进行到如图下所示界面的时候,暂停下 我们可以按下键盘的Shift+F10按键(部分电脑是Fn+Shift+F10),这时屏幕会出现命令行窗口,如图下所示 我们需要在命令行内输入代码oobe\bypassnro.cmd然后回车,这时候电脑会重启。PS:若无法输入命令,可以电脑插入鼠标…

深入探讨微服务架构中的同步通信机制

今天我们专注于微服务之间的网络通信。可以清楚地看到,框架的最终目标是使程序员能够更专注于业务逻辑,而不是被迫写各种无关紧要的代码。总结一下,尽管我们使用了框架和各种抽象,但最终仍然是通过HTTP来进行调用。不同的是,在实际调用之前,我们引入了一个拦截器来实现微…

Windows Server 任务计划执行bat脚本,无法正常自动执行的解决方案

注意点如下: 1、请点击“创建任务”而不是“创建基本任务” 2、运行任务时,请使用System账户 3、配置:请选择:windows server 2016或2003,xp,2000。注意千万不要选择2008 4、在“程序或脚本”中请填写脚本的名称,而不是路径;在“起始于(可选)”中请填写文件路径,注意…