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 19 #include <string.h> 20 21 #include "avclib_common.h" 22 23 #define MAX_QP 51 24 #define MB_BLOCK_SIZE 16 25 26 // NOTE: these 3 tables are for funtion GetStrength() only 27 const static int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303}; 28 29 30 // NOTE: these 3 tables are for funtion EdgeLoop() only 31 // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values 32 33 const static int ALPHA_TABLE[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 15, 17, 20, 22, 25, 28, 32, 36, 40, 45, 50, 56, 63, 71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, 255, 255} ; 34 const static int BETA_TABLE[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18} ; 35 const static int CLIP_TAB[52][5] = 36 { 37 { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, 38 { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, 39 { 0, 0, 0, 0, 0}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 1, 1, 1, 1}, 40 { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 2, 3, 3}, 41 { 0, 1, 2, 3, 3}, { 0, 2, 2, 3, 3}, { 0, 2, 2, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 3, 3, 5, 5}, { 0, 3, 4, 6, 6}, { 0, 3, 4, 6, 6}, 42 { 0, 4, 5, 7, 7}, { 0, 4, 5, 8, 8}, { 0, 4, 6, 9, 9}, { 0, 5, 7, 10, 10}, { 0, 6, 8, 11, 11}, { 0, 6, 8, 13, 13}, { 0, 7, 10, 14, 14}, { 0, 8, 11, 16, 16}, 43 { 0, 9, 12, 18, 18}, { 0, 10, 13, 20, 20}, { 0, 11, 15, 23, 23}, { 0, 13, 17, 25, 25} 44 }; 45 46 // NOTE: this table is only QP clipping, index = QP + video->FilterOffsetA/B, clipped to [0, 51] 47 // video->FilterOffsetA/B is in {-12, 12] 48 const static int QP_CLIP_TAB[76] = 49 { 50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // [-12, 0] 51 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 52 13, 14, 15, 16, 17, 18, 19, 20, 21, 53 22, 23, 24, 25, 26, 27, 28, 29, 30, 54 31, 32, 33, 34, 35, 36, 37, 38, 39, 55 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // [1, 51] 56 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 // [52,63] 57 }; 58 59 static void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV); 60 //static void GetStrength(AVCCommonObj *video, uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir, int edge); 61 static void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir); 62 static void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ); 63 static void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ); 64 static void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch); 65 static void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch); 66 static void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch); 67 static void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch); 68 69 /* 70 ***************************************************************************************** 71 * \brief Filter all macroblocks in order of increasing macroblock address. 72 ***************************************************************************************** 73 */ 74 75 OSCL_EXPORT_REF AVCStatus DeblockPicture(AVCCommonObj *video) 76 { 77 uint i, j; 78 int pitch = video->currPic->pitch, pitch_c, width; 79 uint8 *SrcY, *SrcU, *SrcV; 80 81 SrcY = video->currPic->Sl; // pointers to source 82 SrcU = video->currPic->Scb; 83 SrcV = video->currPic->Scr; 84 pitch_c = pitch >> 1; 85 width = video->currPic->width; 86 87 for (i = 0; i < video->PicHeightInMbs; i++) 88 { 89 for (j = 0; j < video->PicWidthInMbs; j++) 90 { 91 DeblockMb(video, j, i, SrcY, SrcU, SrcV); 92 // update SrcY, SrcU, SrcV 93 SrcY += MB_BLOCK_SIZE; 94 SrcU += (MB_BLOCK_SIZE >> 1); 95 SrcV += (MB_BLOCK_SIZE >> 1); 96 } 97 98 SrcY += ((pitch << 4) - width); 99 SrcU += ((pitch_c << 3) - (width >> 1)); 100 SrcV += ((pitch_c << 3) - (width >> 1)); 101 } 102 103 return AVC_SUCCESS; 104 } 105 106 #ifdef MB_BASED_DEBLOCK 107 /* 108 ***************************************************************************************** 109 * \brief Filter one macroblocks in a fast macroblock memory and copy it to frame 110 ***************************************************************************************** 111 */ 112 void MBInLoopDeblock(AVCCommonObj *video) 113 { 114 AVCPictureData *currPic = video->currPic; 115 #ifdef USE_PRED_BLOCK 116 uint8 *predCb, *predCr, *pred_block; 117 int i, j, dst_width, dst_height, dst_widthc, dst_heightc; 118 #endif 119 int pitch = currPic->pitch; 120 int x_pos = video->mb_x; 121 int y_pos = video->mb_y; 122 uint8 *curL, *curCb, *curCr; 123 int offset; 124 125 offset = (y_pos << 4) * pitch; 126 127 curL = currPic->Sl + offset + (x_pos << 4); 128 129 offset >>= 2; 130 offset += (x_pos << 3); 131 132 curCb = currPic->Scb + offset; 133 curCr = currPic->Scr + offset; 134 135 #ifdef USE_PRED_BLOCK 136 pred_block = video->pred; 137 138 /* 1. copy neighboring pixels from frame to the video->pred_block */ 139 if (y_pos) /* not the 0th row */ 140 { 141 /* copy to the top 4 lines of the macroblock */ 142 curL -= (pitch << 2); /* go back 4 lines */ 143 144 memcpy(pred_block + 4, curL, 16); 145 curL += pitch; 146 memcpy(pred_block + 24, curL, 16); 147 curL += pitch; 148 memcpy(pred_block + 44, curL, 16); 149 curL += pitch; 150 memcpy(pred_block + 64, curL, 16); 151 curL += pitch; 152 153 curCb -= (pitch << 1); /* go back 4 lines chroma */ 154 curCr -= (pitch << 1); 155 156 pred_block += 400; 157 158 memcpy(pred_block + 4, curCb, 8); 159 curCb += (pitch >> 1); 160 memcpy(pred_block + 16, curCb, 8); 161 curCb += (pitch >> 1); 162 memcpy(pred_block + 28, curCb, 8); 163 curCb += (pitch >> 1); 164 memcpy(pred_block + 40, curCb, 8); 165 curCb += (pitch >> 1); 166 167 pred_block += 144; 168 memcpy(pred_block + 4, curCr, 8); 169 curCr += (pitch >> 1); 170 memcpy(pred_block + 16, curCr, 8); 171 curCr += (pitch >> 1); 172 memcpy(pred_block + 28, curCr, 8); 173 curCr += (pitch >> 1); 174 memcpy(pred_block + 40, curCr, 8); 175 curCr += (pitch >> 1); 176 177 pred_block = video->pred; 178 } 179 180 /* 2. perform deblocking. */ 181 DeblockMb(video, x_pos, y_pos, pred_block + 84, pred_block + 452, pred_block + 596); 182 183 /* 3. copy it back to the frame and update pred_block */ 184 predCb = pred_block + 400; 185 predCr = predCb + 144; 186 187 /* find the range of the block inside pred_block to be copied back */ 188 if (y_pos) /* the first row */ 189 { 190 curL -= (pitch << 2); 191 curCb -= (pitch << 1); 192 curCr -= (pitch << 1); 193 194 dst_height = 20; 195 dst_heightc = 12; 196 } 197 else 198 { 199 pred_block += 80; 200 predCb += 48; 201 predCr += 48; 202 dst_height = 16; 203 dst_heightc = 8; 204 } 205 206 if (x_pos) /* find the width */ 207 { 208 curL -= 4; 209 curCb -= 4; 210 curCr -= 4; 211 if (x_pos == (int)(video->PicWidthInMbs - 1)) 212 { 213 dst_width = 20; 214 dst_widthc = 12; 215 } 216 else 217 { 218 dst_width = 16; 219 dst_widthc = 8; 220 } 221 } 222 else 223 { 224 pred_block += 4; 225 predCb += 4; 226 predCr += 4; 227 dst_width = 12; 228 dst_widthc = 4; 229 } 230 231 /* perform copy */ 232 for (j = 0; j < dst_height; j++) 233 { 234 memcpy(curL, pred_block, dst_width); 235 curL += pitch; 236 pred_block += 20; 237 } 238 for (j = 0; j < dst_heightc; j++) 239 { 240 memcpy(curCb, predCb, dst_widthc); 241 memcpy(curCr, predCr, dst_widthc); 242 curCb += (pitch >> 1); 243 curCr += (pitch >> 1); 244 predCb += 12; 245 predCr += 12; 246 } 247 248 if (x_pos != (int)(video->PicWidthInMbs - 1)) /* now copy from the right-most 4 columns to the left-most 4 columns */ 249 { 250 pred_block = video->pred; 251 for (i = 0; i < 20; i += 4) 252 { 253 *((uint32*)pred_block) = *((uint32*)(pred_block + 16)); 254 pred_block += 20; 255 *((uint32*)pred_block) = *((uint32*)(pred_block + 16)); 256 pred_block += 20; 257 *((uint32*)pred_block) = *((uint32*)(pred_block + 16)); 258 pred_block += 20; 259 *((uint32*)pred_block) = *((uint32*)(pred_block + 16)); 260 pred_block += 20; 261 } 262 263 for (i = 0; i < 24; i += 4) 264 { 265 *((uint32*)pred_block) = *((uint32*)(pred_block + 8)); 266 pred_block += 12; 267 *((uint32*)pred_block) = *((uint32*)(pred_block + 8)); 268 pred_block += 12; 269 *((uint32*)pred_block) = *((uint32*)(pred_block + 8)); 270 pred_block += 12; 271 *((uint32*)pred_block) = *((uint32*)(pred_block + 8)); 272 pred_block += 12; 273 } 274 275 } 276 #else 277 DeblockMb(video, x_pos, y_pos, curL, curCb, curCr); 278 #endif 279 280 return ; 281 } 282 #endif 283 284 /* 285 ***************************************************************************************** 286 * \brief Deblocking filter for one macroblock. 287 ***************************************************************************************** 288 */ 289 290 void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV) 291 { 292 AVCMacroblock *MbP, *MbQ; 293 int edge, QP, QPC; 294 int filterLeftMbEdgeFlag = (mb_x != 0); 295 int filterTopMbEdgeFlag = (mb_y != 0); 296 int pitch = video->currPic->pitch; 297 int indexA, indexB; 298 int *tmp; 299 int Alpha, Beta, Alpha_c, Beta_c; 300 int mbNum = mb_y * video->PicWidthInMbs + mb_x; 301 int *clipTable, *clipTable_c, *qp_clip_tab; 302 uint8 Strength[16]; 303 void* str; 304 305 MbQ = &(video->mblock[mbNum]); // current Mb 306 307 308 // If filter is disabled, return 309 if (video->sliceHdr->disable_deblocking_filter_idc == 1) return; 310 311 if (video->sliceHdr->disable_deblocking_filter_idc == 2) 312 { 313 // don't filter at slice boundaries 314 filterLeftMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - 1, mbNum); 315 filterTopMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - video->PicWidthInMbs, mbNum); 316 } 317 318 /* NOTE: edge=0 and edge=1~3 are separate cases because of the difference of MbP, index A and indexB calculation */ 319 /* for edge = 1~3, MbP, indexA and indexB remain the same, and thus there is no need to re-calculate them for each edge */ 320 321 qp_clip_tab = (int *)QP_CLIP_TAB + 12; 322 323 /* 1.VERTICAL EDGE + MB BOUNDARY (edge = 0) */ 324 if (filterLeftMbEdgeFlag) 325 { 326 MbP = MbQ - 1; 327 //GetStrength(video, Strength, MbP, MbQ, 0, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge 328 GetStrength_Edge0(Strength, MbP, MbQ, 0); 329 330 str = (void*)Strength; //de-ref type-punned pointer fix 331 if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0 332 { 333 QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks; 334 indexA = QP + video->FilterOffsetA; 335 indexB = QP + video->FilterOffsetB; 336 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 337 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 338 339 Alpha = ALPHA_TABLE[indexA]; 340 Beta = BETA_TABLE[indexB]; 341 clipTable = (int *) CLIP_TAB[indexA]; 342 343 if (Alpha > 0 && Beta > 0) 344 #ifdef USE_PRED_BLOCK 345 EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, 20); 346 #else 347 EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, pitch); 348 #endif 349 350 QPC = (MbP->QPc + MbQ->QPc + 1) >> 1; 351 indexA = QPC + video->FilterOffsetA; 352 indexB = QPC + video->FilterOffsetB; 353 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 354 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 355 356 Alpha = ALPHA_TABLE[indexA]; 357 Beta = BETA_TABLE[indexB]; 358 clipTable = (int *) CLIP_TAB[indexA]; 359 if (Alpha > 0 && Beta > 0) 360 { 361 #ifdef USE_PRED_BLOCK 362 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, 12); 363 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, 12); 364 #else 365 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1); 366 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1); 367 #endif 368 } 369 } 370 371 } /* end of: if(filterLeftMbEdgeFlag) */ 372 373 /* 2.VERTICAL EDGE (no boundary), the edges are all inside a MB */ 374 /* First calculate the necesary parameters all at once, outside the loop */ 375 MbP = MbQ; 376 377 indexA = MbQ->QPy + video->FilterOffsetA; 378 indexB = MbQ->QPy + video->FilterOffsetB; 379 // index 380 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 381 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 382 383 Alpha = ALPHA_TABLE[indexA]; 384 Beta = BETA_TABLE[indexB]; 385 clipTable = (int *)CLIP_TAB[indexA]; 386 387 /* Save Alpha, Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */ 388 filterLeftMbEdgeFlag = Alpha; 389 mbNum = Beta; 390 tmp = clipTable; 391 392 indexA = MbQ->QPc + video->FilterOffsetA; 393 indexB = MbQ->QPc + video->FilterOffsetB; 394 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 395 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 396 397 Alpha_c = ALPHA_TABLE[indexA]; 398 Beta_c = BETA_TABLE[indexB]; 399 clipTable_c = (int *)CLIP_TAB[indexA]; 400 401 GetStrength_VerticalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge 402 403 for (edge = 1; edge < 4; edge++) // 4 vertical strips of 16 pel 404 { 405 //GetStrength_VerticalEdges(video, Strength, MbP, MbQ, 0, edge); // Strength for 4 blks in 1 stripe, 0 => vertical edge 406 if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0 407 { 408 if (Alpha > 0 && Beta > 0) 409 #ifdef USE_PRED_BLOCK 410 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, 20); 411 #else 412 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, pitch); 413 #endif 414 415 if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0) 416 { 417 #ifdef USE_PRED_BLOCK 418 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12); 419 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12); 420 #else 421 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1); 422 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1); 423 #endif 424 } 425 } 426 427 } //end edge 428 429 430 431 /* 3.HORIZONTAL EDGE + MB BOUNDARY (edge = 0) */ 432 if (filterTopMbEdgeFlag) 433 { 434 MbP = MbQ - video->PicWidthInMbs; 435 //GetStrength(video, Strength, MbP, MbQ, 1, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge 436 GetStrength_Edge0(Strength, MbP, MbQ, 1); 437 str = (void*)Strength; //de-ref type-punned pointer fix 438 if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0 439 { 440 QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks; 441 indexA = QP + video->FilterOffsetA; 442 indexB = QP + video->FilterOffsetB; 443 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 444 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 445 446 Alpha = ALPHA_TABLE[indexA]; 447 Beta = BETA_TABLE[indexB]; 448 clipTable = (int *)CLIP_TAB[indexA]; 449 450 if (Alpha > 0 && Beta > 0) 451 { 452 #ifdef USE_PRED_BLOCK 453 EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, 20); 454 #else 455 EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, pitch); 456 #endif 457 } 458 459 QPC = (MbP->QPc + MbQ->QPc + 1) >> 1; 460 indexA = QPC + video->FilterOffsetA; 461 indexB = QPC + video->FilterOffsetB; 462 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA) 463 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB) 464 465 Alpha = ALPHA_TABLE[indexA]; 466 Beta = BETA_TABLE[indexB]; 467 clipTable = (int *)CLIP_TAB[indexA]; 468 if (Alpha > 0 && Beta > 0) 469 { 470 #ifdef USE_PRED_BLOCK 471 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, 12); 472 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, 12); 473 #else 474 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1); 475 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1); 476 #endif 477 } 478 } 479 480 } /* end of: if(filterTopMbEdgeFlag) */ 481 482 483 /* 4.HORIZONTAL EDGE (no boundary), the edges are inside a MB */ 484 MbP = MbQ; 485 486 /* Recover Alpha, Beta and clipTable for edge!=0 with the variables filterLeftMbEdgeFlag, mbNum and tmp */ 487 /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */ 488 Alpha = filterLeftMbEdgeFlag; 489 Beta = mbNum; 490 clipTable = tmp; 491 492 GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge 493 494 for (edge = 1; edge < 4; edge++) // 4 horicontal strips of 16 pel 495 { 496 //GetStrength(video, Strength, MbP, MbQ, 1, edge); // Strength for 4 blks in 1 stripe 1 => horizontal edge 497 if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0 498 { 499 if (Alpha > 0 && Beta > 0) 500 { 501 #ifdef USE_PRED_BLOCK 502 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*20, Strength + (edge << 2), Alpha, Beta, clipTable, 20); 503 #else 504 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*pitch, Strength + (edge << 2), Alpha, Beta, clipTable, pitch); 505 #endif 506 } 507 508 if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0) 509 { 510 #ifdef USE_PRED_BLOCK 511 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12); 512 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12); 513 #else 514 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1); 515 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1); 516 #endif 517 } 518 } 519 520 } //end edge 521 522 return; 523 } 524 525 /* 526 ***************************************************************************************************** 527 * \brief returns a buffer of 4 Strength values for one stripe in a mb (for different Frame types) 528 ***************************************************************************************************** 529 */ 530 531 void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir) 532 { 533 int tmp; 534 int16 *ptrQ, *ptrP; 535 void* vptr; 536 uint8 *pStrength; 537 void* refIdx; 538 539 if (MbP->mbMode == AVC_I4 || MbP->mbMode == AVC_I16 || 540 MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16) 541 { 542 543 *((int*)Strength) = ININT_STRENGTH[0]; // Start with Strength=3. or Strength=4 for Mb-edge 544 545 } 546 else // if not intra or SP-frame 547 { 548 *((int*)Strength) = 0; 549 550 if (dir == 0) // Vertical Edge 0 551 { 552 553 //1. Check the ref_frame_id 554 refIdx = (void*) MbQ->RefIdx; //de-ref type-punned pointer fix 555 ptrQ = (int16*)refIdx; 556 refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer fix 557 ptrP = (int16*)refIdx; 558 pStrength = Strength; 559 if (ptrQ[0] != ptrP[1]) pStrength[0] = 1; 560 if (ptrQ[2] != ptrP[3]) pStrength[2] = 1; 561 pStrength[1] = pStrength[0]; 562 pStrength[3] = pStrength[2]; 563 564 //2. Check the non-zero coeff blocks (4x4) 565 if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[3] != 0) pStrength[0] = 2; 566 if (MbQ->nz_coeff[4] != 0 || MbP->nz_coeff[7] != 0) pStrength[1] = 2; 567 if (MbQ->nz_coeff[8] != 0 || MbP->nz_coeff[11] != 0) pStrength[2] = 2; 568 if (MbQ->nz_coeff[12] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2; 569 570 //3. Only need to check the mv difference 571 vptr = (void*)MbQ->mvL0; // for deref type-punned pointer 572 ptrQ = (int16*)vptr; 573 ptrP = (int16*)(MbP->mvL0 + 3); // points to 4x4 block #3 (the 4th column) 574 575 // 1st blk 576 if (*pStrength == 0) 577 { 578 // check |mv difference| >= 4 579 tmp = *ptrQ++ - *ptrP++; 580 if (tmp < 0) tmp = -tmp; 581 if (tmp >= 4) *pStrength = 1; 582 583 tmp = *ptrQ-- - *ptrP--; 584 if (tmp < 0) tmp = -tmp; 585 if (tmp >= 4) *pStrength = 1; 586 } 587 588 pStrength++; 589 ptrQ += 8; 590 ptrP += 8; 591 592 // 2nd blk 593 if (*pStrength == 0) 594 { 595 // check |mv difference| >= 4 596 tmp = *ptrQ++ - *ptrP++; 597 if (tmp < 0) tmp = -tmp; 598 if (tmp >= 4) *pStrength = 1; 599 600 tmp = *ptrQ-- - *ptrP--; 601 if (tmp < 0) tmp = -tmp; 602 if (tmp >= 4) *pStrength = 1; 603 } 604 605 pStrength++; 606 ptrQ += 8; 607 ptrP += 8; 608 609 // 3rd blk 610 if (*pStrength == 0) 611 { 612 // check |mv difference| >= 4 613 tmp = *ptrQ++ - *ptrP++; 614 if (tmp < 0) tmp = -tmp; 615 if (tmp >= 4) *pStrength = 1; 616 617 tmp = *ptrQ-- - *ptrP--; 618 if (tmp < 0) tmp = -tmp; 619 if (tmp >= 4) *pStrength = 1; 620 } 621 622 pStrength++; 623 ptrQ += 8; 624 ptrP += 8; 625 626 // 4th blk 627 if (*pStrength == 0) 628 { 629 // check |mv difference| >= 4 630 tmp = *ptrQ++ - *ptrP++; 631 if (tmp < 0) tmp = -tmp; 632 if (tmp >= 4) *pStrength = 1; 633 634 tmp = *ptrQ-- - *ptrP--; 635 if (tmp < 0) tmp = -tmp; 636 if (tmp >= 4) *pStrength = 1; 637 } 638 } 639 else // Horizontal Edge 0 640 { 641 642 //1. Check the ref_frame_id 643 refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer 644 ptrQ = (int16*)refIdx; 645 refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer 646 ptrP = (int16*)refIdx; 647 pStrength = Strength; 648 if (ptrQ[0] != ptrP[2]) pStrength[0] = 1; 649 if (ptrQ[1] != ptrP[3]) pStrength[2] = 1; 650 pStrength[1] = pStrength[0]; 651 pStrength[3] = pStrength[2]; 652 653 //2. Check the non-zero coeff blocks (4x4) 654 if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[12] != 0) pStrength[0] = 2; 655 if (MbQ->nz_coeff[1] != 0 || MbP->nz_coeff[13] != 0) pStrength[1] = 2; 656 if (MbQ->nz_coeff[2] != 0 || MbP->nz_coeff[14] != 0) pStrength[2] = 2; 657 if (MbQ->nz_coeff[3] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2; 658 659 //3. Only need to check the mv difference 660 vptr = (void*)MbQ->mvL0; 661 ptrQ = (int16*)vptr; 662 ptrP = (int16*)(MbP->mvL0 + 12); // points to 4x4 block #12 (the 4th row) 663 664 // 1st blk 665 if (*pStrength == 0) 666 { 667 // check |mv difference| >= 4 668 tmp = *ptrQ++ - *ptrP++; 669 if (tmp < 0) tmp = -tmp; 670 if (tmp >= 4) *pStrength = 1; 671 672 tmp = *ptrQ-- - *ptrP--; 673 if (tmp < 0) tmp = -tmp; 674 if (tmp >= 4) *pStrength = 1; 675 } 676 677 pStrength++; 678 ptrQ += 2; 679 ptrP += 2; 680 681 // 2nd blk 682 if (*pStrength == 0) 683 { 684 // check |mv difference| >= 4 685 tmp = *ptrQ++ - *ptrP++; 686 if (tmp < 0) tmp = -tmp; 687 if (tmp >= 4) *pStrength = 1; 688 689 tmp = *ptrQ-- - *ptrP--; 690 if (tmp < 0) tmp = -tmp; 691 if (tmp >= 4) *pStrength = 1; 692 } 693 694 pStrength++; 695 ptrQ += 2; 696 ptrP += 2; 697 698 // 3rd blk 699 if (*pStrength == 0) 700 { 701 // check |mv difference| >= 4 702 tmp = *ptrQ++ - *ptrP++; 703 if (tmp < 0) tmp = -tmp; 704 if (tmp >= 4) *pStrength = 1; 705 706 tmp = *ptrQ-- - *ptrP--; 707 if (tmp < 0) tmp = -tmp; 708 if (tmp >= 4) *pStrength = 1; 709 } 710 711 pStrength++; 712 ptrQ += 2; 713 ptrP += 2; 714 715 // 4th blk 716 if (*pStrength == 0) 717 { 718 // check |mv difference| >= 4 719 tmp = *ptrQ++ - *ptrP++; 720 if (tmp < 0) tmp = -tmp; 721 if (tmp >= 4) *pStrength = 1; 722 723 tmp = *ptrQ-- - *ptrP--; 724 if (tmp < 0) tmp = -tmp; 725 if (tmp >= 4) *pStrength = 1; 726 } 727 728 } /* end of: else if(dir == 0) */ 729 730 } /* end of: if( !(MbP->mbMode == AVC_I4 ...) */ 731 } 732 733 734 void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ) 735 { 736 int idx, tmp; 737 int16 *ptr, *pmvx, *pmvy; 738 uint8 *pnz; 739 uint8 *pStrength, *pStr; 740 void* refIdx; 741 742 if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16) 743 { 744 *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge 745 *((int*)(Strength + 4)) = ININT_STRENGTH[2]; 746 *((int*)(Strength + 8)) = ININT_STRENGTH[3]; 747 } 748 else // Not intra or SP-frame 749 { 750 751 *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2. 752 *((int*)(Strength + 4)) = 0; 753 *((int*)(Strength + 8)) = 0; 754 755 //1. Check the ref_frame_id 756 refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer fix 757 ptr = (int16*)refIdx; 758 pStrength = Strength; 759 if (ptr[0] != ptr[1]) pStrength[4] = 1; 760 if (ptr[2] != ptr[3]) pStrength[6] = 1; 761 pStrength[5] = pStrength[4]; 762 pStrength[7] = pStrength[6]; 763 764 //2. Check the nz_coeff block and mv difference 765 pmvx = (int16*)(MbQ->mvL0 + 1); // points to 4x4 block #1,not #0 766 pmvy = pmvx + 1; 767 for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2 768 { 769 // first/third row : 1,2,3 or 9,10,12 770 // Strength = 2 for a whole row 771 pnz = MbQ->nz_coeff + (idx << 2); 772 if (*pnz++ != 0) *pStrength = 2; 773 if (*pnz++ != 0) 774 { 775 *pStrength = 2; 776 *(pStrength + 4) = 2; 777 } 778 if (*pnz++ != 0) 779 { 780 *(pStrength + 4) = 2; 781 *(pStrength + 8) = 2; 782 } 783 if (*pnz != 0) *(pStrength + 8) = 2; 784 785 // Then Strength = 1 786 if (*pStrength == 0) 787 { 788 //within the same 8x8 block, no need to check the reference id 789 //only need to check the |mv difference| >= 4 790 tmp = *pmvx - *(pmvx - 2); 791 if (tmp < 0) tmp = -tmp; 792 if (tmp >= 4) *pStrength = 1; 793 794 tmp = *pmvy - *(pmvy - 2); 795 if (tmp < 0) tmp = -tmp; 796 if (tmp >= 4) *pStrength = 1; 797 } 798 799 pmvx += 2; 800 pmvy += 2; 801 pStr = pStrength + 4; 802 803 if (*pStr == 0) 804 { 805 //check the |mv difference| >= 4 806 tmp = *pmvx - *(pmvx - 2); 807 if (tmp < 0) tmp = -tmp; 808 if (tmp >= 4) *pStr = 1; 809 810 tmp = *pmvy - *(pmvy - 2); 811 if (tmp < 0) tmp = -tmp; 812 if (tmp >= 4) *pStr = 1; 813 } 814 815 pmvx += 2; 816 pmvy += 2; 817 pStr = pStrength + 8; 818 819 if (*pStr == 0) 820 { 821 //within the same 8x8 block, no need to check the reference id 822 //only need to check the |mv difference| >= 4 823 tmp = *pmvx - *(pmvx - 2); 824 if (tmp < 0) tmp = -tmp; 825 if (tmp >= 4) *pStr = 1; 826 827 tmp = *pmvy - *(pmvy - 2); 828 if (tmp < 0) tmp = -tmp; 829 if (tmp >= 4) *pStr = 1; 830 } 831 832 // Second/fourth row: 5,6,7 or 14,15,16 833 // Strength = 2 for a whole row 834 pnz = MbQ->nz_coeff + ((idx + 1) << 2); 835 if (*pnz++ != 0) *(pStrength + 1) = 2; 836 if (*pnz++ != 0) 837 { 838 *(pStrength + 1) = 2; 839 *(pStrength + 5) = 2; 840 } 841 if (*pnz++ != 0) 842 { 843 *(pStrength + 5) = 2; 844 *(pStrength + 9) = 2; 845 } 846 if (*pnz != 0) *(pStrength + 9) = 2; 847 848 // Then Strength = 1 849 pmvx += 4; 850 pmvy += 4; 851 pStr = pStrength + 1; 852 if (*pStr == 0) 853 { 854 //within the same 8x8 block, no need to check the reference id 855 //only need to check the |mv difference| >= 4 856 tmp = *pmvx - *(pmvx - 2); 857 if (tmp < 0) tmp = -tmp; 858 if (tmp >= 4) *pStr = 1; 859 860 tmp = *pmvy - *(pmvy - 2); 861 if (tmp < 0) tmp = -tmp; 862 if (tmp >= 4) *pStr = 1; 863 } 864 865 pmvx += 2; 866 pmvy += 2; 867 pStr = pStrength + 5; 868 869 if (*pStr == 0) 870 { 871 //check the |mv difference| >= 4 872 tmp = *pmvx - *(pmvx - 2); 873 if (tmp < 0) tmp = -tmp; 874 if (tmp >= 4) *pStr = 1; 875 876 tmp = *pmvy - *(pmvy - 2); 877 if (tmp < 0) tmp = -tmp; 878 if (tmp >= 4) *pStr = 1; 879 } 880 881 pmvx += 2; 882 pmvy += 2; 883 pStr = pStrength + 9; 884 885 if (*pStr == 0) 886 { 887 //within the same 8x8 block, no need to check the reference id 888 //only need to check the |mv difference| >= 4 889 tmp = *pmvx - *(pmvx - 2); 890 if (tmp < 0) tmp = -tmp; 891 if (tmp >= 4) *pStr = 1; 892 893 tmp = *pmvy - *(pmvy - 2); 894 if (tmp < 0) tmp = -tmp; 895 if (tmp >= 4) *pStr = 1; 896 } 897 898 // update some variables for the next two rows 899 pmvx += 4; 900 pmvy += 4; 901 pStrength += 2; 902 903 } /* end of: for(idx=0; idx<2; idx++) */ 904 905 } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */ 906 } 907 908 909 void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ) 910 { 911 int idx, tmp; 912 int16 *ptr, *pmvx, *pmvy; 913 uint8 *pStrength, *pStr; 914 void* refIdx; 915 916 if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16) 917 { 918 *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge 919 *((int*)(Strength + 4)) = ININT_STRENGTH[2]; 920 *((int*)(Strength + 8)) = ININT_STRENGTH[3]; 921 } 922 else // Not intra or SP-frame 923 { 924 925 *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2. 926 *((int*)(Strength + 4)) = 0; // for non-intra MB, strength = 0, 1 or 2. 927 *((int*)(Strength + 8)) = 0; // for non-intra MB, strength = 0, 1 or 2. 928 929 930 //1. Check the ref_frame_id 931 refIdx = (void*) MbQ->RefIdx; // de-ref type-punned fix 932 ptr = (int16*) refIdx; 933 pStrength = Strength; 934 if (ptr[0] != ptr[2]) pStrength[4] = 1; 935 if (ptr[1] != ptr[3]) pStrength[6] = 1; 936 pStrength[5] = pStrength[4]; 937 pStrength[7] = pStrength[6]; 938 939 //2. Check the nz_coeff block and mv difference 940 pmvx = (int16*)(MbQ->mvL0 + 4); // points to 4x4 block #4,not #0 941 pmvy = pmvx + 1; 942 for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2 943 { 944 // first/third row : 1,2,3 or 9,10,12 945 // Strength = 2 for a whole row 946 if (MbQ->nz_coeff[idx] != 0) *pStrength = 2; 947 if (MbQ->nz_coeff[4+idx] != 0) 948 { 949 *pStrength = 2; 950 *(pStrength + 4) = 2; 951 } 952 if (MbQ->nz_coeff[8+idx] != 0) 953 { 954 *(pStrength + 4) = 2; 955 *(pStrength + 8) = 2; 956 } 957 if (MbQ->nz_coeff[12+idx] != 0) *(pStrength + 8) = 2; 958 959 // Then Strength = 1 960 if (*pStrength == 0) 961 { 962 //within the same 8x8 block, no need to check the reference id 963 //only need to check the |mv difference| >= 4 964 tmp = *pmvx - *(pmvx - 8); 965 if (tmp < 0) tmp = -tmp; 966 if (tmp >= 4) *pStrength = 1; 967 968 tmp = *pmvy - *(pmvy - 8); 969 if (tmp < 0) tmp = -tmp; 970 if (tmp >= 4) *pStrength = 1; 971 } 972 973 pmvx += 8; 974 pmvy += 8; 975 pStr = pStrength + 4; 976 977 if (*pStr == 0) 978 { 979 //check the |mv difference| >= 4 980 tmp = *pmvx - *(pmvx - 8); 981 if (tmp < 0) tmp = -tmp; 982 if (tmp >= 4) *pStr = 1; 983 984 tmp = *pmvy - *(pmvy - 8); 985 if (tmp < 0) tmp = -tmp; 986 if (tmp >= 4) *pStr = 1; 987 } 988 989 pmvx += 8; 990 pmvy += 8; 991 pStr = pStrength + 8; 992 993 if (*pStr == 0) 994 { 995 //within the same 8x8 block, no need to check the reference id 996 //only need to check the |mv difference| >= 4 997 tmp = *pmvx - *(pmvx - 8); 998 if (tmp < 0) tmp = -tmp; 999 if (tmp >= 4) *pStr = 1; 1000 1001 tmp = *pmvy - *(pmvy - 8); 1002 if (tmp < 0) tmp = -tmp; 1003 if (tmp >= 4) *pStr = 1; 1004 } 1005 1006 // Second/fourth row: 5,6,7 or 14,15,16 1007 // Strength = 2 for a whole row 1008 if (MbQ->nz_coeff[idx+1] != 0) *(pStrength + 1) = 2; 1009 if (MbQ->nz_coeff[4+idx+1] != 0) 1010 { 1011 *(pStrength + 1) = 2; 1012 *(pStrength + 5) = 2; 1013 } 1014 if (MbQ->nz_coeff[8+idx+1] != 0) 1015 { 1016 *(pStrength + 5) = 2; 1017 *(pStrength + 9) = 2; 1018 } 1019 if (MbQ->nz_coeff[12+idx+1] != 0) *(pStrength + 9) = 2; 1020 1021 // Then Strength = 1 1022 pmvx -= 14; 1023 pmvy -= 14; // -14 = -16 + 2 1024 pStr = pStrength + 1; 1025 if (*pStr == 0) 1026 { 1027 //within the same 8x8 block, no need to check the reference id 1028 //only need to check the |mv difference| >= 4 1029 tmp = *pmvx - *(pmvx - 8); 1030 if (tmp < 0) tmp = -tmp; 1031 if (tmp >= 4) *pStr = 1; 1032 1033 tmp = *pmvy - *(pmvy - 8); 1034 if (tmp < 0) tmp = -tmp; 1035 if (tmp >= 4) *pStr = 1; 1036 } 1037 1038 pmvx += 8; 1039 pmvy += 8; 1040 pStr = pStrength + 5; 1041 1042 if (*pStr == 0) 1043 { 1044 //check the |mv difference| >= 4 1045 tmp = *pmvx - *(pmvx - 8); 1046 if (tmp < 0) tmp = -tmp; 1047 if (tmp >= 4) *pStr = 1; 1048 1049 tmp = *pmvy - *(pmvy - 8); 1050 if (tmp < 0) tmp = -tmp; 1051 if (tmp >= 4) *pStr = 1; 1052 } 1053 1054 pmvx += 8; 1055 pmvy += 8; 1056 pStr = pStrength + 9; 1057 1058 if (*pStr == 0) 1059 { 1060 //within the same 8x8 block, no need to check the reference id 1061 //only need to check the |mv difference| >= 4 1062 tmp = *pmvx - *(pmvx - 8); 1063 if (tmp < 0) tmp = -tmp; 1064 if (tmp >= 4) *pStr = 1; 1065 1066 tmp = *pmvy - *(pmvy - 8); 1067 if (tmp < 0) tmp = -tmp; 1068 if (tmp >= 4) *pStr = 1; 1069 } 1070 1071 // update some variables for the next two rows 1072 pmvx -= 14; 1073 pmvy -= 14; // -14 = -16 + 2 1074 pStrength += 2; 1075 1076 } /* end of: for(idx=0; idx<2; idx++) */ 1077 1078 } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */ 1079 } 1080 1081 /* 1082 ***************************************************************************************** 1083 * \brief Filters one edge of 16 (luma) or 8 (chroma) pel 1084 ***************************************************************************************** 1085 */ 1086 1087 void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch) 1088 { 1089 int pel, ap = 0, aq = 0, Strng; 1090 int C0, c0, dif, AbsDelta, tmp, tmp1; 1091 int L2 = 0, L1, L0, R0, R1, R2 = 0, RL0; 1092 1093 1094 if (Strength[0] == 4) /* INTRA strong filtering */ 1095 { 1096 for (pel = 0; pel < 16; pel++) 1097 { 1098 R0 = SrcPtr[0]; 1099 R1 = SrcPtr[pitch]; 1100 L0 = SrcPtr[-pitch]; 1101 L1 = SrcPtr[-(pitch<<1)]; 1102 1103 // |R0 - R1| < Beta 1104 tmp1 = R0 - R1; 1105 if (tmp1 < 0) tmp1 = -tmp1; 1106 tmp = (tmp1 - Beta); 1107 1108 //|L0 - L1| < Beta 1109 tmp1 = L0 - L1; 1110 if (tmp1 < 0) tmp1 = -tmp1; 1111 tmp &= (tmp1 - Beta); 1112 1113 //|R0 - L0| < Alpha 1114 AbsDelta = R0 - L0; 1115 if (AbsDelta < 0) AbsDelta = -AbsDelta; 1116 tmp &= (AbsDelta - Alpha); 1117 1118 if (tmp < 0) 1119 { 1120 AbsDelta -= ((Alpha >> 2) + 2); 1121 R2 = SrcPtr[pitch<<1]; //inc2 1122 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3 1123 1124 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2) 1125 tmp = R0 - R2; 1126 if (tmp < 0) tmp = -tmp; 1127 aq = AbsDelta & (tmp - Beta); 1128 1129 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2) 1130 tmp = L0 - L2; 1131 if (tmp < 0) tmp = -tmp; 1132 ap = AbsDelta & (tmp - Beta); 1133 1134 if (aq < 0) 1135 { 1136 tmp = R1 + R0 + L0; 1137 SrcPtr[0] = (L1 + (tmp << 1) + R2 + 4) >> 3; 1138 tmp += R2; 1139 SrcPtr[pitch] = (tmp + 2) >> 2; 1140 SrcPtr[pitch<<1] = (((SrcPtr[(pitch+(pitch<<1))] + R2) << 1) + tmp + 4) >> 3; 1141 } 1142 else 1143 SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2; 1144 1145 if (ap < 0) 1146 { 1147 tmp = L1 + R0 + L0; 1148 SrcPtr[-pitch] = (R1 + (tmp << 1) + L2 + 4) >> 3; 1149 tmp += L2; 1150 SrcPtr[-(pitch<<1)] = (tmp + 2) >> 2; 1151 SrcPtr[-(pitch+(pitch<<1))] = (((SrcPtr[-(pitch<<2)] + L2) << 1) + tmp + 4) >> 3; 1152 } 1153 else 1154 SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2; 1155 1156 } /* if(tmp < 0) */ 1157 1158 SrcPtr ++; // Increment to next set of pixel 1159 1160 } /* end of: for(pel=0; pel<16; pel++) */ 1161 1162 } /* if(Strength[0] == 4) */ 1163 1164 else /* Normal filtering */ 1165 { 1166 for (pel = 0; pel < 16; pel++) 1167 { 1168 Strng = Strength[pel >> 2]; 1169 if (Strng) 1170 { 1171 R0 = SrcPtr[0]; 1172 R1 = SrcPtr[pitch]; 1173 L0 = SrcPtr[-pitch]; 1174 L1 = SrcPtr[-(pitch<<1)]; // inc2 1175 1176 //|R0 - L0| < Alpha 1177 tmp1 = R0 - L0; 1178 if (tmp1 < 0) tmp1 = -tmp1; 1179 tmp = (tmp1 - Alpha); 1180 1181 // |R0 - R1| < Beta 1182 tmp1 = R0 - R1; 1183 if (tmp1 < 0) tmp1 = -tmp1; 1184 tmp &= (tmp1 - Beta); 1185 1186 //|L0 - L1| < Beta 1187 tmp1 = L0 - L1; 1188 if (tmp1 < 0) tmp1 = -tmp1; 1189 tmp &= (tmp1 - Beta); 1190 1191 if (tmp < 0) 1192 { 1193 R2 = SrcPtr[pitch<<1]; //inc2 1194 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3 1195 1196 // |R0 - R2| < Beta 1197 tmp = R0 - R2; 1198 if (tmp < 0) tmp = -tmp; 1199 aq = tmp - Beta; 1200 1201 // |L0 - L2| < Beta 1202 tmp = L0 - L2; 1203 if (tmp < 0) tmp = -tmp; 1204 ap = tmp - Beta; 1205 1206 1207 c0 = C0 = clipTable[Strng]; 1208 if (ap < 0) c0++; 1209 if (aq < 0) c0++; 1210 1211 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3); 1212 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3; 1213 tmp = dif + c0; 1214 if ((uint)tmp > (uint)c0 << 1) 1215 { 1216 tmp = ~(tmp >> 31); 1217 dif = (tmp & (c0 << 1)) - c0; 1218 } 1219 1220 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif); 1221 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif); 1222 RL0 = R0 + L0; 1223 R0 -= dif; 1224 L0 += dif; 1225 if ((uint)R0 > 255) 1226 { 1227 tmp = ~(R0 >> 31); 1228 R0 = tmp & 255; 1229 } 1230 if ((uint)L0 > 255) 1231 { 1232 tmp = ~(L0 >> 31); 1233 L0 = tmp & 255; 1234 } 1235 SrcPtr[-pitch] = L0; 1236 SrcPtr[0] = R0; 1237 1238 if (C0 != 0) /* Multiple zeros in the clip tables */ 1239 { 1240 if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1); 1241 { 1242 R2 = (R2 + ((RL0 + 1) >> 1) - (R1 << 1)) >> 1; 1243 tmp = R2 + C0; 1244 if ((uint)tmp > (uint)C0 << 1) 1245 { 1246 tmp = ~(tmp >> 31); 1247 R2 = (tmp & (C0 << 1)) - C0; 1248 } 1249 SrcPtr[pitch] += R2; 1250 } 1251 1252 if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1); 1253 { 1254 L2 = (L2 + ((RL0 + 1) >> 1) - (L1 << 1)) >> 1; 1255 tmp = L2 + C0; 1256 if ((uint)tmp > (uint)C0 << 1) 1257 { 1258 tmp = ~(tmp >> 31); 1259 L2 = (tmp & (C0 << 1)) - C0; 1260 } 1261 SrcPtr[-(pitch<<1)] += L2; 1262 } 1263 } 1264 1265 } /* if(tmp < 0) */ 1266 1267 } /* end of: if((Strng = Strength[pel >> 2])) */ 1268 1269 SrcPtr ++; // Increment to next set of pixel 1270 1271 } /* for(pel=0; pel<16; pel++) */ 1272 1273 } /* else if(Strength[0] == 4) */ 1274 } 1275 1276 void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch) 1277 { 1278 int pel, ap = 1, aq = 1; 1279 int C0, c0, dif, AbsDelta, Strng, tmp, tmp1; 1280 int L2 = 0, L1, L0, R0, R1, R2 = 0; 1281 uint8 *ptr, *ptr1; 1282 register uint R_in, L_in; 1283 uint R_out, L_out; 1284 1285 1286 if (Strength[0] == 4) /* INTRA strong filtering */ 1287 { 1288 1289 for (pel = 0; pel < 16; pel++) 1290 { 1291 1292 // Read 8 pels 1293 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0} 1294 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3} 1295 R1 = (R_in >> 8) & 0xff; 1296 R0 = R_in & 0xff; 1297 L0 = L_in >> 24; 1298 L1 = (L_in >> 16) & 0xff; 1299 1300 // |R0 - R1| < Beta 1301 tmp1 = (R_in & 0xff) - R1; 1302 if (tmp1 < 0) tmp1 = -tmp1; 1303 tmp = (tmp1 - Beta); 1304 1305 1306 //|L0 - L1| < Beta 1307 tmp1 = (L_in >> 24) - L1; 1308 if (tmp1 < 0) tmp1 = -tmp1; 1309 tmp &= (tmp1 - Beta); 1310 1311 //|R0 - L0| < Alpha 1312 AbsDelta = (R_in & 0xff) - (L_in >> 24); 1313 if (AbsDelta < 0) AbsDelta = -AbsDelta; 1314 tmp &= (AbsDelta - Alpha); 1315 1316 if (tmp < 0) 1317 { 1318 AbsDelta -= ((Alpha >> 2) + 2); 1319 R2 = (R_in >> 16) & 0xff; 1320 L2 = (L_in >> 8) & 0xff; 1321 1322 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2) 1323 tmp1 = (R_in & 0xff) - R2; 1324 if (tmp1 < 0) tmp1 = -tmp1; 1325 aq = AbsDelta & (tmp1 - Beta); 1326 1327 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2) 1328 tmp1 = (L_in >> 24) - L2; 1329 if (tmp1 < 0) tmp1 = -tmp1; 1330 ap = AbsDelta & (tmp1 - Beta); 1331 1332 1333 ptr = SrcPtr; 1334 if (aq < 0) 1335 { 1336 R_out = (R_in >> 24) << 24; // Keep R3 at the fourth byte 1337 1338 tmp = R0 + L0 + R1; 1339 R_out |= (((tmp << 1) + L1 + R2 + 4) >> 3); 1340 tmp += R2; 1341 R_out |= (((tmp + 2) >> 2) << 8); 1342 tmp1 = ((R_in >> 24) + R2) << 1; 1343 R_out |= (((tmp1 + tmp + 4) >> 3) << 16); 1344 1345 *((uint *)SrcPtr) = R_out; 1346 } 1347 else 1348 *ptr = ((R1 << 1) + R0 + L1 + 2) >> 2; 1349 1350 1351 if (ap < 0) 1352 { 1353 L_out = (L_in << 24) >> 24; // Keep L3 at the first byte 1354 1355 tmp = R0 + L0 + L1; 1356 L_out |= ((((tmp << 1) + R1 + L2 + 4) >> 3) << 24); 1357 tmp += L2; 1358 L_out |= (((tmp + 2) >> 2) << 16); 1359 tmp1 = ((L_in & 0xff) + L2) << 1; 1360 L_out |= (((tmp1 + tmp + 4) >> 3) << 8); 1361 1362 *((uint *)(SrcPtr - 4)) = L_out; 1363 } 1364 else 1365 *(--ptr) = ((L1 << 1) + L0 + R1 + 2) >> 2; 1366 1367 } /* if(tmp < 0) */ 1368 1369 SrcPtr += pitch; // Increment to next set of pixel 1370 1371 } /* end of: for(pel=0; pel<16; pel++) */ 1372 1373 } /* if(Strength[0] == 4) */ 1374 1375 else /* Normal filtering */ 1376 { 1377 1378 for (pel = 0; pel < 16; pel++) 1379 { 1380 Strng = Strength[pel >> 2]; 1381 if (Strng) 1382 { 1383 // Read 8 pels 1384 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0} 1385 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3} 1386 R1 = (R_in >> 8) & 0xff; 1387 R0 = R_in & 0xff; 1388 L0 = L_in >> 24; 1389 L1 = (L_in >> 16) & 0xff; 1390 1391 //|R0 - L0| < Alpha 1392 tmp = R0 - L0; 1393 if (tmp < 0) tmp = -tmp; 1394 tmp -= Alpha; 1395 1396 // |R0 - R1| < Beta 1397 tmp1 = R0 - R1; 1398 if (tmp1 < 0) tmp1 = -tmp1; 1399 tmp &= (tmp1 - Beta); 1400 1401 //|L0 - L1| < Beta 1402 tmp1 = L0 - L1; 1403 if (tmp1 < 0) tmp1 = -tmp1; 1404 tmp &= (tmp1 - Beta); 1405 1406 if (tmp < 0) 1407 { 1408 L2 = SrcPtr[-3]; 1409 R2 = SrcPtr[2]; 1410 1411 // |R0 - R2| < Beta 1412 tmp = R0 - R2; 1413 if (tmp < 0) tmp = -tmp; 1414 aq = tmp - Beta; 1415 1416 // |L0 - L2| < Beta 1417 tmp = L0 - L2; 1418 if (tmp < 0) tmp = -tmp; 1419 ap = tmp - Beta; 1420 1421 1422 c0 = C0 = clipTable[Strng]; 1423 if (ap < 0) c0++; 1424 if (aq < 0) c0++; 1425 1426 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3); 1427 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3; 1428 tmp = dif + c0; 1429 if ((uint)tmp > (uint)c0 << 1) 1430 { 1431 tmp = ~(tmp >> 31); 1432 dif = (tmp & (c0 << 1)) - c0; 1433 } 1434 1435 ptr = SrcPtr; 1436 ptr1 = SrcPtr - 1; 1437 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif); 1438 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif); 1439 R_in = R0 - dif; 1440 L_in = L0 + dif; /* cannot re-use R0 and L0 here */ 1441 if ((uint)R_in > 255) 1442 { 1443 tmp = ~((int)R_in >> 31); 1444 R_in = tmp & 255; 1445 } 1446 if ((uint)L_in > 255) 1447 { 1448 tmp = ~((int)L_in >> 31); 1449 L_in = tmp & 255; 1450 } 1451 *ptr1-- = L_in; 1452 *ptr++ = R_in; 1453 1454 if (C0 != 0) // Multiple zeros in the clip tables 1455 { 1456 if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1); 1457 { 1458 L2 = (L2 + ((R0 + L0 + 1) >> 1) - (L1 << 1)) >> 1; 1459 tmp = L2 + C0; 1460 if ((uint)tmp > (uint)C0 << 1) 1461 { 1462 tmp = ~(tmp >> 31); 1463 L2 = (tmp & (C0 << 1)) - C0; 1464 } 1465 *ptr1 += L2; 1466 } 1467 1468 if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1); 1469 { 1470 R2 = (R2 + ((R0 + L0 + 1) >> 1) - (R1 << 1)) >> 1; 1471 tmp = R2 + C0; 1472 if ((uint)tmp > (uint)C0 << 1) 1473 { 1474 tmp = ~(tmp >> 31); 1475 R2 = (tmp & (C0 << 1)) - C0; 1476 } 1477 *ptr += R2; 1478 } 1479 } 1480 1481 } /* if(tmp < 0) */ 1482 1483 } /* end of: if((Strng = Strength[pel >> 2])) */ 1484 1485 SrcPtr += pitch; // Increment to next set of pixel 1486 1487 } /* for(pel=0; pel<16; pel++) */ 1488 1489 } /* else if(Strength[0] == 4) */ 1490 1491 } 1492 1493 void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch) 1494 { 1495 int pel, Strng; 1496 int c0, dif; 1497 int L1, L0, R0, R1, tmp, tmp1; 1498 uint8 *ptr; 1499 uint R_in, L_in; 1500 1501 1502 for (pel = 0; pel < 16; pel++) 1503 { 1504 Strng = Strength[pel>>2]; 1505 if (Strng) 1506 { 1507 // Read 8 pels 1508 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0} 1509 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3} 1510 R1 = (R_in >> 8) & 0xff; 1511 R0 = R_in & 0xff; 1512 L0 = L_in >> 24; 1513 L1 = (L_in >> 16) & 0xff; 1514 1515 // |R0 - R1| < Beta 1516 tmp1 = R0 - R1; 1517 if (tmp1 < 0) tmp1 = -tmp1; 1518 tmp = (tmp1 - Beta); 1519 1520 //|L0 - L1| < Beta 1521 tmp1 = L0 - L1; 1522 if (tmp1 < 0) tmp1 = -tmp1; 1523 tmp &= (tmp1 - Beta); 1524 1525 //|R0 - L0| < Alpha 1526 tmp1 = R0 - L0; 1527 if (tmp1 < 0) tmp1 = -tmp1; 1528 tmp &= (tmp1 - Alpha); 1529 1530 if (tmp < 0) 1531 { 1532 ptr = SrcPtr; 1533 if (Strng == 4) /* INTRA strong filtering */ 1534 { 1535 *ptr-- = ((R1 << 1) + R0 + L1 + 2) >> 2; 1536 *ptr = ((L1 << 1) + L0 + R1 + 2) >> 2; 1537 } 1538 else /* normal filtering */ 1539 { 1540 c0 = clipTable[Strng] + 1; 1541 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3); 1542 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3; 1543 tmp = dif + c0; 1544 if ((uint)tmp > (uint)c0 << 1) 1545 { 1546 tmp = ~(tmp >> 31); 1547 dif = (tmp & (c0 << 1)) - c0; 1548 } 1549 1550 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif); 1551 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif); 1552 L0 += dif; 1553 R0 -= dif; 1554 if ((uint)L0 > 255) 1555 { 1556 tmp = ~(L0 >> 31); 1557 L0 = tmp & 255; 1558 } 1559 if ((uint)R0 > 255) 1560 { 1561 tmp = ~(R0 >> 31); 1562 R0 = tmp & 255; 1563 } 1564 1565 *ptr-- = R0; 1566 *ptr = L0; 1567 } 1568 } 1569 pel ++; 1570 SrcPtr += pitch; // Increment to next set of pixel 1571 1572 } /* end of: if((Strng = Strength[pel >> 2])) */ 1573 else 1574 { 1575 pel += 3; 1576 SrcPtr += (pitch << 1); //PtrInc << 1; 1577 } 1578 1579 } /* end of: for(pel=0; pel<16; pel++) */ 1580 } 1581 1582 1583 void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch) 1584 { 1585 int pel, Strng; 1586 int c0, dif; 1587 int L1, L0, R0, R1, tmp, tmp1; 1588 1589 for (pel = 0; pel < 16; pel++) 1590 { 1591 Strng = Strength[pel>>2]; 1592 if (Strng) 1593 { 1594 R0 = SrcPtr[0]; 1595 L0 = SrcPtr[-pitch]; 1596 L1 = SrcPtr[-(pitch<<1)]; //inc2 1597 R1 = SrcPtr[pitch]; 1598 1599 // |R0 - R1| < Beta 1600 tmp1 = R0 - R1; 1601 if (tmp1 < 0) tmp1 = -tmp1; 1602 tmp = (tmp1 - Beta); 1603 1604 //|L0 - L1| < Beta 1605 tmp1 = L0 - L1; 1606 if (tmp1 < 0) tmp1 = -tmp1; 1607 tmp &= (tmp1 - Beta); 1608 1609 //|R0 - L0| < Alpha 1610 tmp1 = R0 - L0; 1611 if (tmp1 < 0) tmp1 = -tmp1; 1612 tmp &= (tmp1 - Alpha); 1613 1614 if (tmp < 0) 1615 { 1616 if (Strng == 4) /* INTRA strong filtering */ 1617 { 1618 SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2; 1619 SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2; 1620 } 1621 else /* normal filtering */ 1622 { 1623 c0 = clipTable[Strng] + 1; 1624 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3); 1625 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3; 1626 tmp = dif + c0; 1627 if ((uint)tmp > (uint)c0 << 1) 1628 { 1629 tmp = ~(tmp >> 31); 1630 dif = (tmp & (c0 << 1)) - c0; 1631 } 1632 1633 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif); 1634 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif); 1635 L0 += dif; 1636 R0 -= dif; 1637 if ((uint)L0 > 255) 1638 { 1639 tmp = ~(L0 >> 31); 1640 L0 = tmp & 255; 1641 } 1642 if ((uint)R0 > 255) 1643 { 1644 tmp = ~(R0 >> 31); 1645 R0 = tmp & 255; 1646 } 1647 SrcPtr[0] = R0; 1648 SrcPtr[-pitch] = L0; 1649 } 1650 } 1651 1652 pel ++; 1653 SrcPtr ++; // Increment to next set of pixel 1654 1655 } /* end of: if((Strng = Strength[pel >> 2])) */ 1656 else 1657 { 1658 pel += 3; 1659 SrcPtr += 2; 1660 } 1661 1662 } /* end of: for(pel=0; pel<16; pel++) */ 1663 } 1664 1665 1666 1667 1668