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