Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include    "mp4dec_lib.h"
     19 #include    "post_proc.h"
     20 
     21 #ifdef PV_POSTPROC_ON
     22 
     23 void Deringing_Chroma(
     24     uint8 *Rec_C,
     25     int width,
     26     int height,
     27     int16 *QP_store,
     28     int,
     29     uint8 *pp_mod
     30 )
     31 {
     32     /*----------------------------------------------------------------------------
     33     ; Define all local variables
     34     ----------------------------------------------------------------------------*/
     35     int thres;
     36     int v_blk, h_blk;
     37     int max_diff;
     38     int v_pel, h_pel;
     39     int max_blk, min_blk;
     40     int v0, h0;
     41     uint8 *ptr;
     42     int sum, sum1, incr;
     43     int32 addr_v;
     44     int sign_v[10], sum_v[10];
     45     int *ptr2, *ptr3;
     46     uint8 pelu, pelc, pell;
     47     incr = width - BLKSIZE;
     48 
     49     /*----------------------------------------------------------------------------
     50     ; Function body here
     51     ----------------------------------------------------------------------------*/
     52     /* chrominance */
     53     /* Do the first line (7 pixels at a time => Don't use MMX)*/
     54     for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
     55     {
     56         max_diff = (QP_store[h_blk>>3] >> 2) + 4;
     57         ptr = &Rec_C[h_blk];
     58         max_blk = min_blk = *ptr;
     59         FindMaxMin(ptr, &min_blk, &max_blk, width);
     60         h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
     61 
     62         if (max_blk - min_blk >= 4)
     63         {
     64             thres = (max_blk + min_blk + 1) >> 1;
     65 
     66 
     67             for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
     68             {
     69                 addr_v = (int32)v_pel * width;
     70                 ptr = &Rec_C[addr_v + h0 - 1];
     71                 ptr2 = &sum_v[0];
     72                 ptr3 = &sign_v[0];
     73 
     74                 pelu = *(ptr - width);
     75                 pelc = *ptr;
     76                 pell = *(ptr + width);
     77                 ptr++;
     78                 *ptr2++ = pelu + (pelc << 1) + pell;
     79                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
     80 
     81                 pelu = *(ptr - width);
     82                 pelc = *ptr;
     83                 pell = *(ptr + width);
     84                 ptr++;
     85                 *ptr2++ = pelu + (pelc << 1) + pell;
     86                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
     87 
     88                 for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
     89                 {
     90                     pelu = *(ptr - width);
     91                     pelc = *ptr;
     92                     pell = *(ptr + width);
     93 
     94                     *ptr2 = pelu + (pelc << 1) + pell;
     95                     *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
     96 
     97                     sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
     98                     if (sum1 == 0 || sum1 == 9)
     99                     {
    100                         sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
    101 
    102                         ptr--;
    103                         if (PV_ABS(*ptr - sum) > max_diff)
    104                         {
    105                             if (sum > *ptr)
    106                                 sum = *ptr + max_diff;
    107                             else
    108                                 sum = *ptr - max_diff;
    109                         }
    110                         *ptr++ = (uint8) sum;
    111                     }
    112                     ptr++;
    113                     ptr2++;
    114                     ptr3++;
    115                 }
    116             }
    117         }
    118     }
    119 
    120     for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
    121     {
    122         v0 = v_blk - 1;
    123         /* Do the first block (pixels=7 => No MMX) */
    124         max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
    125         ptr = &Rec_C[(int32)v_blk * width];
    126         max_blk = min_blk = *ptr;
    127         FindMaxMin(ptr, &min_blk, &max_blk, incr);
    128 
    129         if (max_blk - min_blk >= 4)
    130         {
    131             thres = (max_blk + min_blk + 1) >> 1;
    132 
    133             for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
    134             {
    135                 addr_v = v_pel * width;
    136                 ptr = &Rec_C[addr_v];
    137                 ptr2 = &sum_v[0];
    138                 ptr3 = &sign_v[0];
    139 
    140                 pelu = *(ptr - width);
    141                 pelc = *ptr;
    142                 pell = *(ptr + width);
    143                 ptr++;
    144                 *ptr2++ = pelu + (pelc << 1) + pell;
    145                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
    146 
    147                 pelu = *(ptr - width);
    148                 pelc = *ptr;
    149                 pell = *(ptr + width);
    150                 ptr++;
    151                 *ptr2++ = pelu + (pelc << 1) + pell;
    152                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
    153 
    154                 for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
    155                 {
    156                     pelu = *(ptr - width);
    157                     pelc = *ptr;
    158                     pell = *(ptr + width);
    159 
    160                     *ptr2 = pelu + (pelc << 1) + pell;
    161                     *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
    162 
    163                     sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
    164                     if (sum1 == 0 || sum1 == 9)
    165                     {
    166                         sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
    167 
    168                         ptr--;
    169                         if (PV_ABS(*ptr - sum) > max_diff)
    170                         {
    171                             if (sum > *ptr)
    172                                 sum = *ptr + max_diff;
    173                             else
    174                                 sum = *ptr - max_diff;
    175                         }
    176                         *ptr++ = (uint8) sum;
    177                     }
    178                     ptr++;
    179                     ptr2++;
    180                     ptr3++;
    181                 }
    182             }
    183         }
    184 
    185 
    186         /* Do the rest in MMX */
    187         for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
    188         {
    189             if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
    190             {
    191                 max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
    192                 ptr = &Rec_C[(int32)v_blk * width + h_blk];
    193                 max_blk = min_blk = *ptr;
    194                 FindMaxMin(ptr, &min_blk, &max_blk, incr);
    195                 h0 = h_blk - 1;
    196 
    197                 if (max_blk - min_blk >= 4)
    198                 {
    199                     thres = (max_blk + min_blk + 1) >> 1;
    200 #ifdef NoMMX
    201                     AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
    202 #else
    203                     DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
    204 #endif
    205                 }
    206             }
    207         }
    208     } /* macroblock level */
    209 
    210     /*----------------------------------------------------------------------------
    211     ; Return nothing or data or data pointer
    212     ----------------------------------------------------------------------------*/
    213     return;
    214 }
    215 #endif
    216