1.RGB格式
为了提高算法的效率,很多程序,譬如ffmpeg,会将数据补齐,譬如补齐为4字节或8字节对齐(原本用3个字节表示RGB,但为了提高算法效率,用4个字节来表示RGB)。这里有一个坑,在显示时,需要将这些ffmpeg自动补齐的直接去掉,否则显示会有问题(很多显示问题都是由这个造成)。
自动补齐的效果就是,第4个像素不是从第9个字节开始,因为第8个字节后面补了一个3个字节,也就是第4个像素是从第12个字节开始的。所以在复制像素数据时,一般是一行一行的复制,但一行一行的复制效率低一些。如果不想一行一行的复制,需要保证 像素个数是4的倍数或者是8的倍数,譬如1280或1920。
软解码比硬解码性能和兼容性都更强,我们通常说的软解码性能会差指的是在一些嵌入式设备中,譬如在一些嵌入式设备中只有一个dsp芯片,其主频才1G,即单核1G,所以它的解码性能很差;而我们现在的CPU一般都是8核2G的,所以软解码的兼容器和性能一般都是强于硬解码的。硬解码一般是固定死的,即每秒钟只能解码60帧数据,但因为硬解码是固化在CPU里面的程序,类似于用硬件实现了解码功能,所以它不用做指令转换,CPU开销就小,省电。
在某些应用,譬如需要每秒钟解码200帧数据,用硬解码肯定解不了(某些安霸的芯片可以做到,但大部分手机芯片都做不到),只能用软解码。在直播或播放器领域,硬解码绰绰有余;但硬解码解出来的YUV格式数据和软解码解出来的YUV格式数据可能不一样,这时需要进行转换。
8.YUV格式
实心圆表示Y,空心的大圆表示UV。
“Y”指亮度,也就是灰度值,“U”和“V”是成套/一起出现的,UV指色度。
(1)YUV444:如果8bit话,一个像素一个3个字节表示。
(2)YUV422:第一个Y用一个UV,第二个Y,用的也是第一个UV,即两个亮度共用一个色度。
(3)YUV420:一般解出来的都是这种格式的数据。四个Y共用一个UV,即四个亮度共用一个色度。这里的四个亮度不是连续的四个,而是上下四个,上下附近的点的色度变化不会太大,但亮度可能变化比较大。每个像素点用12bit来表示。
3.YUV420和YUV420P的区别?
音频和视频都有这种带P的格式,带P的表示是以平面的形式存放数据。
譬如YUV420P,它是先将所有Y存在一起,然后再将所有U存在一起,最后再把所有V存在一起,即Y U V不是交织在一起的。
在ffmpeg中,可能会有三个地址,也就是有三个数组,用来分别存放Y U V,这需要注意。如果是RGBP也是一样的道理。而YUV420,是将Y U V交织在一起进行存储的。
4.PCM参数
(1)采样率:sample_rate,指一秒钟中采样多少个样本数据,一般音频的采样率都是44100,即一秒钟采集44100个数据。这个值越大,听到的声音的质量就越好。
(2)通道:channels(左右声道);如果是双声道采样,那么每秒钟采样的数据量就变成了44100*2个采样点。
(3)样本格式/样本大小:sample_size,指一个采样点是多少个bit。这个值越大,声音质量也越好。
①AV_SAMPLE_FMT_S16:用两个字节来存储的。
②AV_SAMPLE_FMT_FLET:用一个浮点类型来存储,即32bit/4字节来存储一个采样点,用float来存储 有利于编码算法的优化,但这种相机很少。如果解码之后的声音是这种格式,普通的声卡是播不了的,所以还需要先进行重采样,然后转为AV_SAMPLE_FMT_S16格式,即由32bit转为16bit。
5.样本类型
S16P以平面的形式展开,就将左声道和右声道的数据分开来存储,所以也会有两个数组。做重采样的时候,如果是S16P的格式,需要给这两个数组,如果只给一个,重采样就会出错。非P形式就是一种交错格式的。