postprocessing_c.c

来自「VLC媒体播放程序」· C语言 代码 · 共 626 行 · 第 1/2 页

C
626
字号
    }    return;}/***************************************************************************** * * Internals functions common to pp_Dering_Y pp_Dering_C * *****************************************************************************/static inline void pp_dering_MinMax( uint8_t *p_block, int i_stride,                                     int *pi_min, int *pi_max ){    int y;    int i_min, i_max;    i_min = 255; i_max = 0;    for( y = 0; y < 8; y++ )    {        if( i_min > p_block[0] ) i_min = p_block[0];        if( i_max < p_block[0] ) i_max = p_block[0];        if( i_min > p_block[1] ) i_min = p_block[1];        if( i_max < p_block[1] ) i_max = p_block[1];        if( i_min > p_block[2] ) i_min = p_block[2];        if( i_max < p_block[2] ) i_max = p_block[2];        if( i_min > p_block[3] ) i_min = p_block[3];        if( i_max < p_block[3] ) i_max = p_block[3];        if( i_min > p_block[4] ) i_min = p_block[4];        if( i_max < p_block[4] ) i_max = p_block[4];        if( i_min > p_block[5] ) i_min = p_block[5];        if( i_max < p_block[5] ) i_max = p_block[5];        if( i_min > p_block[6] ) i_min = p_block[6];        if( i_max < p_block[6] ) i_max = p_block[6];        if( i_min > p_block[7] ) i_min = p_block[7];        if( i_max < p_block[7] ) i_max = p_block[7];#if 0        int x;        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];        }#endif        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 + -
显示快捷键?