1 音视频录制和播放原理
1.1 录制原理
若想记录生活中的影像又或声音,我们需要借助摄像头和麦克风两个输入源来实现对音视频的采集,而其内部工作原理也有章可循。
如图:
麦克风通过时钟控制频率去采帧,经过特定的音频处理后放入帧队列,然后对音频进行编码,最后通过复用器输出对声音记录的文件。
同理,摄像头经过采样图像帧和视频编码,最终通过复用器输出对图像的连续记录文件。
关键点有:每一秒采集多少个图像帧、多长时间的音频算是一个音频帧、音视频编码的主要作用是压缩数据、复用器就是封装音视频到一个具体格式下、音频处理主要是变音、降噪等等,图像处理主要是比如调整亮度等操作、时钟主要做音视频同步用,避免图像和声音不匹配的情况。
1.2 播放原理
播放媒体文件,我们则需要用到解复用器,通过对音视频的包进行相应的解码(视频解码、音频解码),将包转化为帧,通过同步控制对图像音频进行处理,最终呈现在机器荧幕上。
2 图像基础概念
像素:
像素是一个图片的基本单位,pix是英语单词picture的简写,加上英 语单词“元素element”,就得到了“pixel”,简称px,所以“像素”有“图像元素” 之意。
像素是一个图片的基本单位,pix是英语单词picture的简写,加上英语单词“元素element”, 就得到了“pixel”,简称px,所以“像素”有“图像元素”之意。 例如2500×2000的照片就是指横向有2500个像素点,竖向有2000个像素点,总共是500万 个像素,也俗称500万像素照片。
分辨率:
是指图像的大小或尺寸。比如1920x1080。
图像(或视频)的分辨率是指图像的大小或尺寸。我们通常用像素表示图像的尺寸。
例如2500×2000的照片就是指横向(宽)有2500个像素点,竖向(高)有2000个像素点。 常见的分辨率: 360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)
常说的1080 和720 其实是指垂直像素数,分辨率除去垂直像素,还需要考虑到水平像 素数。按照16:9 (宽: 高) 的比例计算,720p 的水平像素数为720 ÷9 ×16 = 1280,总 计像素为921600像素即大约为92 万像素。1080p 具有1920 个水平像素,总计2073600 像素即约200 万像素,是720p 的两倍多
像素越多视频就越清晰,所以1080p 比720p 的视频更加清晰。图像的分辨率越高,图像就越清晰(不绝对,清晰度还跟原始图像有关系,如果原始图像本来就不清晰,分辨率再高也还是不清晰的)。
位深:
是指在记录数字图像的颜色时,计算机实际上是用每个像素需要的 位深来表示的。比如红色分量用8bit。
我们看到的彩色图片,都有三个通道,分别为红(R)、绿(G)、蓝(B)通道。(如果需 要透明度则还有alpha分量)
通常每个通道用8bit表示,8bit能表示256种颜色,所以可以组成 256*256*256=16,777,216 = 1677万种颜色。 这里的8bit就是我们讲的位深。
每个通道的位深越大,能够表示的颜色值就越大,比如现在高端电视说的10bit色 彩,即是每个通道用10bit表示,每个通道有1024种颜色。1024*1024*1024约为 10,7374万色=10亿色,是8bit的64倍。 常见的颜色还是8bit居多。(可以把深度当多每个颜色的梯度,位深越多梯度越多,表示的内容就越多)
帧率:
在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟 能够刷新几次。比如25fps表示一秒有25张图片。
帧率即FPS(每秒有多少帧画面),经常玩游戏的同学应该会对这个词很熟悉。我们玩游 戏时,FPS 帧率越高就代表游戏画面越流畅,越低则越卡顿。视频也是如此。
由于视觉图像在视网膜的暂时停留,一般图像帧率能达到24帧,我们就认为图像是连续动态的。
电影帧率一般是24fps(帧每秒); 电视剧一般是25fps; 监控行业常用25fps; 音视频通话常用15fps;
帧率越高,画面越流畅,需要的设备性能也越高。
码率:
视频文件在单位时间内使用的数据流量。比如1Mbps。
大多数情况下码率越高分辨率越高,也就越清晰。但模糊的视频文件大小(码率)也 可以很大,分辨率小的视频文件可能也比分辨率大的视频文件清晰。
对于同一个原始图像源的时候,同样的编码算法,则码率越高,图像的失真就会越小, 视频画面就会越清晰。
Stride:
指在内存中每行像素所占的空间。为了实现内存对齐每行像素在内存中所占的空间并不一定是图像的宽度。
Stride 就是这些扩展内容的名称,Stride 也被称作Pitch,如果图像的每一行像素末尾拥 有扩展内容,Stride 的值一定大于图像的宽度值。
比如分辨率638x480的RGB24图像,我们在内存处理的时候如果要以16字节对齐, 则638*3/16=119.625不能整除,因此不能16字节对齐,我们需要在每行尾部填充6 个字节。就是(638+2->640), 640*3/16=120。此时该图片的stride为1920字节。
3 图像的表示
RGB:红R、绿G、蓝B三基色。
YUV:“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表 示的则是色度(Chrominance或Chroma)。
2.1 RGB格式
我们应当知道,我们平时看到的“颜色”是由“三原色”构成,而三原色指的是红、绿、蓝这三种颜色。因此在计算机中我们也采用这个概念,设计了R(Red)、G(Green)、B(Blue)三个键值组合起来指示一种具体的颜色。
通常的图像像素是按 RGB顺序进行排列,但有些图像处理要转成其他顺序,比如OpenCV经常转成BGR的 排列方式。
值得注意的是,这每个键值的位宽是8bit,因此单一键值可以有种组合方式,那么三种键值所能构成的指定颜色则有
。
2.2 YUV格式
YUV格式一开始广泛应用于黑白电视上,它被设计的目的主要用于视频信号的压缩、传输和存储,其中“Y”表示的是明亮度(Luminance or Luma),又称灰阶值,而“U”和“V”则表示的是色度(Chrominance or Chroma)
YUV也是一种颜色编码方法,它是指将亮度参量(Y:Luminance 或Luma)和色度参量(UV:Chrominance或Chroma)分开进行表示的像素编码格式。
这样分开的好处就是不但可以避免相互干扰,没有UV信息一样可以显示完整的图像, 因而解决了彩色电视与黑白电视的兼容问题;
还可以降低色度的采样率而不会对图像质量影响太大(因为多个Y可以共用一组UV分量),降低了视屏信号传输时对频宽(带宽)的要求。
YUV组合在一起的意义是用来描述影响的色彩和饱和度,用以指定像素的颜色。
YUV的格式有两类,分别是 平面 Planar 和 紧凑Packed
对于 Planar - 先连续存储所有像素点的Y,紧接着存储所有像素点的U。
对于 Packed - 每个像素点的Y,U,V连续存储在内存中。
Packed的优点相较于Planar主要是更节省内存空间。
而Planar的优势也显而易见:
- 可以并行访问像素数据。在内存带宽不足的时候,
Planar
就明显优于Packed
了。如YUV,如果采用Planar
,相比于Packed
,可以并行访问Y、U、V三个平面,那就相当于只花1/3的时间,就可以访问到一个YUV像素。 Planar
在切换bit depth
时,更加快:可以通过增加或丢弃平面,来快速扩增或缩减调色板。比如,4个平面变成5个平面时,一个像素的可选颜色,变成了种。
- 当代表像素的bit数,不是2的次幂的时候,
Planar
在空间和时间上的效率,都高于Packed
。比如,在3-bit的RGB中(每3个bit表示一个像素,一个像素可选颜色为种)。
- 如果采用
Planar
,只需要3个平面。 - 如果采用
Packed
,有两种实现方式:- 允许像素跨字节边界:提高了内存寻址和unpack像素的复杂度,导致耗时增加。
- 采用padding:每个字节只存储两个像素,耗费6个bit,保留两个2bit不使用,导致空间消耗增大。RGB555就是这种做法。
- 如果采用
Libyuv 是一款由Google主导的实现各种YUV与RGB间相互转换、旋转、缩放的库
YUV还存在其他多种格式,比如YUV420p,YUV420sp等。
不同YUV格式的数据在存储时的排列顺序是不一样的,选用错误的解析格式可能导致画面出现花屏,绿屏等现象
2.3 YUV采样表示法
YUV采用A:B:C表示法来描述Y,U,V采样频率比例,下图中黑点表示采样像素点Y分量, 空心圆表示采样像素点的UV分量。主要分为 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 这几种常用的类型。
常见格式参考:
2.4 RGB和YUV转换
通常情况下RGB和YUV直接的相互转换都是调用接口实现,比如Ffmpeg的swscale或者 libyuv等库。
主要转换标准是BT601和BT709。
8bit位深的情况下,TV range是16-235(Y)、16-240(UV) , 也叫Limited Range,PC range是0-255,也叫Full Range ,而RGB没有range之分,全是0-255。
BT601 TV Range转换公式:
YUV(256 级别) 可以从8位 RGB 直接计算:
Y = 0.299*R + 0.587*G + 0.114*B;
U = -0.169*R - 0.331*G + 0.5 *B ;
V = 0.5 *R - 0.419*G - 0.081*B;
反过来,RGB 也可以直接从YUV (256级别) 计算:
R = Y + 1.402 (Y-128)
G = Y - 0.34414 (U-128) - 0.71414 (U-128)
B = Y + 1.772 (V-128)
从YUV 转到RGB 如果值小于0要取0,如果大于255要取255。
靠谱推荐:Free Pos,微信JOCIHEZ