postprocessing_mmx.c
来自「VLC媒体播放程序」· C语言 代码 · 共 890 行 · 第 1/3 页
C
890 行
MMXEXT_GET_LMINMAX( (%%eax, %3), %%mm0, %%mm1, %%mm7 ) MMXEXT_GET_LMINMAX( (%%eax, %3,2), %%mm0, %%mm1, %%mm7 ) MMXEXT_GET_LMINMAX( (%2, %3, 4), %%mm0, %%mm1, %%mm7 ) "leal (%%eax,%3,4), %%eax \n" MMXEXT_GET_LMINMAX( (%%eax), %%mm0, %%mm1, %%mm7 ) MMXEXT_GET_LMINMAX( (%%eax, %3), %%mm0, %%mm1, %%mm7 ) MMXEXT_GET_LMINMAX( (%%eax, %3,2), %%mm0, %%mm1, %%mm7 ) MMXEXT_GET_PMIN( %%mm0, %%mm7 ) MMXEXT_GET_PMAX( %%mm1, %%mm7 ) "movd %%mm0, %%eax \n" "andl $255, %%eax \n" "movl %%eax, (%0) \n" "movd %%mm1, %%eax \n" "andl $255, %%eax \n" "movl %%eax, (%1) \n" : : "r"(pi_min), "r"(pi_max), "r"(p_block), "r"(i_stride) : "%eax", "memory" );#endif i_min = 255; i_max = 0; for( y = 0; y < 8; y++ ) { for( x = 0; x < 8; x++ ) { if( i_min > p_block[x] ) i_min = p_block[x]; if( i_max < p_block[x] ) i_max = p_block[x]; } p_block += i_stride; } *pi_min = i_min; *pi_max = i_max;}static inline void pp_dering_BinIndex( uint8_t *p_block, int i_stride, int i_thr, uint32_t *p_bin ){ int x, y; uint32_t i_bin; for( y = 0; y < 10; y++ ) { i_bin = 0; for( x = 0; x < 10; x++ ) { if( p_block[x] > i_thr ) { i_bin |= 1 << x; } } i_bin |= (~i_bin) << 16; /* for detect also three 0 */ *p_bin = i_bin&( i_bin >> 1 )&( i_bin << 1 ); p_block += i_stride; p_bin++; }}static inline void pp_dering_Filter( uint8_t *p_block, int i_stride, uint32_t *p_bin, int i_QP ){ int x, y; uint32_t i_bin; int i_flt[8][8]; int i_f; uint8_t *p_sav; int i_QP_2; p_sav = p_block; i_QP_2 = i_QP >> 1; for( y = 0; y < 8; y++ ) { i_bin = p_bin[y] & p_bin[y+1] & p_bin[y+2]; /* To be optimised */ i_bin |= i_bin >> 16; /* detect 0 or 1 */ for( x = 0; x < 8; x++ ) { if( i_bin&0x02 ) /* 0x02 since 10 index but want 1-9 */ { /* apply dering */ /* 1 2 1 2 4 2 + (8) 1 2 1 */ i_f = p_block[x - i_stride - 1] + ( p_block[x - i_stride ] << 1)+ p_block[x - i_stride + 1] + ( p_block[x - 1] << 1 )+ ( p_block[x ] << 2 )+ ( p_block[x + 1] << 1 )+ p_block[x + i_stride - 1] + ( p_block[x + i_stride ] << 1 ) + p_block[x + i_stride + 1]; i_f = ( 8 + i_f ) >> 4; /* Clamp this value */ if( i_f - p_block[x] > ( i_QP_2 ) ) { i_flt[y][x] = p_block[x] + i_QP_2; } else if( i_f - p_block[x] < -i_QP_2 ) { i_flt[y][x] = p_block[x] - i_QP_2; } else { i_flt[y][x] = i_f ; } } else { i_flt[y][x] = p_block[x]; } i_bin >>= 1; } p_block += i_stride; } for( y = 0; y < 8; y++ ) { for( x = 0; x < 8; x++ ) { p_sav[x] = i_flt[y][x]; } p_sav+= i_stride; }}/*****************************************************************************//*---------------------------------------------------------------------------*//* *//* ----------------- Dering filter on Y and C blocks ----------------- *//* *//*---------------------------------------------------------------------------*//*****************************************************************************/void E_( pp_dering_Y )( uint8_t *p_plane, int i_width, int i_height, int i_stride, QT_STORE_T *p_QP_store, int i_QP_stride ){ int x, y, k; int i_max[4], i_min[4], i_range[4]; int i_thr[4]; int i_max_range, i_kmax; uint32_t i_bin[4][10]; uint8_t *p_block[4]; QT_STORE_T *p_QP; /* We process 4 blocks/loop*/ for( y = 8; y < i_height-8; y += 16 ) { /* +---+ |0|1| +-+-+ :)) |2|3| +-+-+ */ p_block[0] = p_plane + y * i_stride + 8; p_block[1] = p_block[0] + 8; p_block[2] = p_block[0] + ( i_stride << 3 ); p_block[3] = p_block[2] + 8; for( x = 8; x < i_width-8; x += 16 ) { /* 1: Calculate threshold */ /* Calculate max/min for each block */ pp_dering_MinMax( p_block[0], i_stride, &i_min[0], &i_max[0] ); pp_dering_MinMax( p_block[1], i_stride, &i_min[1], &i_max[1] ); pp_dering_MinMax( p_block[2], i_stride, &i_min[2], &i_max[2] ); pp_dering_MinMax( p_block[3], i_stride, &i_min[3], &i_max[3] ); /* Calculate range, max_range and thr */ i_max_range = 0; i_kmax = 0; for( k = 0; k <= 4; k++ ) { i_range[k] = i_max[k] - i_min[k]; i_thr[k] = ( i_max[k] + i_min[k] + 1 )/2; if( i_max_range < i_max[k]) { i_max_range = i_max[k]; i_kmax = k; } } /* Now rearrange thr */ if( i_max_range > 64 ) { for( k = 1; k < 5; k++ ) { if( i_range[k] < 16 ) { i_thr[k] = 0; } else if( i_range[k] < 32 ) { i_thr[k] = i_thr[i_kmax]; } } } else { for( k = 1; k < 5; k++ ) { if( i_range[k] < 16 ) { i_thr[k] = 0; } } } /* 2: Index acquisition 10x10 ! so " -i_stride - 1"*/ pp_dering_BinIndex( p_block[0] - i_stride - 1, i_stride, i_thr[0], i_bin[0] ); pp_dering_BinIndex( p_block[1] - i_stride - 1, i_stride, i_thr[1], i_bin[1] ); pp_dering_BinIndex( p_block[2] - i_stride - 1, i_stride, i_thr[2], i_bin[2] ); pp_dering_BinIndex( p_block[3] - i_stride - 1, i_stride, i_thr[3], i_bin[3] ); /* 3: adaptive smoothing */ /* since we begin at (8,8) QP can be different for each block */ p_QP = &( p_QP_store[( y >> 4) * i_QP_stride + (x >> 4)] ); pp_dering_Filter( p_block[0], i_stride, i_bin[0], p_QP[0] ); pp_dering_Filter( p_block[1], i_stride, i_bin[1], p_QP[1] ); pp_dering_Filter( p_block[2], i_stride, i_bin[2], p_QP[i_QP_stride] ); pp_dering_Filter( p_block[3], i_stride, i_bin[3], p_QP[i_QP_stride+1] ); p_block[0] += 8; p_block[1] += 8; p_block[2] += 8; p_block[3] += 8; } }}void E_( pp_dering_C )( uint8_t *p_plane, int i_width, int i_height, int i_stride, QT_STORE_T *p_QP_store, int i_QP_stride ){ int x, y; int i_max, i_min; int i_thr; uint32_t i_bin[10]; uint8_t *p_block; for( y = 8; y < i_height-8; y += 8 ) { p_block = p_plane + y * i_stride + 8; for( x = 8; x < i_width-8; x += 8 ) { /* 1: Calculate threshold */ /* Calculate max/min for each block */ pp_dering_MinMax( p_block, i_stride, &i_min, &i_max ); /* Calculate thr*/ i_thr = ( i_max + i_min + 1 )/2; /* 2: Index acquisition 10x10 */ /* point on 10x10 in wich we have our 8x8 block */ pp_dering_BinIndex( p_block - i_stride -1, i_stride, i_thr, i_bin ); /* 3: adaptive smoothing */ pp_dering_Filter( p_block, i_stride, i_bin, p_QP_store[(y>>5)*i_QP_stride+ (x>>5)]); p_block += 8; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?