当前位置: 首页 > news >正文

音视频及H264/H256编码相关原理

一、音视频封装格式原理:

          我们播放的视频文件一般都是用一种封装格式封装起来的,封装格式的作用是什么呢?一般视频文件里不光有视频,还有音频,封装格式的作用就是把视频和音频打包起来。 所以我们先要解封装格式,看有哪些视频流和哪些音频流,此时的音频流和视频流都还是压缩数据,不能直接用于显示的,这就需要解码。

        

        如FFmpeg 视频文件就是一个容器 (视频流(H264) 音频流(aac))。

      1、视频文件封装格式:

          封装格式(也叫容器),就是将已经编码压缩好的视频轨和音频轨按照一定的格式放到一个文件中,也就是说仅仅是一个外壳,或者大家把它当成一个放视频轨和音频轨的文件夹也可以。

      2、音视频编码方式:

  • 视频编码方式:将视频像素数据(RGB,YUV 等)压缩成视频码流,从而降低视频的数据量。包含有HEVC(H265)、H264、MPEG4、MPEG2、VP9等;
  • 音频编码方式:将音频采样数据(PCM 等)压缩成音频码流,从而降低音频的数据量。包含有AAC、MP3、WMV、AC-3。

       3、编解码方式和封装格式的关系:

                「视频封装格式」= 视频 + 音频 +视频编解码方式 等信息的容器。

       4、RGB/YUV概念:

        通常我们采用RGB模型来表示颜色,RGB模型中,每种颜色需要3个数字分别表示R、G、B,每个数字占用1个bit字节,这样总共需要24bits

        YUV能更高效颜色模型用更少的bit来表示颜色,Y——表示亮度,也就是灰阶值,U和V表示色度分量。

  •  YCbCr颜色模型基本原理:

        假设我们定义一个 「亮度(Luminance)」 的概念来表示颜色的亮度,那它就可以用含 R、G、B 的表达式表示为:

    Y = kr*R + kg*G + kb*B

        Y 即「亮度」,kr、kg、kb 即 R、G、B 的权重值。

        可以定义一个 「色度(Chrominance)」 的概念来表示颜色的差异

    Cr = R – YCg = G – YCb = B – Y

        Cr、Cg、Cb 分别表示在 R、G、B 上的色度分量.。

  • YUV:关键是在于它的亮度信号 Y 和色度信号 U、V 是分离的,那就是说即使只有 Y 信号分量而没有 U、V 分量,我们仍然可以表示出图像,只不过图像是黑白灰度图像。在YCbCr 中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量。
  • YCbCr 与 RGB 相互转换的公式:
    Y = 0.299R + 0.587G + 0.114BCb = 0.564(B - Y)Cr = 0.713(R - Y)R = Y + 1.402CrG = Y - 0.344Cb - 0.714CrB = Y + 1.772Cb

        

二、H264编码框架:

         视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式的文件的方式。H.264和H265编码是目前视频格式中用得最广泛的编码方式,H.264创造了多参考帧、多块类型、整数变换、帧内预测等新的压缩技术,使用了更精细的分像素运动矢量(1/4、1/8)和新一代的环路滤波器,使得压缩性能大大提高,系统更加完善。H.265是ITUTVCEG继H.264之后所制定的新的视频编码标准。H.265标准围绕着现有的视频编码标准H.264,保留原来的某些技术,同时对一些相关技术加以改进。H.265旨在在有限的带宽下传输更高质量的网络视频,仅需要原先的一半带宽即可播放相同质量的视频。

        1、H264码流文件分层:

  • VCL(Video Coding Layer,视频编码层):负责高效的视频内容表示,VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。
  • NAL(Network AbstractionLayer,网络提取层):负责以网络所要求的恰当的方式对数据进行打包和传送,是传输层。不管是在本地播放还是在网络上播放,都要通过这一层来传输。

        2、H264编码原理:

  •  H.264/AVC并未明确表述一个编解码器如何实现,而是规定了一个编码的视频比特流的句法和该比特流的解码方法,因此在实现上有较大的灵活性。H264和以前的H261、H.263、MPEG-1、MPEG-4 等的编解码器功能模块的组成类似,不同的部分是其内部各功能模块的细节部分,H.264编解码器的功能组成如下:

        

  •  H.264/AVC 编解码器的工作原理。H.264编码器采用变换和预测混合编码方式。编码时,首先输入的帧或场Fn以宏块为单位被编码器处理。宏块有帧内和帧间两种模式。帧内模式使用当前帧内已编码的宏块进行预测。帧间模式使用以往一个或多个帧作为参考进行运动预测。然后,对预测值和原始值的差值进行变换、量化、重新排序和编码,对量化系统X进行逆量化、逆变换后,与预测系统相加,得到未经滤波的uF*帧,对uF*帧进行块间滤波,得到当前重构帧 Fn*。而解码过程相对比较简单,对于编码器的各部分进行逆向操作,结果经逆量化、逆变换后通过滤波器得到重构输出图像。H.264编解码器工作原理如图:

        

         3、H264码流分析:

        H264码流的结构中包含 :H264视频序列——图像——片组——片——NALU——宏块 ——像素。从大到小排序               

  • H264编码格式:在 VCL数据传输或存储之前,这些编码的VCL数据先被映射或封装进NAL单元中。每个NAL单元包括一个原始字节序列负载(RBSP,RawByteSequencePayload)和一组对应于视频编码的 NAL 头信息。RBSP的基本结构:在原始编码数据的后面添加了结尾标记,一个比特“1”和若干比特“0”,以便字节对齐。H.264码流NAL单元序列如图        
  •  NAL Header:NAL头由一个字节组成,禁止位(1位)、重要性指示位(2位)、NALU类型(5位)。         

        

  •  RBSP:包括一系列的NAL单元,每个NAL单元包含一个RBSP。典型的RBSP单元序列。每个单元都按独立的NAL单元传送。NAL单元的信息头(1字节)定义了RBSP单元的类型,NAL单元的其余部分为RBSP数据。        

     

  • SODB ,String Of Data Bits 原始数据比特流:因为它是流的形式,所以长度不一定是8倍数,它是由 VLC 层产生的。由于我们计算机是以8倍数去处理数据所以计算机在处理H264时,就需要 RBSP。
  • RBSP,SODB + tailing bits (原始字节序列载荷):由于它是一个压缩流,SODB 不知道是在何处结束,所以算法在SODB最后一位补一个1,没有按字节对齐的则补 0。
  • EBSP (扩展字节序列载荷):在生成压缩流之后,在每一帧的开头加一个起始位,这个起始位一般是 00 00 00 01 或者是 00 00 01。所以在h264码流中规定每有两个连续的00 00,就增加一个0x03。
  • EBSP 和 RBSP的区别:NALU的组成部分为(NALU = NALU Header + RBSP),严格来说NALU的组成部分为(NALU = NALU Header + EBSP);
  •  NALU单元中的参数集:SPS(序列参数集)作用于一系列连续的编码图像;PSS(图像参数集)作用于编码视频序列中一个或多个独立的图像。参数集是一个独立的数据单位,不依赖于参数集外的其他句法元素。一个参数集不对应某个特定的图像或序列,同一序列参数集可以被一个或者多个图像参数集引用。同理,同一个图像参数集也可以被一个或者多个图像引用只在编码器认为需要更新参数集的内容时,才会发出新的参数集。         
  •  NALU中的视频帧:生成的H264视频帧是由多个切片组成的。一个H264的帧至少由一个切片组成,不能没有切片,可以是一个到多个不能没有。在网络传输的时候一个H264帧可能需要切开去传,一个一次传不完,这就按照切片来切。每一个切片组成一个NAL Unit。
  • 切片与宏块的关系:在切片数据中,包含若干个宏块。在一个宏块中,又包含了宏块类型、宏块预测、残差数据。

        4、H264码流结构图:        

         5、H264码流NAL单元解码流程:

        首先从NAL单元中提取出RBSP语法结构,然后按照下图所示的流程处理RBSP语法结构。输入的是NAL单元,输出结果是经过解码的当前图像的样值点。 NAL单元中分别包含了序列参数集和图像参数集。图像参数集和序列参数集在其他NAL单元传输过程中作为参考使用,在这些数据NAL单元的片头中,通过语法元素pic_parameter_set_id设置它们所使用的图像参数集编号;而相应的每个图像参数集中,通过语法元素seq_paramter_set_id设置他们使用的序列参数集编号。        

         6、H264解码详解:

         H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论依据是:参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内。所以对于一段变化不大图像画面,我们可以先编码出一个完整的图像帧A,随后的B帧就不编码全部图像,只写入与A帧的差别,这样B帧的大小就只有完整帧的1/10或更小!B帧之后的C帧如果变化不大,我们可以继续以参考B的方式编码C帧,这样循环下去。这段图像我们称为一个序列(序列就是有相同特点的一段数据),当某个图像与之前的图像变化很大,无法参考前面的帧来生成,那我们就结束上一个序列,开始下一段序列,也就是对这个图像生成一个完整帧A1,随后的图像就参考A1生成,只写入与A1的差别内容。

  • GOP:在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开始,到下一个I帧结束。 

  • GOP序列说明:在 H.264协议里定义了3种帧,完整编码的帧叫I帧,参考之前的I帧生成的只对差异部分进行编码的帧叫P帧,还有一种参考前后的帧进行编码的帧叫B帧。在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以帧开始,到下一个I帧结束,中间部分也被称为一个GOP。一个序列的第一个图像叫作IDR图像(立即刷新图像),IDR图像都是I帧图像。H.264引入IDR图像是为了解码的重新同步,当解码器解码到IDR图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找下一个参数集,开始解码一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以是一个Ⅰ帧,然后一直是P帧、B帧。当运动变化多时,一个序列可能会比较短,比如只包含一个I和几个P、B帧。
  •  I帧:指帧内编码帧,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)。特点如下:
    1. 它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;
    2. 解码时仅用I帧的数据就可以重构完整图像;
    3. I帧描述了图像背景和运动主体的详情;
    4. I帧不需要参考其他画面生成;
    5. I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各的质量);
    6. I帧是帧组GOP的基础帧(第1帧),在一组中只有一个I帧;
    7. I帧不需要考虑运动矢量;
    8. I帧所占数据的信息量比较大。
  • P帧的预测与重构:P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。 P帧特点如下::
    1. P帧是I帧后面相隔1~2帧的编码帧;
    2. P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
    3. 解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
    4. P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;
    5. P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
    6. 由于P帧是参考帧,它可能造成解码错误的扩散; 7.由于是差值传送,P帧的压缩比较高。
  • B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况,但我这样说简单些),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。

 

 

 

 

相关文章:

音视频及H264/H256编码相关原理

一、音视频封装格式原理: 我们播放的视频文件一般都是用一种封装格式封装起来的,封装格式的作用是什么呢?一般视频文件里不光有视频,还有音频,封装格式的作用就是把视频和音频打包起来。 所以我们先要解封装格式&#…...

查看cpu进程数

import multiprocessing from multiprocessing import Pool# 导入 Pool 允许你创建一个进程池 # 进程池是一组工作进程,它们可以并行地执行多个任务# multiprocessing.cpu_count(): 返回当前机器上的CPU核心数 sum_cpu multiprocessing.cpu_count()use_cpu max(1,…...

MySQL优化篇

文章目录 库表结构优化1.规范和反规范化2.数据类型选择3.主键类型选择 索引优化聚簇索引和辅助索引(一切的起源)复合索引 查询优化 库表结构优化 1.规范和反规范化 表设计之间性能和数据完整性,耦合和解耦合之间的取舍。 进而考虑是要冗余…...

Python3 笔记:部分专有名词解释

1、python 英 /ˈpaɪθən/ 这个词在英文中的意思是蟒蛇。但据说Python的创始人Guido van Rossum(吉多范罗苏姆)选择Python这个名字的原因与蟒蛇毫无关系,只是因为他是“蒙提派森飞行马戏团(Monty Python's Flying Ci…...

javaAPI文档中文版(JDK11在线版)java帮助文档,掌握文档java学习事半功倍。

🌠个人主页 : 赶路人- - 🌌个人格言 : 要努力成为梧桐,让喜鹊在这里栖息。 要努力成为大海,让百川在这里聚积。 11.by,prep.凭,靠,沿 [baɪ] 12.press,v.按,压 [prɛs] 菜鸟教程javaAPI文档中文…...

移动端适配:vw适配方案

vw (Viewport Width) 是一种长度单位,代表视口宽度的百分比。1vw 等于视口宽度的1%。在网页设计和前端开发中,vw 单位常用于实现响应式设计和屏幕适配,尤其是针对不同尺寸和分辨率的移动设备。 为什么使用vw适配? 响应式: 使用v…...

实战Java虚拟机-实战篇

一、内存调优 1.内存溢出和内存泄漏 内存泄漏(memory leak):在Java中如果不再使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏。内存泄漏绝大…...

力扣:349. 两个数组的交集

349. 两个数组的交集 给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2]示例 2: …...

深度学习之基于Matlab的BP神经网络交通标志识别

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着智能交通系统(ITS)的快速发展,交通标志识别&#xff0…...

Linux备份服务及rsync企业备份架构(应用场景)

备份服务概述 备份服务:需要使用到脚本,打包备份,定时任务. 备份服务:rsyncd服务,不同主机之间数据传输. 特点: rsync是个服务也是命令使用方便,具有多种模式传输数据的时候是增量传输 增量与全量: 全量 :无论多少数据全部推…...

用手机打印需要下载什么软件

在快节奏的现代生活中,打印需求无处不在,无论是工作文件、学习资料还是生活小贴士,都可能需要一纸呈现。然而,传统的打印方式往往受限于时间和地点,让人倍感不便。今天,就为大家推荐一款便捷又省钱的手机打…...

Storm在Java中的应用

Storm在Java中的应用主要体现在构建分布式实时计算系统,用于处理大数据流。以下是一些Storm在Java中的具体应用场景和步骤: 实时数据处理:Storm可以实时地接收、处理和传输数据。对于需要快速响应的应用场景,如在线广告、金融交易…...

Java 面试题日常练习

### 基础知识 1. **什么是 JVM?解释其架构。** - JVM(Java Virtual Machine)是 Java 程序的运行时环境。其架构包括类加载器子系统、运行时数据区(堆、栈、本地方法栈、PC 寄存器、方法区)、执行引擎和本地方法接口…...

卷爆短剧出海:五大关键,由AIGC重构

短剧高温下,谈谈AIGC的助攻路线。 短剧,一个席卷全球的高温赛道。 以往只是踏着霸总题材,如今,内容循着精品化、IP化的自然发展风向,给内容、制作、平台等产业全链都带来新机,也让短剧消费走向文化深处&am…...

LLM实战:当网页爬虫集成gpt3.5

1. 背景 最近本qiang~关注了一个开源项目Scrapegraph-ai,是关于网页爬虫结合LLM的项目,所以想一探究竟,毕竟当下及未来,LLM终将替代以往的方方面面。 这篇文章主要介绍下该项目,并基于此项目实现一个demo页面&#x…...

Flutter底部导航栏和顶部Tab切换完整代码

题记 —— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。 目前市场上绝大部分App的布局结构基本统一:底部导航顶部导航,底部导航页里嵌套顶部导航栏,顶部导航页里嵌套图文…...

Jupyter 使用手册: 探索交互式计算的无限可能

什么是 Jupyter? Jupyter 是一个开源的 Web 应用程序,可用于创建和共享包含实时代码、可视化和叙述性文本的文档。它最初是作为 IPython 项目的一部分开发的,后来发展成为支持多种编程语言的交互式计算环境。 应用场景 作为一个开源的交互式计算环境,Jupyter 在以下几个领域…...

IP地址显示“不安全”怎么办|已解决

解决IP地址显示“不安全”的问题,通常需要确保网站或服务使用HTTPS协议进行加密通信,可以通过部署SSL证书来解决,以下是具体的解决步骤: 1 申请IP地址SSL证书:网站管理员应向证书颁发机构(CA)申…...

国内安全实用的图纸透明加密软件厂家,靠谱的透明加密软件供应商--安秉信息

设计类图纸安全已经成为企业需要注意的问题,在当前互联网设计行业、汽车制造设计、机械制造行业等相关企业都需要对企业内部图纸的保护需求,现在在互联网中,企业数据泄露的事情已经层出不穷,企业对核心图纸的数据安全工作需要重点…...

【kubernetes】探索k8s集群中kubectl的陈述式资源管理

目录 一、k8s集群资源管理方式分类 1.1陈述式资源管理方式:增删查比较方便,但是改非常不方便 1.2声明式资源管理方式:yaml文件管理 二、陈述式资源管理方法 2.1查看版本信息 2.2查看资源对象简写 2.3配置kubectl自动补全 2.4node节点…...

微信小程序之bind和catch

这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

PHP和Node.js哪个更爽?

先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...