x264 分像素的运动估计总结
来源:互联网 发布:网络唱歌比赛 编辑:程序博客网 时间:2024/04/30 11:05
(1) static uint8_t *get_ref( uint8_t *src[4], int i_src_stride,
uint8_t *dst, int * i_dst_stride,
int mvx,int mvy,
int i_width, int i_height )
{
int qpel_idx = ((mvy&3)<<2) + (mvx&3); //取出运动矢量的分像素部分。
int offset = (mvy>>2)*i_src_stride + (mvx>>2); //偏移到所选的整像素点
uint8_t *src1 = src[hpel_ref0[qpel_idx]] + offset + ((mvy&3) == 3) * i_src_stride;
/*src1和src2都分别指向的是1/2像素块,关键是这个hpel_ref0[qpel_idx]和hpel_ref1[qpel_idx],下面将详细介绍。
注意一点就是参考帧定义了uint8_t *p_fref[2][32][4+2]; /* last: lN, lH, lV, lHV, cU, cV */
这里面的 4+2 的这个2代表色度,而这个4分别代表整像素,在整像素水平右边的1/2像素,在整像素垂直下面的1/2像素和整像素右下角的1/2像素。1/2像素的值已经在前面函数里面插值存好了,只要调用就可以了,而如果要进行1/4像素估计,要临时插值。现在这个函数 get_ref 中,src[0]、src[1]、src[2]、src[3]这传进来的就是分别是 lN, lH, lV, lHV
*/
if( qpel_idx & 5 ) /* qpel interpolation needed */
{
uint8_t *src2 = src[hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);
pixel_avg( dst, *i_dst_stride, src1, i_src_stride,
src2, i_src_stride, i_width, i_height );//1/4搜索时需要临时插值函数
return dst;
}
else
{
*i_dst_stride = i_src_stride;
return src1;
}
}
按照 毕厚杰 的《新一代视频压缩编码标准——H.264/AVC》关于运动矢量那一节的介绍。看图6.22
那四个像素点,G为整像素点 b、h、i分别是lH, lV, lHV,也就是水平,垂直和对角线的值。
G b
h i
对应为
src[0] src[1]
src[2] src[3]
现在看这两个数组
static const int hpel_ref0[16] = {0,1,1,1,0,1,1,1,2,3,3,3,0,1,1,1};
static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};
也按像素的平面图画出来的话
src[hpel_ref0[qpel_idx]]为
0 1 1 1
0 1 1 1
2 3 3 3
0 1 1 1
src[hpel_ref1[qpel_idx]]为
0 0 0 0
2 2 3 2
2 2 3 2
2 2 3 2
这上面的数字 0、1、2、3分别代表 整像素、水平1/2像素值、垂直1/2像素值 和对角线1/2像素值,也就是毕厚杰书中的 G、b、h、I 。这里要注意src[hpel_ref0[qpel_idx]]最后一行的 0 1 1 1 和src[hpel_ref1[qpel_idx]]最右边一列0 2 2 2不是当前的整像素0的1/2像素,而分别是其下面和右边一个整像素的对应的1/2像素值,因为 ((mvy&3) == 3) * i_src_stride 和((mvx&3) == 3)。
为什么要这么来排,是因为要根据1/4像素是通过1/2像素线性插值的公式来的,具体看下面这个函数。
(2) static inline void pixel_avg( uint8_t *dst, int i_dst_stride,
uint8_t *src1, int i_src1_stride,
uint8_t *src2, int i_src2_stride,
int i_width, int i_height )
{ //1/4搜索时需要临时插值函数
int x, y;
for( y = 0; y < i_height; y++ )
{
for( x = 0; x < i_width; x++ )
{
dst[x] = ( src1[x] + src2[x] + 1 ) >> 1; //利用相邻半像素和两个像素取平均插值
}
dst += i_dst_stride;
src1 += i_src1_stride;
src2 += i_src2_stride;
}
} 不过最后我有个疑问,那就是1/4插值后,应该原来的1/2 值保持不变的.但是分析发现,这个 b 、h、 i 这三个1/2像素中,h和i是不变的,不过 b会发生变化. 个人觉得 static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};如果改为 static const int hpel_ref1[16] = {0,0,1,0,2,2,3,2,2,2,3,2,2,2,3,2};则 b也不会发生变化. 所以这里打个问号?
- x264 分像素的运动估计总结
- x264 分像素的运动估计总结
- x264 分像素的运动估计总结
- x264运动估计的1/2像素和1/4像素搜索
- x264运动估计的1/2像素和1/4像素搜索
- AVS 分像素运动估计优化算法
- x264运动估计
- x264运动估计
- x264运动估计
- x264运动估计
- x264运动估计实验
- x264运动估计宏块cost值的计算
- x264运动估计宏块cost值的计算
- x264运动估计宏块cost值的计算
- 1/4像素运动估计
- 1/4像素运动估计
- x264运动估计六边形搜索算法分析
- x264运动估计菱形搜索源代码解析
- 类型转换工具
- 物联网帮城市应急指挥"打通六脉"
- PowerShell base operate about list
- 文件输入和输出简单示例
- 通向架构师的道路(第五天)之tomcat集群-群猫乱舞
- x264 分像素的运动估计总结
- linux的PS命令解析
- JN系列(3):如何得到JavaVM,JNIEnv接口
- 输入二十个整数来求值
- 通向架构师的道路(第六天)之漫谈基于数据库的权限系统的设计
- 1000以内所有偶数的和(解法一)
- 随机过程考试经验
- 条款8中placement new练习
- WNetAddConnection2 映射网络驱动器