函数名:sad
int sad(const pixel* pix1, intptr_t stride_pix1, const pixel* pix2, intptr_t stride_pix2,int lx, int ly)
位深为8位的SAD函数
int sad_int16_t(const int16_t* pix1, intptr_t stride_pix1, const int16_t* pix2, intptr_t stride_pix2,int lx, int ly)
位深为10、12位的SAD函数
函数名:sad_x3
函数功能:同时计算3个MV对应的3个SAD值
通过3个预测的MV找到对应块,使用当前块-对应块获得SAD值,最后选择最小的SAD值对应的MV作为当前块的MV。
http://blog.csdn.net/cabbage2008/article/details/50612487
函数名:sad_x4
sad_x4:同时计算4个MV对应的4个SAD值
为什么要同时进行3组MV或者4组MV的同时计算,应该是为了并行加速或者用于并行能力比较强的处理器,比如DSP、FPGA硬件电路、GPU等
函数名:satd_4x4 两个参数
static int satd_4x4(const int16_t* pix1, intptr_t stride_pix1)
计算一个4x4块的SATD值,用于帧间亚象素搜索。
函数名:satd_8x4
static int satd_8x4(const pixel* pix1, intptr_t stride_pix1, const pixel* pix2, intptr_t stride_pix2)
计算8x4块(PU)的SATD值/2(跟拆分成4x4计算相同)
函数名:satd8(四个参数)
int satd8(const pixel* pix1, intptr_t stride_pix1, const pixel* pix2, intptr_t stride_pix2)
将当前块划分为若干个8x4的块(PU),分别计算8x4块的SATD值,并将所有8x4块的SATD值累加。该函数是调用satd_8x4实现的。这个函数能否使用循环展开?
函数名:_sa8d_8x8和sa8d_8x8都是两个参数
_sa8d_8x8直接计算一个8x8块的SATD值 ;sa8d_8x8计算一个8x8块的SATD值,调用_sa8d_8x8函数的返回值加2后再右移2位。sa8d_8x8函数在psyCost_pp中调用,暂时不优化。
SAD和SATD的区别
Q:如果不用率失真最优化,为什么选择SATD+delta×r(mv,mode)作为模式选择的依据?为什么运动估计中,整象素搜索用SAD,而亚象素搜索用SATD?为什么帧内模式选择要用SATD?
SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。整象素搜索即粗匹配,可用来缩小搜索范围。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。亚象素搜索即精匹配,可使用SATD。一般帧内要对所有的模式进行检测,帧内预测选用SATD的原因同上。
在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素搜索中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。
x264的哈达玛变换(hadamard)的实现和优化
运动估计模块中,需要在众多候选的匹配位置中挑选出“最优”的一个参考块,利用其与当前块的残差进行后续编码操作。因此,为了评选出最优编码结构和预测模式,可以采用绝对误差和(Sum of Absolute Difference, SAD)、基于绝对误差变换和(Sum of Absolute Transform Distortion, SATD)、基于误差平方和(Sum of Square Error, SSE)的具有较低复杂度的模型函数以及率失真代价函数,作为选取的衡量标准。
SAD代价函数
绝对误差和,即SAD,其计算公式如式(2-2)所示:
式中的N为编码图像块尺寸,Org_value(x, y)表示编码图像块中(x, y)位置的原始图像像素值,Pred_value(x, y)表示预测块中(x, y)位置的像素值。
可见,SAD指当前编码块与预测块像素之差的绝对值之和。
SATD代价函数
绝对误差变换和,即SATD,其计算结果按照公式(2-3)求得:
#include "app_entry.h"
#include
#include
#include
#include
#pragma DATA_SECTION(src0,".data1")
unsigned char src0[]={
#include "data_in\\data_1_8.in"
};
#pragma DATA_SECTION(src1,".data2")
unsigned char src1[]={
#include "data_in\\data_2_8.in"
};
#pragma DATA_SECTION(src2,".data3")
unsigned char src2[]={
#include "data_in\\carphone00.in"
};
int __satd88( int* piOrg, int* piCur, int iStrideOrg, int iStrideCur);
//app entry point
void app_entry(){
time_t op,ed;
int i,satd;
//time(&op);
//for(i=0;i<10000;i++)
{satd=satd88(src0,src1,8,8);}
//time(&ed);
printf("satd = %d\n",satd);
//printf("%d\n",sum);
i=9;
}
/********************************************************************************
** **
** **
** ALL RIGHTS RESERVED **
** **
*********************************************************************************
File name: _xCalcHADs8x8.asm
Author: zengfeiyang
Create Date: 2015-4-8 pm
********************************************************************************/
/*____________________________________________________________________________
Func name : __xCalcHADs8x8
C-Syntax : __xCalcHADs8x8( Pel *piOrg,
Pel *piCur,
Int iStrideOrg,
Int iStrideCur,
Int iStep )
----------------------------------------------------------------------------
Purpose :
Inputs : U0 contains the point which point to piOrg
U1 contains the point which point to piCur
xr2 contains the number of iStrideOrg
xr3 contains the number of iStrideCur
xr4 contains the number of iStep
Outputs : none
Data Memory :yr0~63 diff[64] yr0~63 m1[16] ybr0~63 m2[64]
Prog Memory :
Stack Memory:
Cycles :
____________________________________________________________________________*/
.global __satd88
//.global _input_data_1
//.global _input_data_2
.text
__satd88:
//u0 = _input_data_1
//u1 = _input_data_2
xr0=u1
v0=xr0||u1=u0+8
u2=u0+16||v1=v0+8
v2=v0+16
__start:
r1:0 = [u0 += 24,1]||r11:10 = [v0 += 24,1]
r3:2 = [u1 += 24,1]||r13:12 = [v1 += 24,1]
r5:4 = [u2 += 24,1]||r15:14 = [v2 += 24,1]
cr21:20=cr11:10-cr1:0||r1:0 = [u0 += 24,1]||r11:10 = [v0 += 24,1]
cr23:22=cr13:12-cr3:2||r3:2 = [u1 += 24,1]||r13:12 = [v1 += 24,1]
cr25:24=cr15:14-cr5:4||r5:4 = [u2 += 24,1]||r15:14 = [v2 += 24,1]
xr21=zr20||zr20=xr21||yr21=tr20||tr20=yr21||cr27:26=cr11:10-cr1:0||r1:0 = [u0 += 24,1]||r11:10 = [v0 += 24,1]
xr23=zr22||zr22=xr23||yr23=tr22||tr22=yr23||cr29:28=cr13:12-cr3:2||r3:2 = [u1 += 24,1]||r13:12 = [v1 += 24,1]
xr25=zr24||zr24=xr25||yr25=tr24||tr24=yr25||cr31:30=cr15:14-cr5:4
r0=r20+r21||r1=r20-r21||xr27=zr26||zr26=xr27||yr27=tr26||tr26=yr27||cr33:32=cr11:10-cr1:0
r2=r22+r23||r3=r22-r23||xr29=zr28||zr28=xr29||yr29=tr28||tr28=yr29||cr35:34=cr13:12-cr3:2
r4=r24+r25||r5=r24-r25||xr31=zr30||zr30=xr31||yr31=tr30||tr30=yr31
r6=r26+r27||r7=r26-r27||xr33=zr32||zr32=xr33||yr33=tr32||tr32=yr33
r8=r28+r29||r9=r28-r29||xr35=zr34||zr34=xr35||yr35=tr34||tr34=yr35
yr0=xr1||xr1=yr0||tr0=zr1||zr1=tr0||r10=r30+r31||r11=r30-r31
yr2=xr3||xr3=yr2||tr2=zr3||zr3=tr2||r12=r32+r33||r13=r32-r33
yr4=xr5||xr5=yr4||tr4=zr5||zr5=tr4||r14=r34+r35||r15=r34-r35
r20=r0+r1||r21=r0-r1||yr6=xr7||xr7=yr6||tr6=zr7||zr7=tr6
r22=r2+r3||r23=r2-r3||yr8=xr9||xr9=yr8||tr8=zr9||zr9=tr8
r24=r4+r5||r25=r4-r5||yr10=xr11||xr11=yr10||tr10=zr11||zr11=tr10
r26=r6+r7||r27=r6-r7||yr12=xr13||xr13=yr12||tr12=zr13||zr13=tr12
r28=r8+r9||r29=r8-r9||yr14=xr15||xr15=yr14||tr14=zr15||zr15=tr14
xr21=zr20||zr20=xr21||yr21=tr20||tr20=yr21||r30=r10+r11||r31=r10-r11
xr23=zr22||zr22=xr23||yr23=tr22||tr22=yr23||r32=r12+r13||r33=r12-r13
xr25=zr24||zr24=xr25||yr25=tr24||tr24=yr25||r34=r14+r15||r35=r14-r15
r40=r20+r21||r41=r20-r21||xr27=zr26||zr26=xr27||yr27=tr26||tr26=yr27
r42=r22+r23||r43=r22-r23||xr29=zr28||zr28=xr29||yr29=tr28||tr28=yr29
r44=r24+r25||r45=r24-r25||xr31=zr30||zr30=xr31||yr31=tr30||tr30=yr31
r46=r26+r27||r47=r26-r27||xr33=zr32||zr32=xr33||yr33=tr32||tr32=yr33
r48=r28+r29||r49=r28-r29||xr35=zr34||zr34=xr35||yr35=tr34||tr34=yr35
r50=r30+r31||r51=r30-r31
r52=r32+r33||r53=r32-r33
r40=r40+r48||r41=r40-r48||r42=r41+r49||r43=r41-r49||r54=r34+r35||r55=r34-r35
r44=r42+r50||r45=r42-r50||r46=r43+r51||r47=r43-r51
r48=r44+r52||r49=r44-r52||r50=r45+r53||r51=r45-r53
r52=r46+r54||r53=r46-r54||r54=r47+r55||r55=r47-r55
r0=r40+r48||r1=r42+r50||r2=r40-r48||r3=r42-r50
r4=r44+r52||r5=r46+r54||r6=r44-r52||r7=r46-r54
r8=r41+r49||r9=r43+r51||r10=r41-r49||r11=r43-r51
r12=r45+r53||r13=r47+r55||r14=r45-r53||r15=r47-r55
r20=r0+r4||r21=r1+r5||r22=r0-r4||r23=r1-r5
r24=r2+r6||r25=r3+r7||r26=r2-r6||r27=r3-r7
r28=r8+r12||r29=r9+r13||r30=r8-r12||r31=r9-r13
r40=abs(r20)+abs(r21)||r41=abs(r22)+abs(r23)||r32=r10+r14||r33=r11+r15||r34=r10-r14||r35=r11-r15
r42=abs(r24)+abs(r25)||r43=abs(r26)+abs(r27)
r44=abs(r28)+abs(r29)||r45=abs(r30)+abs(r31)
r48=r40+r41||r46=abs(r32)+abs(r33)||r47=abs(r34)+abs(r35)
r49=r42+r43
r50=r44+r45
r51=r46+r47
r52=r48+r49||r53=r50+r51
r54=r52+r53
xr55=sigmaxyztr54
xr8=r55 lshift -2
__end:
.code_align 16
ret
/*
.section data0,"aw",@progbits
_input_data_1:
.include "C:\\workspace1\\satd88\\data_in\\data_1.in"
.section data1,"aw",@progbits
_input_data_2:
.include "C:\\workspace1\\satd88\\data_in\\data_2.in"
.data
_output:
.end
*/