postprocessing_c.c

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

C
626
字号
/***************************************************************************** * postprocessing_c.c: Post Processing plugin in C ***************************************************************************** * Copyright (C) 2001 VideoLAN * $Id: postprocessing_c.c,v 1.2 2002/12/06 16:34:05 sam Exp $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#include <vlc/vlc.h> /* only use uint8_t, uint32_t .... */#include "postprocessing.h"#include "postprocessing_common.h"/***************************************************************************** * * Internals functions common to pp_deblock_V and pp_deblock_H * *****************************************************************************//**************************************************************************** * pp_deblock_isDC_mode : Check if we will use DC mode or Default mode **************************************************************************** * Use constant PP_THR1 and PP_THR2 ( PP_2xTHR1 ) * * Called for for each pixel on a boundary block when doing deblocking *  so need to be fast ... * ****************************************************************************/static inline int pp_deblock_isDC_mode( uint8_t *p_v ){    unsigned int i_eq_cnt;    /* algo :  if ( | v[i] -v[i+1] | <= PP_THR1 ) { i_eq_cnt++; } */    i_eq_cnt = 0;    if((  ( p_v[0] - p_v[1] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[1] - p_v[2] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[2] - p_v[3] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[3] - p_v[4] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[4] - p_v[5] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[5] - p_v[6] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[6] - p_v[7] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[7] - p_v[8] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;    if((  ( p_v[8] - p_v[9] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;#if 0    int i;    for( i =0; i < 9; i++ )    {        if((  ( p_v[i] - p_v[i+1] + PP_THR1 )&0xffff )<= PP_2xTHR1 )        {            i_eq_cnt++;        }    }#endif    return( (i_eq_cnt >= PP_THR2 ) ? 1 : 0 );}static inline int pp_deblock_isMinMaxOk( uint8_t *p_v, int i_QP ){    int i_max, i_min;    i_min = i_max = p_v[1];    if( i_max < p_v[1] ) i_max = p_v[1];    if( i_min > p_v[1] ) i_min = p_v[1];    if( i_max < p_v[2] ) i_max = p_v[2];    if( i_min > p_v[2] ) i_min = p_v[2];    if( i_max < p_v[3] ) i_max = p_v[3];    if( i_min > p_v[3] ) i_min = p_v[3];    if( i_max < p_v[4] ) i_max = p_v[4];    if( i_min > p_v[4] ) i_min = p_v[4];    if( i_max < p_v[5] ) i_max = p_v[5];    if( i_min > p_v[5] ) i_min = p_v[5];    if( i_max < p_v[6] ) i_max = p_v[6];    if( i_min > p_v[6] ) i_min = p_v[6];    if( i_max < p_v[7] ) i_max = p_v[7];    if( i_min > p_v[7] ) i_min = p_v[7];    if( i_max < p_v[8] ) i_max = p_v[8];    if( i_min > p_v[8] ) i_min = p_v[8];#if 0    int i;    int i_range;    for( i = 2; i < 9; i++ )    {        if( i_max < p_v[i] ) i_max = p_v[i];        if( i_min > p_v[i] ) i_min = p_v[i];    }    i_range = i_max - i_min;#endif    return( i_max - i_min < 2*i_QP ? 1 : 0 );}static inline void pp_deblock_DefaultMode( uint8_t i_v[10], int i_stride,                                      int i_QP ){    int d, i_delta;    int a3x0, a3x0_, a3x1, a3x2;    int b_neg;    /* d = CLIP( 5(a3x0' - a3x0)//8, 0, (v4-v5)/2 ).d( abs(a3x0) < QP ) */    /* First calculate a3x0 */    a3x0 = 2 * ( i_v[3] - i_v[6] ) + 5 *( i_v[5] - i_v[4] );    if( a3x0 < 0 )    {        b_neg = 1;        a3x0  = -a3x0;    }    else    {        b_neg = 0;    }    /* XXX Now a3x0 is abs( a3x0 ) */    if( ( a3x0 < 8 * i_QP )&&( a3x0 != 0 ) ) /* |a3x0| < 8*i_QP */    {        /* calculate a3x1 et a3x2 */        a3x1 = 2 * ( i_v[1] - i_v[4] ) + 5 * ( i_v[3] - i_v[2] );        a3x2 = 2 * ( i_v[5] - i_v[8] ) + 5 * ( i_v[7] - i_v[6] );        if( a3x1 < 0) a3x1 = -a3x1; /* abs( a3x1 ) */        if( a3x2 < 0) a3x2 = -a3x2; /* abs( a3x2 ) */        a3x0_ = PP_MIN3( a3x0, a3x1, a3x2 );        d = 5 *( a3x0 - a3x0_ ) / 8; /* always > 0 */        i_delta = ( i_v[4] - i_v[5] ) / 2;        /* clip into [0, i_delta] or [i_delta, 0] */        if( i_delta < 0 )        {            if( !b_neg ) /* since true d has sgn(d) = - sgn( a3x0 ) */            {                d = -d;                if( d < i_delta ) d = i_delta;                i_v[4] -= d;                i_v[5] += d;            }        }        else        {            if( b_neg )            {                if( d > i_delta ) d = i_delta;                i_v[4] -= d;                i_v[5] += d;            }        }    }}static inline void pp_deblock_DCMode( uint8_t *p_v, /*  = int i_v[10] */                                 int i_QP ){    int v[10];    int i;    int i_p0, i_p9;    i_p0 = PP_ABS( p_v[1] - p_v[0] ) < i_QP ? p_v[0] : p_v[1];    i_p9 = PP_ABS( p_v[8] - p_v[9] ) < i_QP ? p_v[9] : p_v[8];    for( i = 1; i < 9; i++ )    {        v[i] = p_v[i]; /* save 8 pix that will be modified */    }    p_v[1] = ( 6 * i_p0                        + 4 * v[1]                + 2 *( v[2] + v[3]) + v[4] + v[5]) >> 4;    p_v[2] = ( 4 * i_p0    + 2 * v[1]          + 4 * v[2]                + 2 *( v[3] + v[4]) + v[5] + v[6]) >> 4;    p_v[3] = ( 2 * i_p0    + 2 * (v[1] + v[2]) + 4 * v[3]                + 2 *( v[4] + v[5]) + v[6] + v[7]) >> 4;    p_v[4] = ( i_p0 + v[1] + 2 * (v[2] + v[3]) + 4 * v[4]                + 2 *( v[5] + v[6]) + v[7] + v[8]) >> 4;    p_v[5] = ( v[1] + v[2] + 2 * (v[3] + v[4]) + 4 * v[5]                + 2 *( v[6] + v[7]) + v[8] + i_p9) >> 4;    p_v[6] = ( v[2] + v[3] + 2 * (v[4] + v[5]) + 4 * v[6]            + 2 *( v[7] + v[8]) + 2 * i_p9) >> 4;    p_v[7] = ( v[3] + v[4] + 2 * (v[5] + v[6]) + 4 * v[7]                + 2 * v[8] + 4 * i_p9) >> 4;    p_v[8] = ( v[4] + v[5] + 2 * (v[6] + v[7]) + 4 * v[8]                                    + 6 * i_p9) >> 4;}/*****************************************************************************//*---------------------------------------------------------------------------*//*                                                                           *//*    ---------- filter Vertical lines so follow horizontal edges --------   *//*                                                                           *//*---------------------------------------------------------------------------*//*****************************************************************************/void E_( pp_deblock_V )( uint8_t *p_plane,                         int i_width, int i_height, int i_stride,                         QT_STORE_T *p_QP_store, int i_QP_stride,                         int b_chroma ){    int x, y, i;    uint8_t *p_v;    int i_QP_scale; /* use to do ( ? >> i_QP_scale ) */    int i_QP;    uint8_t i_v[10];    i_QP_scale = b_chroma ? 5 : 4 ;    for( y = 8; y < i_height - 4; y += 8 )    {        p_v = p_plane + ( y - 5 )* i_stride;        for( x = 0; x < i_width; x++ )        {            /* First get  10 vert pix to use them without i_stride */            for( i = 0; i < 10; i++ )            {                i_v[i] = p_v[i*i_stride + x];            }            i_QP = p_QP_store[(y>>i_QP_scale)*i_QP_stride+                                (x>>i_QP_scale)];            /* XXX QP is for v5 */            if( pp_deblock_isDC_mode( i_v ) )            {                if( pp_deblock_isMinMaxOk( i_v, i_QP ) )                {                    pp_deblock_DCMode( i_v, i_QP );                }            }            else            {                pp_deblock_DefaultMode( i_v, i_stride, i_QP );            }            /* Copy back, XXX only 1-8 were modified */            for( i = 1; i < 9; i++ )            {                p_v[i*i_stride + x] = i_v[i];            }        }    }    return;}/*****************************************************************************//*---------------------------------------------------------------------------*//*                                                                           *//*     --------- filter Horizontal lines so follow vertical edges --------   *//*                                                                           *//*---------------------------------------------------------------------------*//*****************************************************************************/void E_( pp_deblock_H )( uint8_t *p_plane,                         int i_width, int i_height, int i_stride,                         QT_STORE_T *p_QP_store, int i_QP_stride,                         int b_chroma ){    int x, y;    uint8_t *p_v;    int i_QP_scale;    int i_QP;    i_QP_scale = b_chroma ? 5 : 4 ;    for( y = 0; y < i_height; y++ )    {        p_v = p_plane + y * i_stride - 5;        for( x = 8; x < i_width - 4; x += 8 )        {            /* p_v point 5 pix before a block boundary */            /* XXX QP is for v5 */            i_QP = p_QP_store[(y>>i_QP_scale)*i_QP_stride+                                 (x>>i_QP_scale)];            if( pp_deblock_isDC_mode( p_v + x ) )            {                if( pp_deblock_isMinMaxOk( p_v+ x, i_QP ) )                {                    pp_deblock_DCMode( p_v+x, i_QP );                }            }            else            {                pp_deblock_DefaultMode( p_v+x, i_stride, i_QP );            }        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?