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 + -
显示快捷键?