H.264提出了半象素预测的概念,这主要是针对整象素插值的不精确性进行的改善。比如对某个4x4块进行运动估计,在其参考帧中,整数象素的4x4块并不能更好的将参差减小(达不到预期的效果)。众所周知,图象的存储与表达都是基于整象素的,如果想进行半象素的预测等操作,首先要进行的就是半象素插值。也就是人为的将半象素补齐,这样就可以比较在整象素中间的象素值。
很明显,这个值是介于其邻近的两个(或几个整数象素)值,那么究竟如何算得呢?H.264为我们提供了很好的方法,当然,我不知道他们是怎么搞出来的。但最起码,他们的测试效果是很好的,别人也很乐于使用他们提供的方法来计算。我们以水平为例,在H.264中说明有:
b=round(e-5f+20g+20H-5i+j)/32,其中他们在图中的关系是:e
motion compensation performance.(这六个周围插值滤波相对比较复杂,但是它产生了一个精确的整数采样,这就是使得在运动补偿中获得了很好的性能)。
而在T264中的相关代码为(注释为相对标准的说明):
void
interpolate_halfpel_h_c(uint8_t* src, int32_t src_stride, uint8_t* dst, int32_t dst_stride, int32_t width, int32_t height)
{
}
static __inline int32_t
tapfilter_h(uint8_t* p)
{
}
#define CLIP1(x) (x & ~255) ? (-x >> 31) : x
这样对照标准,在对照源码,就很好理解了半象素插值。上个学期看了很长时间的x264始终没抓住重点,近几天调试线性汇编,才发现这个法门。我想学习H.264就是要标准对照源码才能事半功倍。
其后的四分之一象素,以及垂直方向的插值,也是类似的,就是复杂性稍微多一点。在此就不再详述了。