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 "mp4dec_lib.h" 20 21 #ifdef PV_ANNEX_IJKT_SUPPORT 22 #include "motion_comp.h" 23 #include "mbtype_mode.h" 24 const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12}; 25 #endif 26 27 #ifdef PV_POSTPROC_ON 28 /*---------------------------------------------------------------------------- 29 ; FUNCTION CODE 30 ----------------------------------------------------------------------------*/ 31 void PostFilter( 32 VideoDecData *video, 33 int filter_type, 34 uint8 *output) 35 { 36 /*---------------------------------------------------------------------------- 37 ; Define all local variables 38 ----------------------------------------------------------------------------*/ 39 uint8 *pp_mod; 40 int16 *QP_store; 41 int combined_with_deblock_filter; 42 int nTotalMB = video->nTotalMB; 43 int width, height; 44 int32 size; 45 int softDeblocking; 46 uint8 *decodedFrame = video->videoDecControls->outputFrame; 47 /*---------------------------------------------------------------------------- 48 ; Function body here 49 ----------------------------------------------------------------------------*/ 50 width = video->width; 51 height = video->height; 52 size = (int32)width * height; 53 54 oscl_memcpy(output, decodedFrame, size); 55 oscl_memcpy(output + size, decodedFrame + size, (size >> 2)); 56 oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2)); 57 58 if (filter_type == 0) 59 return; 60 61 /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip */ 62 if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12))) // MC_sofDeblock 63 softDeblocking = FALSE; 64 else 65 softDeblocking = TRUE; 66 67 combined_with_deblock_filter = filter_type & PV_DEBLOCK; 68 QP_store = video->QPMB; 69 70 /* Luma */ 71 pp_mod = video->pstprcTypCur; 72 73 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING)) 74 { 75 CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod); 76 } 77 else 78 { 79 if (filter_type & PV_DEBLOCK) 80 { 81 if (softDeblocking) 82 { 83 CombinedHorzVertFilter(output, width, height, 84 QP_store, 0, pp_mod); 85 } 86 else 87 { 88 CombinedHorzVertFilter_NoSoftDeblocking(output, width, height, 89 QP_store, 0, pp_mod); 90 } 91 } 92 if (filter_type & PV_DERING) 93 { 94 Deringing_Luma(output, width, height, QP_store, 95 combined_with_deblock_filter, pp_mod); 96 97 } 98 } 99 100 /* Chroma */ 101 102 pp_mod += (nTotalMB << 2); 103 output += size; 104 105 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING)) 106 { 107 CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod); 108 } 109 else 110 { 111 if (filter_type & PV_DEBLOCK) 112 { 113 if (softDeblocking) 114 { 115 CombinedHorzVertFilter(output, (int)(width >> 1), 116 (int)(height >> 1), QP_store, (int) 1, pp_mod); 117 } 118 else 119 { 120 CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1), 121 (int)(height >> 1), QP_store, (int) 1, pp_mod); 122 } 123 } 124 if (filter_type & PV_DERING) 125 { 126 Deringing_Chroma(output, (int)(width >> 1), 127 (int)(height >> 1), QP_store, 128 combined_with_deblock_filter, pp_mod); 129 } 130 } 131 132 pp_mod += nTotalMB; 133 output += (size >> 2); 134 135 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING)) 136 { 137 CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod); 138 } 139 else 140 { 141 if (filter_type & PV_DEBLOCK) 142 { 143 if (softDeblocking) 144 { 145 CombinedHorzVertFilter(output, (int)(width >> 1), 146 (int)(height >> 1), QP_store, (int) 1, pp_mod); 147 } 148 else 149 { 150 CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1), 151 (int)(height >> 1), QP_store, (int) 1, pp_mod); 152 } 153 } 154 if (filter_type & PV_DERING) 155 { 156 Deringing_Chroma(output, (int)(width >> 1), 157 (int)(height >> 1), QP_store, 158 combined_with_deblock_filter, pp_mod); 159 } 160 } 161 162 /* swap current pp_mod to prev_frame pp_mod */ 163 pp_mod = video->pstprcTypCur; 164 video->pstprcTypCur = video->pstprcTypPrv; 165 video->pstprcTypPrv = pp_mod; 166 167 /*---------------------------------------------------------------------------- 168 ; Return nothing or data or data pointer 169 ----------------------------------------------------------------------------*/ 170 return; 171 } 172 #endif 173 174 175 #ifdef PV_ANNEX_IJKT_SUPPORT 176 void H263_Deblock(uint8 *rec, 177 int width, 178 int height, 179 int16 *QP_store, 180 uint8 *mode, 181 int chr, int annex_T) 182 { 183 /*---------------------------------------------------------------------------- 184 ; Define all local variables 185 ----------------------------------------------------------------------------*/ 186 int i, j, k; 187 uint8 *rec_y; 188 int tmpvar; 189 int mbnum, strength, A_D, d1_2, d1, d2, A, B, C, D, b_size; 190 int d, offset, nMBPerRow, nMBPerCol, width2 = (width << 1); 191 /* MAKE SURE I-VOP INTRA MACROBLOCKS ARE SET TO NON-SKIPPED MODE*/ 192 mbnum = 0; 193 194 if (chr) 195 { 196 nMBPerRow = width >> 3; 197 nMBPerCol = height >> 3; 198 b_size = 8; 199 } 200 else 201 { 202 nMBPerRow = width >> 4; 203 nMBPerCol = height >> 4; 204 b_size = 16; 205 } 206 207 208 /********************************* VERTICAL FILTERING ****************************/ 209 /* vertical filtering of mid sections no need to check neighboring QP's etc */ 210 if (!chr) 211 { 212 rec_y = rec + (width << 3); 213 for (i = 0; i < (height >> 4); i++) 214 { 215 for (j = 0; j < (width >> 4); j++) 216 { 217 if (mode[mbnum] != MODE_SKIPPED) 218 { 219 k = 16; 220 strength = STRENGTH_tab[QP_store[mbnum]]; 221 while (k--) 222 { 223 A = *(rec_y - width2); 224 D = *(rec_y + width); 225 A_D = A - D; 226 C = *rec_y; 227 B = *(rec_y - width); 228 d = (((C - B) << 2) + A_D); 229 230 if (d < 0) 231 { 232 d1 = -(-d >> 3); 233 if (d1 < -(strength << 1)) 234 { 235 d1 = 0; 236 } 237 else if (d1 < -strength) 238 { 239 d1 = -d1 - (strength << 1); 240 } 241 d1_2 = -d1 >> 1; 242 } 243 else 244 { 245 d1 = d >> 3; 246 if (d1 > (strength << 1)) 247 { 248 d1 = 0; 249 } 250 else if (d1 > strength) 251 { 252 d1 = (strength << 1) - d1; 253 } 254 d1_2 = d1 >> 1; 255 } 256 257 if (A_D < 0) 258 { 259 d2 = -(-A_D >> 2); 260 if (d2 < -d1_2) 261 { 262 d2 = -d1_2; 263 } 264 } 265 else 266 { 267 d2 = A_D >> 2; 268 if (d2 > d1_2) 269 { 270 d2 = d1_2; 271 } 272 } 273 274 *(rec_y - width2) = A - d2; 275 tmpvar = B + d1; 276 CLIP_RESULT(tmpvar) 277 *(rec_y - width) = tmpvar; 278 tmpvar = C - d1; 279 CLIP_RESULT(tmpvar) 280 *rec_y = tmpvar; 281 *(rec_y + width) = D + d2; 282 rec_y++; 283 } 284 } 285 else 286 { 287 rec_y += b_size; 288 } 289 mbnum++; 290 } 291 rec_y += (15 * width); 292 293 } 294 } 295 296 /* VERTICAL boundary blocks */ 297 298 299 rec_y = rec + width * b_size; 300 301 mbnum = nMBPerRow; 302 for (i = 0; i < nMBPerCol - 1; i++) 303 { 304 for (j = 0; j < nMBPerRow; j++) 305 { 306 if (mode[mbnum] != MODE_SKIPPED || mode[mbnum - nMBPerRow] != MODE_SKIPPED) 307 { 308 k = b_size; 309 if (mode[mbnum] != MODE_SKIPPED) 310 { 311 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])]; 312 } 313 else 314 { 315 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - nMBPerRow]] : QP_store[mbnum - nMBPerRow])]; 316 } 317 318 while (k--) 319 { 320 A = *(rec_y - width2); 321 D = *(rec_y + width); 322 A_D = A - D; 323 C = *rec_y; 324 B = *(rec_y - width); 325 d = (((C - B) << 2) + A_D); 326 327 if (d < 0) 328 { 329 d1 = -(-d >> 3); 330 if (d1 < -(strength << 1)) 331 { 332 d1 = 0; 333 } 334 else if (d1 < -strength) 335 { 336 d1 = -d1 - (strength << 1); 337 } 338 d1_2 = -d1 >> 1; 339 } 340 else 341 { 342 d1 = d >> 3; 343 if (d1 > (strength << 1)) 344 { 345 d1 = 0; 346 } 347 else if (d1 > strength) 348 { 349 d1 = (strength << 1) - d1; 350 } 351 d1_2 = d1 >> 1; 352 } 353 354 if (A_D < 0) 355 { 356 d2 = -(-A_D >> 2); 357 if (d2 < -d1_2) 358 { 359 d2 = -d1_2; 360 } 361 } 362 else 363 { 364 d2 = A_D >> 2; 365 if (d2 > d1_2) 366 { 367 d2 = d1_2; 368 } 369 } 370 371 *(rec_y - width2) = A - d2; 372 tmpvar = B + d1; 373 CLIP_RESULT(tmpvar) 374 *(rec_y - width) = tmpvar; 375 tmpvar = C - d1; 376 CLIP_RESULT(tmpvar) 377 *rec_y = tmpvar; 378 *(rec_y + width) = D + d2; 379 rec_y++; 380 } 381 } 382 else 383 { 384 rec_y += b_size; 385 } 386 mbnum++; 387 } 388 rec_y += ((b_size - 1) * width); 389 390 } 391 392 393 /***************************HORIZONTAL FILTERING ********************************************/ 394 mbnum = 0; 395 /* HORIZONTAL INNER */ 396 if (!chr) 397 { 398 rec_y = rec + 8; 399 offset = width * b_size - b_size; 400 401 for (i = 0; i < nMBPerCol; i++) 402 { 403 for (j = 0; j < nMBPerRow; j++) 404 { 405 if (mode[mbnum] != MODE_SKIPPED) 406 { 407 k = 16; 408 strength = STRENGTH_tab[QP_store[mbnum]]; 409 while (k--) 410 { 411 A = *(rec_y - 2); 412 D = *(rec_y + 1); 413 A_D = A - D; 414 C = *rec_y; 415 B = *(rec_y - 1); 416 d = (((C - B) << 2) + A_D); 417 418 if (d < 0) 419 { 420 d1 = -(-d >> 3); 421 if (d1 < -(strength << 1)) 422 { 423 d1 = 0; 424 } 425 else if (d1 < -strength) 426 { 427 d1 = -d1 - (strength << 1); 428 } 429 d1_2 = -d1 >> 1; 430 } 431 else 432 { 433 d1 = d >> 3; 434 if (d1 > (strength << 1)) 435 { 436 d1 = 0; 437 } 438 else if (d1 > strength) 439 { 440 d1 = (strength << 1) - d1; 441 } 442 d1_2 = d1 >> 1; 443 } 444 445 if (A_D < 0) 446 { 447 d2 = -(-A_D >> 2); 448 if (d2 < -d1_2) 449 { 450 d2 = -d1_2; 451 } 452 } 453 else 454 { 455 d2 = A_D >> 2; 456 if (d2 > d1_2) 457 { 458 d2 = d1_2; 459 } 460 } 461 462 *(rec_y - 2) = A - d2; 463 tmpvar = B + d1; 464 CLIP_RESULT(tmpvar) 465 *(rec_y - 1) = tmpvar; 466 tmpvar = C - d1; 467 CLIP_RESULT(tmpvar) 468 *rec_y = tmpvar; 469 *(rec_y + 1) = D + d2; 470 rec_y += width; 471 } 472 rec_y -= offset; 473 } 474 else 475 { 476 rec_y += b_size; 477 } 478 mbnum++; 479 } 480 rec_y += (15 * width); 481 482 } 483 } 484 485 486 487 /* HORIZONTAL EDGE */ 488 rec_y = rec + b_size; 489 offset = width * b_size - b_size; 490 mbnum = 1; 491 for (i = 0; i < nMBPerCol; i++) 492 { 493 for (j = 0; j < nMBPerRow - 1; j++) 494 { 495 if (mode[mbnum] != MODE_SKIPPED || mode[mbnum-1] != MODE_SKIPPED) 496 { 497 k = b_size; 498 if (mode[mbnum] != MODE_SKIPPED) 499 { 500 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])]; 501 } 502 else 503 { 504 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - 1]] : QP_store[mbnum - 1])]; 505 } 506 507 while (k--) 508 { 509 A = *(rec_y - 2); 510 D = *(rec_y + 1); 511 A_D = A - D; 512 C = *rec_y; 513 B = *(rec_y - 1); 514 d = (((C - B) << 2) + A_D); 515 516 if (d < 0) 517 { 518 d1 = -(-d >> 3); 519 if (d1 < -(strength << 1)) 520 { 521 d1 = 0; 522 } 523 else if (d1 < -strength) 524 { 525 d1 = -d1 - (strength << 1); 526 } 527 d1_2 = -d1 >> 1; 528 } 529 else 530 { 531 d1 = d >> 3; 532 if (d1 > (strength << 1)) 533 { 534 d1 = 0; 535 } 536 else if (d1 > strength) 537 { 538 d1 = (strength << 1) - d1; 539 } 540 d1_2 = d1 >> 1; 541 } 542 543 if (A_D < 0) 544 { 545 d2 = -(-A_D >> 2); 546 if (d2 < -d1_2) 547 { 548 d2 = -d1_2; 549 } 550 } 551 else 552 { 553 d2 = A_D >> 2; 554 if (d2 > d1_2) 555 { 556 d2 = d1_2; 557 } 558 } 559 560 *(rec_y - 2) = A - d2; 561 tmpvar = B + d1; 562 CLIP_RESULT(tmpvar) 563 *(rec_y - 1) = tmpvar; 564 tmpvar = C - d1; 565 CLIP_RESULT(tmpvar) 566 *rec_y = tmpvar; 567 *(rec_y + 1) = D + d2; 568 rec_y += width; 569 } 570 rec_y -= offset; 571 } 572 else 573 { 574 rec_y += b_size; 575 } 576 mbnum++; 577 } 578 rec_y += ((width * (b_size - 1)) + b_size); 579 mbnum++; 580 } 581 582 return; 583 } 584 #endif 585 586