timgfilterpostproc.cpp
来自「从FFMPEG转换而来的H264解码程序,VC下编译..」· C++ 代码 · 共 1,961 行 · 第 1/5 页
CPP
1,961 行
label2:
csimd::movq (REG_d, mm3);
csimd::movq (mm3, mm4);
csimd::pxor (mm7, mm7);
csimd::punpcklbw (mm7, mm3);
csimd::punpckhbw (mm7, mm4);
REG_c=width;
csimd::psraw (mm5, mm3);
csimd::psraw (mm5, mm4);
label1:
csimd::movq (REG_S, mm0);
csimd::movq (8+REG_S, mm1);
csimd::paddw (mm3, mm0);
csimd::paddw (REG_S+REG_a, mm0);
csimd::paddw (mm4, mm1);
csimd::movq (8+REG_S+REG_a, mm6);
csimd::movq (mm7, REG_S+REG_a);
csimd::psraw (mm2, mm0);
csimd::paddw (mm6, mm1);
csimd::movq (mm7, 8+REG_S+REG_a);
csimd::psraw (mm2, mm1);
csimd::packuswb (mm1, mm0);
csimd::movq (mm0, REG_D);
REG_S+=16;
REG_D+=8;
REG_c-=8;
if (REG_c>0) //jg 1b
goto label1;
REG_S+=src_stride;
REG_d+=8;
REG_D+=dst_stride;
if (end>REG_d)
goto label2;//jl 2b
}
void TimgFilterPostprocFspp::mul_thrmat_s(int q)
{
const uint64_t *adr=&threshold_mtx_noq[0];
uint8_t *REG_D=(uint8_t*)adr;
uint8_t *REG_S=(uint8_t*)adr;
__m64 mm0,mm7,mm1,mm2,mm3,mm4,mm5,mm6;
csimd::movd (q, mm7);
REG_D+= 8*8*2;
csimd::movq (0*8+REG_S, mm0);
csimd::punpcklwd( mm7, mm7);
csimd::movq (1*8+REG_S, mm1);
csimd::punpckldq( mm7, mm7);
csimd::pmullw (mm7, mm0);
csimd::movq (2*8+REG_S, mm2);
csimd::pmullw( mm7, mm1);
csimd::movq (3*8+REG_S, mm3);
csimd::pmullw (mm7, mm2);
csimd::movq (mm0, 0*8+REG_D);
csimd::movq (4*8+REG_S, mm4);
csimd::pmullw (mm7, mm3);
csimd::movq (mm1, 1*8+REG_D);
csimd::movq (5*8+REG_S, mm5);
csimd::pmullw( mm7, mm4);
csimd::movq (mm2, 2*8+REG_D);
csimd::movq (6*8+REG_S, mm6);
csimd::pmullw( mm7, mm5);
csimd::movq (mm3, 3*8+REG_D);
csimd::movq (7*8+0*8+REG_S, mm0);
csimd::pmullw(mm7, mm6 );
csimd::movq (mm4, 4*8+REG_D);
csimd::movq (7*8+1*8+REG_S, mm1);
csimd::pmullw( mm7, mm0);
csimd::movq (mm5, 5*8+REG_D);
csimd::movq (7*8+2*8+REG_S, mm2);
csimd::pmullw( mm7, mm1);
csimd::movq (mm6, 6*8+REG_D);
csimd::movq (7*8+3*8+REG_S, mm3);
csimd::pmullw( mm7, mm2);
csimd::movq (mm0, 7*8+0*8+REG_D);
csimd::movq (7*8+4*8+REG_S, mm4);
csimd::pmullw( mm7, mm3);
csimd::movq (mm1, 7*8+1*8+REG_D);
csimd::movq (7*8+5*8+REG_S, mm5);
csimd::pmullw( mm7, mm4);
csimd::movq (mm2, 7*8+2*8+REG_D);
csimd::movq (7*8+6*8+REG_S, mm6 );
csimd::pmullw( mm7, mm5);
csimd::movq (mm3, 7*8+3*8+REG_D);
csimd::movq (14*8+0*8+REG_S, mm0);
csimd::pmullw( mm7, mm6);
csimd::movq (mm4, 7*8+4*8+REG_D);
csimd::movq (14*8+1*8+REG_S, mm1);
csimd::pmullw (mm7, mm0);
csimd::movq (mm5, 7*8+5*8+REG_D);
csimd::pmullw (mm7, mm1);
csimd::movq (mm6, 7*8+6*8+REG_D);
csimd::movq (mm0, 14*8+0*8+REG_D);
csimd::movq (mm1, 14*8+1*8+REG_D);
}
#define FIX(x,s) ((int) ((x) * (1<<s) + 0.5)&0xffff)
#define C64(x) ((uint64_t)((x)|(x)<<16))<<32 | (uint64_t)(x) | (uint64_t)(x)<<16
#define FIX64(x,s) C64(FIX(x,s))
const __int64 TimgFilterPostprocFspp::MM_FIX_0_382683433=FIX64(0.382683433, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_0_541196100=FIX64(0.541196100, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_0_707106781=FIX64(0.707106781, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_1_306562965=FIX64(1.306562965, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_1_414213562_A=FIX64(1.414213562, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_1_847759065=FIX64(1.847759065, 13);
const __int64 TimgFilterPostprocFspp::MM_FIX_2_613125930=FIX64(-2.613125930, 13); //-
const __int64 TimgFilterPostprocFspp::MM_FIX_1_414213562=FIX64(1.414213562, 13);
const __int64 TimgFilterPostprocFspp::MM_FIX_1_082392200=FIX64(1.082392200, 13);
const __int64 TimgFilterPostprocFspp::MM_FIX_0_847759065=FIX64(0.847759065, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_0_566454497=FIX64(0.566454497, 14);
const __int64 TimgFilterPostprocFspp::MM_FIX_0_198912367=FIX64(0.198912367, 14);
const __int64 TimgFilterPostprocFspp::MM_DESCALE_RND={C64(4)};
const __int64 TimgFilterPostprocFspp::MM_2={C64(2)};
#undef FIX
#undef C64
#undef FIX64
void TimgFilterPostprocFspp::column_fidct_s(int16_t* thr_adr_, DCTELEM *data_, DCTELEM *output_, int cnt)
{
__m64 mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7;
uint8_t *REG_S=(uint8_t*)data_;
uint8_t *REG_D=(uint8_t*)output_;
int REG_c=cnt;
uint8_t *REG_d=(uint8_t*)thr_adr_;
__m64 temps[4];
int REG_a;
label1:
csimd::movq( DCTSIZE_S*0*2+REG_S, mm1 );
//
csimd::movq( DCTSIZE_S*3*2+REG_S, mm7 );
csimd::movq( mm1, mm0 );
csimd::paddw( DCTSIZE_S*7*2+REG_S, mm1); //t0
csimd::movq( mm7, mm3 );
csimd::paddw( DCTSIZE_S*4*2+REG_S, mm7); //t3
csimd::movq( mm1, mm5 );
csimd::movq( DCTSIZE_S*1*2+REG_S, mm6 );
csimd::psubw (mm7, mm1 ); //t13
csimd::movq( DCTSIZE_S*2*2+REG_S, mm2 );
csimd::movq( mm6, mm4 );
csimd::paddw( DCTSIZE_S*6*2+REG_S, mm6 ); //t1
csimd::paddw( mm7, mm5 ); //t10
csimd::paddw( DCTSIZE_S*5*2+REG_S, mm2); //t2
csimd::movq( mm6, mm7 );
csimd::paddw (mm2, mm6); //t11
csimd::psubw( mm2, mm7); //t12
csimd::movq( mm5, mm2 );
csimd::paddw( mm6, mm5); //d0
// i0 t13 t12 i3 i1 d0 - d4
csimd::psubw( mm6, mm2); //d4
csimd::paddw( mm1, mm7);
csimd::movq( 4*16+REG_d, mm6);
csimd::psllw (2, mm7 );
csimd::psubw (0*16+REG_d, mm5 );
csimd::psubw (mm6, mm2 );
csimd::paddusw (0*16+REG_d, mm5 );
csimd::paddusw (mm6, mm2 );
csimd::pmulhw (MM_FIX_0_707106781, mm7 );
//
csimd::paddw (0*16+REG_d, mm5);
csimd::paddw (mm6, mm2 );
csimd::psubusw( 0*16+REG_d, mm5 );
csimd::psubusw( mm6, mm2 );
//This func is totally compute-bound, operates at huge speed. So, DC shortcut
// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3).
//However, typical numbers: nondc - 29, dc - 46, zero - 25. All <> 0 case is very rare.
csimd::paddw (MM_2, mm5 );
csimd::movq( mm2, mm6 );
csimd::paddw( mm5, mm2);
csimd::psubw( mm6, mm5 );
csimd::movq( mm1, mm6);
csimd::paddw (mm7, mm1 ); //d2
csimd::psubw (2*16+REG_d, mm1);
csimd::psubw (mm7, mm6 ); //d6
csimd::movq( 6*16+REG_d, mm7 );
csimd::psraw (2, mm5 );
csimd::paddusw(2*16+REG_d, mm1);
csimd::psubw(mm7, mm6 );
// t7 d2 /t11 t4 t6 - d6 /t10
csimd::paddw(2*16+REG_d, mm1 );
csimd::paddusw(mm7, mm6 );
csimd::psubusw(2*16+REG_d, mm1 );
csimd::paddw(mm7, mm6 );
csimd::psubw(DCTSIZE_S*4*2+REG_S, mm3 );
csimd::psubusw(mm7, mm6 );
//csimd::movq( [edi+DCTSIZE_S*2*2], mm1
//csimd::movq( [edi+DCTSIZE_S*6*2], mm6
csimd::movq( mm1, mm7 );
csimd::psraw (2, mm2 );
csimd::psubw(DCTSIZE_S*6*2+REG_S, mm4 );
csimd::psubw(mm6, mm1 );
csimd::psubw(DCTSIZE_S*7*2+REG_S, mm0 );
csimd::paddw(mm7, mm6 ); //'t13
csimd::psraw (2, mm6 ); //csimd::paddw(mm6, MM_2 !! ---
csimd::movq( mm2, mm7 );
csimd::pmulhw (MM_FIX_1_414213562_A, mm1 );
csimd::paddw(mm6, mm2 ); //'t0
csimd::movq( mm2, temps[0] ); //!
csimd::psubw(mm6, mm7 ); //'t3
csimd::movq( DCTSIZE_S*2*2+REG_S, mm2 );
csimd::psubw(mm6, mm1 ); //'t12
csimd::psubw(DCTSIZE_S*5*2+REG_S, mm2); //t5
csimd::movq( mm5, mm6 );
csimd::movq( mm7, temps[3] );
csimd::paddw(mm2, mm3 ); //t10
csimd::paddw(mm4, mm2 ); //t11
csimd::paddw(mm0, mm4 );//t12
csimd::movq( mm3, mm7 );
csimd::psubw(mm4, mm3 );
csimd::psllw(2, mm3 );
csimd::psllw(2, mm7 ); //opt for P6
csimd::pmulhw (MM_FIX_0_382683433, mm3 );
csimd::psllw(2, mm4 );
csimd::pmulhw (MM_FIX_0_541196100, mm7 );
csimd::psllw(2, mm2 );
csimd::pmulhw (MM_FIX_1_306562965, mm4 );
csimd::paddw(mm1, mm5 ); //'t1
csimd::pmulhw (MM_FIX_0_707106781, mm2 );
csimd::psubw(mm1, mm6 ); //'t2
// t7 't12 't11 t4 t6 - 't13 't10 ---
csimd::paddw(mm3, mm7 ); //z2
csimd::movq( mm5, temps[1]);
csimd::paddw(mm3, mm4 ); //z4
csimd::movq( 3*16+REG_d, mm3 );
csimd::movq( mm0, mm1 );
csimd::movq( mm6, temps[2] );
csimd::psubw(mm2, mm1 ); //z13
//===
csimd::paddw(mm2, mm0 ); //z11
csimd::movq( mm1, mm5 );
csimd::movq( 5*16+REG_d, mm2 );
csimd::psubw(mm7, mm1 );//d3
csimd::paddw(mm7, mm5 );//d5
csimd::psubw(mm3, mm1 );
csimd::movq( 1*16+REG_d, mm7 );
csimd::psubw(mm2, mm5 );
csimd::movq( mm0, mm6 );
csimd::paddw(mm4, mm0 );//d1
csimd::paddusw(mm3, mm1 );
csimd::psubw(mm4, mm6 ); //d7
// d1 d3 - - - d5 d7 -
csimd::movq( 7*16+REG_d, mm4 );
csimd::psubw(mm7, mm0 );
csimd::psubw(mm4, mm6 );
csimd::paddusw(mm2, mm5 );
csimd::paddusw(mm4, mm6 );
csimd::paddw(mm3, mm1 );
csimd::paddw(mm2, mm5 );
csimd::paddw(mm4, mm6 );
csimd::psubusw(mm3, mm1 );
csimd::psubusw(mm2, mm5 );
csimd::psubusw(mm4, mm6);
csimd::movq( mm1, mm4 );
csimd::por( mm5, mm4 );
csimd::paddusw(mm7, mm0 );
csimd::por( mm6, mm4 );
csimd::paddw(mm7, mm0 );
csimd::packssdw(mm4, mm4);
csimd::psubusw(mm7, mm0 );
csimd::movd (mm4, REG_a );
if (REG_a) //or REG_a, REG_a
goto label2; //jnz 2f
//csimd::movq( [edi+DCTSIZE_S*3*2], mm1
//csimd::movq( [edi+DCTSIZE_S*5*2], mm5
//csimd::movq( [edi+DCTSIZE_S*1*2], mm0
//csimd::movq( [edi+DCTSIZE_S*7*2], mm6
// t4 t5 - - - t6 t7 -
//--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0
//Typical numbers: nondc - 19, dc - 26, zero - 55. zero case alone isn't worthwhile
csimd::movq( temps[0], mm4);
csimd::movq( mm0, mm1 );
csimd::pmulhw (MM_FIX_0_847759065, mm0); //tmp6
csimd::movq( mm1, mm2 );
csimd::movq( DCTSIZE_S*0*2+REG_D, mm5);
csimd::movq( mm2, mm3 );
csimd::pmulhw (MM_FIX_0_566454497, mm1 ); //tmp5
csimd::paddw(mm4, mm5 );
csimd::movq( temps[1], mm6 );
//csimd::paddw(mm3, MM_2
csimd::psraw( 2, mm3 ); //tmp7
csimd::pmulhw (MM_FIX_0_198912367, mm2 ); //-tmp4
csimd::psubw(mm3, mm4 );
csimd::movq( DCTSIZE_S*1*2+REG_D, mm7);
csimd::paddw(mm3, mm5 );
csimd::movq( mm4, DCTSIZE_S*7*2+REG_D );
csimd::paddw(mm6, mm7 );
csimd::movq( temps[2], mm3 );
csimd::psubw(mm0, mm6 );
csimd::movq( DCTSIZE_S*2*2+REG_D, mm4 );
csimd::paddw(mm0, mm7 );
csimd::movq( mm5, DCTSIZE_S*0*2+REG_D );
csimd::paddw(mm3, mm4 );
csimd::movq( mm6, DCTSIZE_S*6*2+REG_D );
csimd::psubw(mm1, mm3 );
csimd::movq( DCTSIZE_S*5*2+REG_D, mm5 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?