解码的本质就是将一个个原来被编码的数据变成一个个像素点对应的像素值(YUV或者RGB)。会造成两者差异性的地方通常在下面三个方面:
1. 变化和量化精度的不同:解码过程中,硬件和软件可能造成区别的地方是反量化和DCT变换或者小波变换或者其他变换,可能存在一些硬件为了设计上的简便对精度进行了一些调整,因此会造成最后像素值的差异。但是,这些差异在现在硬件解码上,肉眼是基本看不出来的。
2. 像素插值:常用的编码采用的是YUV420的色彩采样,对每个像素采样的时候,对亮度逐个采样,但是色差是4个像素采样一个,如下图4个像素:
A(采样Y,U,V) B(Only Y)
C(Only Y) D(Only Y)
BCD点的UV值采用的是与A相同的UV值(也有其他的,比如取ABCD 4点UV的均值)。
但是,在解码后播放的时候,硬件和软件对于ABCD的UV值可能会采取不同的策略(这种差异同样也会出现在两个不同的解码方案上),以保证每个显示的像素都有各自的UV值,这个策略可能是直接使用A点UV值,或者与相邻的4个像素进行滤波处理,达到像素间平滑,例如双线性的插值。在早期的硬件解码时,显卡中没有专门的用于解码的模块,因此在这些处理上往往会用更加快速而不是精度的方法去实现,因此会造成画质上的差异。
3. 显示输出:在解码结束的时候,需要将结果在屏幕上输出,硬件解码结果往往可以直接用于显示,但是软件解码的结果需要从内存传递到显存后进行输出。这当中需要进行一次转换,假设显示的时候使用的api要求使用RGB的输出,但是解码的结果是YUV的,那么需要进行一次转换,这是一个线性的转换,但是由于像素的精度只有8bit,因此会有一些差值(1/255之内),当然,这个肉眼几乎看不出来的。
综上,造成软解和硬解画质上区别的原因主要是在解码和显示过程中一些计算精度上的区别,造成了两者的区别。通常来说,软解在这些计算精度上会比硬解更高。
如果使用更高的码率(更小的量化单位),更高的bit色的时候,这些差异会减小,但是会增加加酸量。
同时,随着硬件的不断发展,现在的显卡或者soc都会有独立的解码模块,计算的精度也越来越高了,这种差异正在逐步减小。 |