RTSP实时音视频开发实战课程:
音视频开发入门基础知识(音频入门篇)
目录
一、前言
二、视频采集和显示
三、视频常见的格式
四、RGB转YUV和YUV转RGB
五、视频的压缩编码
当前随着科技的进步和人们生活水平的不断提高,现在人们在茶余饭后都会使用手机、电脑等这类产品,来看一些有趣的视频,来娱乐自己;而这些都离不开音视频技术的支持。本文开始介绍视频开发中最基本的技术知识,比如视频采集和显示、视频常见的格式、视频压缩编码等。
首先要知道我们是如何看到他人的视频的;如下图所示,视频/声音通过摄像头/麦克风采集后(捕捉)将视频/声音通过网络发送出去,其他人通过网络接收后在视频显示屏幕上显示,声音在扬声器播放,比如我们通过抖音、朋友圈视频等,都是拍摄视频上传,通过网络传输,之后在通过网络接收来播放视频和声音;另外视频/声音通过摄像头/麦克风采集后(捕捉)将视频/声音保存为文件存储,通过播放器选择文件来播放来将视频显示到屏幕上,声音通过扬声器播放,比如我们手机通过相机拍摄后就是保存在手机中,然后通过手机自带播放器来播放视频和声音。
人们要想看到自然界中的景象就需要光,通过光的传递将自然界的景象传递给人眼。我们手机/相机对景象的采集也是通过光。如下图是视频/图像采集的一个过程;通常自然界的人物景象通过光电转换将光信号转换为电信号,常见的光电转换就是摄像头感光元器件;电信号经过处理器转为数字信号,程序就可以将数字信号进行存储为文件。
那么显示器是如何显示数字图像的呢?如下图是显示数字图像的过程;处理器将数字信号转为电信号,电信号通过电光转换器转换为光信号就可以被人眼观察到,通常电信号转为光信号的有发光二极管、液晶显示器等。
任何一个和视频或者一个图像都有一个像素格式,而像素是指在数字图像/视频中一个最小的颜色单位,在图像/视频中按照水平+垂直的方向进行排列,通过像素的位置和颜色就可以呈现真实景象的样子。如下图是一副图像,下图的一个格子就可以认为是一个像素(实际进行了放大)。水平和垂直方向的数字520和280就是这个图像的大小,也叫图像的宽度和高度,通常也叫分辨率520x280,也就是图像的宽度是520,高度是280,单位就是像素。
经过摄像头/处理器得到的视频/图像的像素格式通常有RGB、YUV等格式,在这里我们重点介绍RGB和YUV。
什么是RGB?RGB格式也叫RGB色彩,就是常说的光学三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色);自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成。在RGB格式的图像中一个像素包含了R、G、B三个颜色,其中每个颜色占8bit,也就是一个字节,三个颜色就是24bit(3个字节),由于一个R、G或者B占用8bit那么其锁表达的数字范围就是0-255,所以单个颜色所能表示的颜色范围只有256中。通常为了方便图像的存取RGB图像的三个颜色是交叉存储的,如下图,一个像素的RGB存储完之后存下一个像素的RGB。一副分辨率为520x280的RGB格式的图像其大小为520x280*3=436800字节=426.5625KB。
此外对于RGB图像格式不同可能每个像素大小不同,除了RGB还有其他格式比如RGBA,ARGB、BGR等、对于RGBA和ARGB是在RGB颜色上多了一个Alpha,也通常指图像的透明度,也占用一个字节;对于ARGB和RGBA格式的图像来说每一个像素占32bit(4个字节),一副分辨率为520x280的ARGB/RGBA格式的图像其大小为520x280*4=582400字节=568.75KB。BGR图像格式和RGB的格式像素大小都是24bit仅仅是RGB的存储顺序不同,RGB是先存储Red颜色,BGR是先存储Blue颜色。另外还有些更高bit的RGB存在比如10bit的RGB甚至16bit的RGB,10bit和16bit的RGB和8bit的RGB相比大小会明显增大,此外10bit和16bit由于单个像素的bit数增加那么所表达的颜色范围也会增加,比如10bitRGB单个颜色可以表示的颜色有1024中,比8bitRGB高出4倍。
什么是YUV?YUV是是一种颜色编码方法,通常是对RGB进行颜色转换得到YUV。Y通常是颜色中的亮度信息(灰度信息),UV是颜色中的彩色信息。通常人眼对事物颜色的亮度和彩色信息的敏感程度不同,大多是对亮度敏感度较高,对彩色信息敏感度较低,所以将颜色的亮度和彩色信息分离表示可以有助于图像的编码。通常YUV的格式有YUV444、YUV422、YUV420;YUV444表示的YUV图像中亮度和彩色信息所占空间大小是1:1:1(Y:U:V);YUV422表示的YUV图像中亮度和彩色信息所占空间大小是2:1:1(Y:U:V),即彩色信息比亮度信息比较降低了一半的信息和存储空间;YUV420表示的YUV图像中亮度和彩色信息所占空间大小是4:1:1(Y:U:V),即彩色信息比亮度信息比较降低了3/4的信息和存储空间,通常是减少彩色信息来降低存储空间大小的一种格式;YUV420的存储空间结构可以如下图所示,先存储32个Y,在存帧8个U和8个V。
在实际的视频和图像编码中使用的YUV格式大多是YUV420的。可以发现上图YUV420的存储结构是三分量是单独存储的,除了上面的单独存储外还有UV交织存储的YUV格式,比如NV21,NV12,这两种也是比较常见的YUV格式。NV21通常是V在前U在后的存储方式,NV12是U在前V在后的存储方式.,如下图左侧是NV12,右侧是NV21.
YUV图像格式通常一个像素由Y分量和U、V分量表示,三个分量通常都是占8bit(一个字节),对于YUV420(NV21/NV12)的图像来说一个像素需要1.5个字节(一个字节的Y和0.25字节的U+0.25字节的V)表示;一副520x280的YUV420图像大小为520x280x1.5=218400字节=213.28KB,可以看到YUV420的格式图像比同分辨率的RGB的大小降低了一半。和RGB一样,YUV不仅有8bit的数据也有10bit、12bit表示的,对于Y(亮度)10bit的数据可以表示0-1023范围的亮度,UV10bit的数据可以表示0-1023范围的色度。
通常情况下RGB图像的大小比较大,占用存储空间,所示需要对RGB格式进行压缩,通常RGB压缩为YUV(通常是YUV420),RGB压缩为YUV的过程也就是RGB转YUV的公式如下,下面的公式是BT709色域空间下的RGB转YUV的公式。
BT709
Y = 0.183*R + 0.614*G + 0.062*B + 16;
U = 0.439*B - 0.339*G - 0.101*R + 128;
V = 0.439*R - 0.399*G - 0.040*B + 128;
下面的公式是BT601色域空间下的RGB转YUV的公式。
BT601
Y = 0.257*R + 0.504*G + 0.098*B + 16;
U = 0.439*B - 0.291*G - 0.148*R + 128;
V = 0.439*R - 0.368*G - 0.071*B + 128;
关于BT709和BT601是国际标准中不同的两种色域(也就是表示红绿蓝颜色的范围)。
另外在显示图像数据的时候通常都是按照RGB数据格式进行显示二点,所以还需要将YUV转RGB,下面的公式是BT709色域空间下的YUV转RGB的公式。
BT709
R = 1.164*(Y-16) + 1.792*(V-128);
G = 1.164*(Y-16) - 0.213*(U-128) - 0.534*(V-128);
B = 1.164*(Y-16) + 2.114*(U-128);
下面的公式是BT601色域空间下的YUV转RGB的公式。
BT601
R = 1.164*(Y-16) + 1.596*(V-128);
G = 1.164*(Y-16) - 0.392*(U-128) - 0.812*(V-128);
B = 1.164*(Y-16) + 2.016*(U-128);
上面的RGB和YUV的介绍中我们可以知道,一副格式为YUV420,分辨率为520x280的图像占用213.28KB,如果是格式为YUV420,分辨率为520x280,帧率为30帧每秒的视频其大小为
520x280x1.5x30=6398.4375KB=6.25MB,如果视频分辨率是高清也就是1920x1080,则视频的大小为1920x1080x1.5x30=91125KB=88.99MB,如果你要从网上看格式为YUV420,分辨率1920x1080,帧率30帧每秒的视频则需要的网速是88.99MB*8=711.9Mb每秒,网速一般人根本达不到。如果你要是录制格式为YUV420,分辨率1920x1080,帧率30帧每秒,时常为1小时的视频则大小是:1920x1080x1.5*30*60*60=320364MB=312.8GB,这么大的存储空间,一部256G内存的手机根本不够,所以需要对YUV视频进一步压缩才能满足我们日常视频拍摄,浏览的需求。
目前视频压缩编码算法标准比较多,通常使用较多的是H264(也叫AVC)和H265(也叫HEVC);使用H264对YUV420的图像进行压缩,压缩率可以达到100倍-200倍,而不影响视频的观看,H265编码算法可以达到300倍的压缩率。下图是H264的编码框图。
下图是H265的编码框图。
根据H264和H265的编码框图看出H265b编码更加复杂。实际上H265的压缩效率比H264的要高,但是同时H265的编码器实现更加困难,目前开源的H265编码器X265比H264开源的X264编码器速度要慢上很多。
下图是视频解码到显示的数据流程。
H264和H265编码器对YUV进行压缩,主要过程是对视频YUV进行编码,将YUV数据编码为IDR帧、P帧、B帧;
IDR帧(Instantaneous Decoding Refresh),即时解码刷新,是视频的关键帧,他的解码不需要依赖其他视频帧。解码器遇到这个帧会将之前的解码信息清空,根据当前的IDR帧解码生成新的解码信息。视频编码帧中可以有多个IDR帧。
P帧 是前向预测编码的视频帧,他的解码只能参考他前面的P帧或者IDR帧。
B帧 是双向预测编码的视频帧,他的解码需要参考前面的P帧或者IDR帧,也需要参考他后面的P帧或者IDR帧。
通常IDR帧采用帧内压缩方式,只消除空域上的内容冗余,压缩率比较低;P帧采用帧内和帧间的压缩方式不仅消除空间上的冗余也可以消除时间上的冗余,压缩效率比较高;B帧也采用帧间帧内和帧间的压缩方式,也会消除空间和时间上的冗余,其采用双向预测编码可以进一步降低时间冗余。因此视频压缩的目的是降低视频内容的冗余,用更少的数据来保存图像信息。
下图是H264/H265视频编码帧结构图
有关H264和H265视频码流的分析如下文章:
H264视频码流结构分析
H265视频码流结构分析