图像基础知识
像素
像素是图像的基本单元,一个个像素就组成了图像。你可以认为像素就是图像中的一个点。在下面这张图中,你可以看到一个个方块,这些方块就是像素
分辨率
图像(或视频)的分辨率是指图像的大小或尺寸。我们一般用像素个数来表示图像的尺寸。比如说一张1920x1080的图像,前者1920指的是该图像的宽度方向上有1920个像素点,而后者1080指的是图像的高 度方向上有1080个像素点。
Stride
Stride也可以称之为跨距,指的是图像存储时内存中每行像素所占用的 空间。跨距为了能够快速读取一行像素,我们一般会对内存中的图像实现内存对齐,比如16字节对齐。
比如有一张RGB图像,分辨率是1278x720。我们将它存储在内存当中,一行像素需要 1278x3 = 3834个字节,3834除以16无法整除。因此,没有16字节对齐。所以如果需要对齐的话,我们需 要在3834个字节后面填充6个字节,也就是3840个字节做16字节对齐,这样这幅图像的Stride就是3840了。
图像显示格式
RGB
我们看到的彩色图像中,都有三个通道,这三个通道就是R、G、B通道,(有的时候还会有Alpha值,代表透明度) 通常R、G、B各占8个位,我们称这种图像是8bit图像。
YUV
对于图像显示器来说,它是通过RGB模型来显示图像的。而在传输图像数据时是使用YUV模型的,因为YUV模型可以节省带宽。所以就需要采集图像时将RGB模型转换到YUV模型,显示时再将YUV模型转换为RGB模型。
YUV解决了彩色电视机与黑白电视的兼容问题,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的。
YUV更方便对视频信号进行压缩,占用的带宽更低。符合人眼的视觉特性,人眼对亮度的敏感度要大于红蓝,所以我们可以保留Y原始值的基础上,降低U和V的值,而不影响观看,从而更加有效的存储图像数据。
YUV不像RGB那样要求三个独立的的视频信号同时传输,所以YUV方式传送占用极少的频宽。
YUV 颜色编码采用的是 明亮度 和 色度 来指定像素的颜色。其中,Y 表示明亮度(Luminance、Luma),而 U 和 V 表示色度(Chrominance、Chroma)。YUV主要分为YUV 4:4:4,YUV 4:2:2,YUV 4:2:0几种常用类型。
YUV 4:4:4采样
意味着Y、U、V三个分量的采样比例相同,所以在生成的图像里,每个像素的三个分量信息都是8bit,所以相比RGB颜色模型的图片大小一样。
YUV 4:2:2采样
UV分量是Y分量的一半,Y分量和UV分量按照2:1的比例采样,如果水平方向有10个像素点,那么采样了10个Y分量,就只采样了5个UV分量,第一个像素和第二个像素共用一个UV ,相较RGB可以节省1/3 的空间,更利于图像传输。
YUV 4:2:0采样
YUV 4:2:0 采样,并不是指只采样 U 分量而不采样 V 分量。而是指,在每一行扫描时,只扫描一种色度分量(U 或者 V),和 Y 分量按照 2 : 1 的方式采样。比如,第一行扫描时,YU 按照 2 : 1 的方式采样,那么第二行扫描时,YV 分量按照 2:1 的方式采样。对于每个色度分量来说,它的水平方向和竖直方向的采样和 Y 分量相比都是 2:1 。 相较RGB 可以节省1/2的存储空间,也是当下主流的采样方式 (Android Camera 预览流返回格式)。
音频基础知识
由物理学可知,复杂的声波由许多具有不同振幅和频率的正弦波组成。代表声音的模拟信息是个连续的量,不能由计算机直接处理,必须将其数字化。数字声音信息才能够像文字和图形信息一样进行存储、检索、编辑和其它处理。
采样:以适当的时间间隔观测模拟信号波形不连续的样本值替换原来的连续信号波形的操作,又称为取样 。为了复原波形,一次振动中,必须有2个点的采样,人耳能够感觉到的最高频率为20kHz,因此要满足人耳的听觉要求,则需要至少每秒进行40k次采样
量化:数字音频中,把表示声音强弱的模拟电压用数字表示。模拟电压的幅度,即使在某电平范围内,仍然可以有无穷多个,如1.2V,1.21V,1.215V…。而用数字来表示音频幅度时,只能把无穷多个电压幅度用有限个数字表示。即把某一幅度范围内的电压用一个数字表示,这称之为量化。
编码: 将量化后的数据转为二进制
视频基础知识
下图可以很清晰的说明决定视频画质的几个要素
分辨率
视频分辨率又可称为视频解析度、解像度,指的是视频图像在一个单位尺寸内的精密度。
帧率
在视频中,一个帧(Frame)就是指一幅静止的画面。帧率,就是指视频每秒钟包括的画面数量(FPS,Frame per second)。
码率
编码器每秒编出的数据大小,单位是kbps,比如上图的3000kbps代表编码器每秒产生 375kb 的数据
编码
编码的终极目的,就是为了压缩。各种视频编码方式,都是为了让视频变得体积更小,有利于存储和传输。
要实现压缩,就要设计各种算法,将视频数据中的冗余信息去除。
如果一幅图,全是红色的,我有没有必要说2073600次[255,0,0] ,还是我只要说一次[255,0,0],然后再说2073599次“同上”?
如果一段视频,大部分画面是不动的,或者,有80%的图像面积,整个过程都是不变的。那么,是不是这块存储开销,就可以节约掉了?
基本原理:
空间冗余:图像相邻像素之间有较强的相关性;
时间冗余:视频序列的相邻图像之间内容相似;
编码冗余:不同像素值出现的概率不同;
视觉冗余:人的视觉系统对某些细节不敏感;
知识冗余:规律性的结构可由先验知识和背景知识得到。
宏块
每一帧图像,又是划分成一个个块来进行编码的,这一个个块在H264中叫做宏块,而在VP9、AV1 中称之为超级块,其实概念是一样的。宏块大小一般是16x16 (H264、VP8) , 32x32 (H265、VP9), 64x64 (H265、VP9、AV1) , 128x128 (AV1)这几种。这里提到的H264、H265、VP8、VP9和AV1都是市面上常见的编码标准。
帧类型
帧间预测需要参考已经编码的帧,帧间编码帧可以分为只参考前面帧的前向编码帧和前后都可以参考的双向编码帧。
I帧:是自带全部信息的独立帧,是最完整的画面(占用的空间最大),无需参考其它图像便可独立进行解码。视频序列中的第一个帧,始终都是I帧。
P帧:“帧间预测编码帧”,需要参考前面的I帧和/或P帧的不同部分,才进行编码。P帧对前面的P和I参考帧有依赖性。
B帧:“双向预测编码帧”,以前帧后帧作为参考帧。不仅参考前面,还参考后面的帧,所以,它的压缩率最高,可以达到200:1。
如图,箭头是从参考帧指向编码帧
GOP(序列)和IDR
在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流。
一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据输出或抛弃,重新查找参数集,开始一个新的序列。如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
一个序列就是一段内容差异不大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,所可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了,比如就包含一个I帧和1、2个P帧。
在视频编码序列中,GOP即Group of picture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离。两个I帧之间形成一组图片,就是GOP(Group Of Picture)。
PTS和DTS
如果IBP数据流并非有序返回,存在先到的B、P帧等I帧的情况,就需要引入 PTS和DTS概念
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
假设编码器采集到的帧是这个样子的:I B B P B B P 1 2 3 4 5 6 7
假设 编码器的编码顺序是: I P B B P B B 1 4 2 3 7 5 6
接收端 根据PTS 显示对应的数据