视频相关的一些基本概念

        本文主要阐述和讲解视频相关的一些基本概念,以此记录,方便他人学习也方便自己查阅。视频相关的很多概念,作为音视频开发来说,是需要先去做了解的,比如帧率,码率,IPB帧等等一些概念。

一、像素、位深和分辨率

1、像素

        像素这个概率并不陌生,很多手机都会说自己的摄像头是多少多少像素。像素越高,图像就会越清晰。

        像素是图像的基本单元,一个一个像素就组成了一张图像,可以说像素就是图像中的一个点。所以当一张图像像素越高,那么其中的点就越多,看起来就越清晰。

2、分辨率

        分辨率其实就是代表一张图像是有多少个像素点组成的,也就是图像的尺寸或大小。比如一张图像分辨率是1920*1080,那么就代表它有1920*1080个像素点。

        视频行业常见的分辨率有 QCIF(176x144)、CIF(352x288)、D1(704x576 或 720x576),还有比较熟悉的 360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)等。

3、位深  

        上面我们有说到像素是一个点,那么在彩色图像中,一个点一般会有三个通道,或者叫颜色通道,即是R、G、B这三个通道。RGB分别代表红绿蓝三个颜色值,三个颜色组成多种多样的颜色。

        而一般来说,RGB各占8个位,也就是一个字节。8 个位能表示 256 种颜色值,那 3 个通道的话就是 256 的 3 次方个颜色值,总共是 1677 万种颜色。我们称这种图像是 8bit 图像,而这个 8bit 就是位深。位深越大,我们能够表示的颜色值就越多。

        8bit图像是我们最常见的,此外还有10bit图像、12bit图像等。

二、YUV & RGB

        上面我们有讲到像素是图像的基本单元,而对于像素点来说,颜色空间是非常重要

的知识点。我们一般会用RGB或者YUV来表示一个像素点的颜色。

1、RGB

        RGB比较简单,代表红绿蓝三个颜色值,这三个颜色值分别取不同的值,即可构成多种多样的颜色。一个像素点由这3个值来进行表示。

        处理图像,或者渲染一般都是会用到RGB。

2、YUV 

        在视频领域,其实我们更多地会用到YUV,它也是一种颜色的表示,但是比起RGB会复杂很多。简单的说,YUV 图像将亮度信息 Y 与色彩信息 U、V 分离开来。Y 表示亮度,是图像的总体轮廓,称之为 Y 分量。U、V 表示色度,主要描绘图像的色彩等信息,分别称为 U 分量和 V 分量。

        YUV在视频领域非常重要也是基础必学的知识,因为我单独给它转载了一篇文章。关于YUV的具体格式和采样方式等,详细的可从下面我转载的这篇文章中仔细去了解:

        一文读懂 YUV 的采样与格式

三、帧率和码率

1、帧率

        我们知道视频是由一帧帧图像组成的。在视频播放过程中,1秒钟播放的图像的数量就是帧率,单位是帧/每秒。一般来说,帧率达到10~12帧每秒,人眼就会认为是流畅的。

        选择帧率的时候需要考虑设备处理性能的问题,尤其是实时视频通话场景。帧率高,代表着每秒钟处理的图像数量会很高,从而需要的设备性能就比较高。如果是含有多个图像处理过程,比如人脸识别、美颜等算法的时候,就更需要考虑帧率大小和设备性能的问题。同样,也要考虑带宽流量的问题。帧率越大,流量也会越多,对带宽的要求也会越高。

2、码率

        帧率是以图像的张数来计量的,每秒多少张/帧图像,但是至于图像大小是不关心的。而码率代表的是1秒内的图像的数据量大小,单位是Kb/s或者是Mb/s

        通常,我们用压缩工具压缩同一个原始视频的时候,码率越高,图像的失真就会越小,视频画面就会越清晰。但同时,码率越高,存储时占用的内存空间就会越大,传输时使用的流量就会越多。

        但是是不是码率越高,清晰度就越高呢?这并不能一概而论,因为视频的压缩是一个非常复杂的过程,视频压缩之后的清晰度还跟压缩时选用的压缩算法,以及压缩时使用的压缩速度有关。压缩算法越先进,压缩率就会越高,码率自然就会越小。压缩速度越慢,压缩的时候压缩算法就会越精细,最后压缩率也会有提高,相同的清晰度码率也会更小。

        由上可见,对比帧率和码率,是针对不同场景的描述。帧率不关心每帧图片的大小,只关注每秒的帧数,表达的是视频播放时候的流畅度的问题。而码率关心的是每帧图片的大小,表达的是视频的清晰度的问题。这两者就有点像我们看视频的时候,对流畅度和清晰度的选择。

        

四、I、P、B帧和GOP

1、I、P、B帧

        视频压缩中,每帧代表一幅静止的图像。而在实际压缩时,会采取各种算法减少数据的容量,比如H264压缩编码等,其中IPB就是最常见的。

        简单地说,I帧是关键帧,属于帧内压缩。就是和AVI的压缩是一样的。 P是向前搜索的意思。B是双向搜索。他们都是基于I帧来压缩数据。

        I帧表示关键帧,可以理解为这一帧画面的信息完整保留;解码时只需要本帧数据就可以完成图像的还原(因为包含完整画面)

        P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)

        B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。

        由此可见,如果一个视频中采用B帧压缩比较多,则压缩率会高很多,但是解码时CPU会比较累,因为总是需要双向搜索才能解析出来。

         三种帧的示例图如下所示。例如,从左向右,第一个 B 帧参考第一个 I 帧和第一个 P 帧,第一个 P 帧只参考第一个 I 帧(箭头是从参考帧指向编码帧)。

2、IDR帧

        在关键帧I帧中,我们还会定义一个特殊的I帧,称之为IDR帧,也叫立即刷新帧。这个帧是干嘛用的呢?

        在上述所讲的B帧和P帧,它们是会去参考其他的帧来进行解析的。假如前面有一帧I帧出错了,那么后面参考它的P帧也出错了,接着参考这个I帧或P帧的其他P帧和B帧,也都相继出错。错误可能就会不断传递下去。为了防止这种情况,H264 编码标准中规定,IDR 帧之后的帧不能再参考 IDR 帧之前的帧。也就是说我们在编码的时候可以编码一个IDR帧,这样这个帧之前的若有错误的帧,对这个IDR帧之后的数据的解析就不会有影响了。

        实际上,在真实场景中,我们大概率会用IDR帧,而比较少用普通的I帧。不过如果你只用普通的I帧,标准也是支持的,但是不推荐。

3、GOP

        GOP是代表从一个 IDR 帧开始到下一个 IDR 帧的前一帧为止的中间包含的所有IDR 帧、普通 I 帧、P 帧和 B 帧,也就是一个图像组。GOP的大小就是两个IDR帧之间的间隔,也就关键帧间隔。

         GOP 越大,编码的 I 帧就会越少。相比而言,P 帧、B 帧的压缩率更高,因此整个视频的编码效率就会越高。但是 GOP 太大,也会导致 IDR 帧距离太大,点播场景时进行视频的 seek 操作就会不方便。并且,在 RTC 和直播场景中,可能会因为网络原因导致丢包而引起接收端的丢帧,大的 GOP 最终可能导致参考帧丢失而出现解码错误。

        因此GOP不是越大越好,也不是越小越好,要根据实际场景来决定。

五、DTS & PTS

        视频和音频的同步过程是一个你等我赶的过程,快了则等待,慢了就加快速度。这就需要一个量来判断(和选择基准比较),到底是播放的快了还是慢了,或者正以同步的速度播放。在视音频流中的包中都含有DTS和PTS,就是这样的量。

        DTS(Decoding Time Stamp):解码时间戳;告诉解码器packet的解码顺序,也就是先解哪个包,才能解哪个包,需要按照顺序来,才能正确地一个一个解析出来。

        PTS(Presentation Time Stamp):显示时间戳;指得是packet解析出来后,要显示的时候是想显示哪个再显示哪个,指明的数据的显示播放的顺序。

        在这里可能有人会有个疑问,这两个东西为什么会不同?一个一个解析,然后一个一个显示,这样的话不就两个应该是一样的吗?

        其实,之所以两者会不同,主要也是跟上面提到的I、B、P帧有关,尤其是B帧,因为B帧要解析需要参考前面的或者后面的帧率,那么就代表着B帧没法按照显示顺序来解析,可能需要先解析后面的某个I帧,P帧,才能解析当前的这个B帧。这也是导致两者时间顺序不同的主要原因。

        例如,假如一个视频序列,要这样显示I B B P,但是需要在B帧之前得到P帧的信息,因此帧可能以这样的顺序来存储I P B B,这样其解码顺序和显示的顺序就不同了,这也是DTS和PTS同时存在的原因。DTS指示解码顺序,PTS指示显示顺序。所以流中可以是这样的:

六、Stride

        这是一个特别的概念,某种程度上来说这个不属于基本概念之一,它不是图像本身的属性,但是视频开发者经常会碰到,也是经常会出问题的一个东西。

        Stride 也可以称之为跨距,是图像存储的时候有的一个概念。它指的是图像存储时内存中每行像素所占用的空间。

        这个可能会有个疑问,一张图像的分辨率确定了,那一行的像素值不就确定了吗?

        实际上,由于芯片处理器处理的时候为了能够快速读取一行像素,一般会对内存中的图像实现内存对齐,比如 16 字节对齐。那么,假如现在有一张 RGB 图像,分辨率是 1278x720。我们将它存储在内存当中,一行像素需要 1278x3=3834 个字节,3834 除以 16 无法整除。因此,没有 16 字节对齐。所以如果需要对齐的话,我们需要在 3834 个字节后面填充 6 个字节,也就是 3840 个字节做 16 字节对齐,这样这幅图像的 Stride 就是 3840 了。如下图所示:

         这个就是stride,当处理这个图像时候,每读取一行数据的时候需要跳过这多余的 6 个字节。不然就肯定出错了。所以,不管去读取还是渲染一张图片,还是说将这张图片存储下来,都需要设置正确的 Stride。

        以上,便是视频相关的一些基本概念。

猜你喜欢

转载自blog.csdn.net/weekend_y45/article/details/125058275