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 "vlc_decode.h" 20 #include "bitstream.h" 21 #include "scaling.h" 22 #include "mbtype_mode.h" 23 #include "idct.h" 24 25 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT 26 /* ======================================================================== */ 27 /* Function : DecodeFrameDataPartMode() */ 28 /* Purpose : Decode a frame of MPEG4 bitstream in datapartitioning mode. */ 29 /* In/out : */ 30 /* Return : */ 31 /* Modified : */ 32 /* */ 33 /* 04/25/2000 : Rewrite the data partitioning path completely */ 34 /* according to the pseudo codes in MPEG-4 */ 35 /* standard. */ 36 /* Modified : 09/18/2000 add fast VlcDecode+Dequant */ 37 /* 04/17/2001 cleanup */ 38 /* ======================================================================== */ 39 PV_STATUS DecodeFrameDataPartMode(VideoDecData *video) 40 { 41 PV_STATUS status; 42 Vop *currVop = video->currVop; 43 BitstreamDecVideo *stream = video->bitstream; 44 45 int nMBPerRow = video->nMBPerRow; 46 47 int vopType = currVop->predictionType; 48 int mbnum; 49 int nTotalMB = video->nTotalMB; 50 int slice_counter; 51 int resync_marker_length; 52 53 /* copy and pad to prev_Vop for INTER coding */ 54 switch (vopType) 55 { 56 case I_VOP : 57 // oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB); 58 resync_marker_length = 17; 59 break; 60 case P_VOP : 61 oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB); 62 oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB); 63 // oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB); 64 resync_marker_length = 16 + currVop->fcodeForward; 65 break; 66 default : 67 mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n"); 68 return PV_FAIL; 69 } 70 71 /** Initialize sliceNo ***/ 72 mbnum = slice_counter = 0; 73 // oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB); 74 75 do 76 { 77 /* This section is equivalent to motion_shape_texture() */ 78 /* in the MPEG-4 standard. 04/13/2000 */ 79 video->mbnum = mbnum; 80 video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */ 81 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 82 83 switch (vopType) 84 { 85 case I_VOP : 86 status = DecodeDataPart_I_VideoPacket(video, slice_counter); 87 break; 88 89 case P_VOP : 90 status = DecodeDataPart_P_VideoPacket(video, slice_counter); 91 break; 92 93 default : 94 mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n"); 95 return PV_FAIL; 96 } 97 98 while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL) 99 { 100 if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS) 101 { 102 break; 103 } 104 } 105 106 if (status == PV_END_OF_VOP) 107 { 108 mbnum = nTotalMB; 109 } 110 111 if (mbnum > video->mbnum + 1) 112 { 113 ConcealPacket(video, video->mbnum, mbnum, slice_counter); 114 } 115 slice_counter++; 116 if (mbnum >= nTotalMB) 117 { 118 break; 119 } 120 121 122 } 123 while (TRUE); 124 125 return PV_SUCCESS; 126 } 127 128 129 /* ======================================================================== */ 130 /* Function : DecodeDataPart_I_VideoPacket() */ 131 /* Date : 04/25/2000 */ 132 /* Purpose : Decode Data Partitioned Mode Video Packet in I-VOP */ 133 /* In/out : */ 134 /* Return : PV_SUCCESS if successed, PV_FAIL if failed. */ 135 /* Modified : 09/18/2000 add fast VlcDecode+Dequant */ 136 /* 04/01/2001 fixed MB_stuffing, removed unnecessary code */ 137 /* ======================================================================== */ 138 PV_STATUS DecodeDataPart_I_VideoPacket(VideoDecData *video, int slice_counter) 139 { 140 PV_STATUS status; 141 uint8 *Mode = video->headerInfo.Mode; 142 BitstreamDecVideo *stream = video->bitstream; 143 int nTotalMB = video->nTotalMB; 144 int mbnum, mb_start, mb_end; 145 int16 QP, *QPMB = video->QPMB; 146 int MBtype, MCBPC, CBPY; 147 uint32 tmpvar; 148 uint code; 149 int nMBPerRow = video->nMBPerRow; 150 Bool valid_stuffing; 151 int32 startSecondPart, startFirstPart = getPointer(stream); 152 153 /* decode the first partition */ 154 QP = video->currVop->quantizer; 155 mb_start = mbnum = video->mbnum; 156 video->usePrevQP = 0; /* 04/27/01 */ 157 158 159 BitstreamShowBits16(stream, 9, &code); 160 while (code == 1) 161 { 162 PV_BitstreamFlushBits(stream, 9); 163 BitstreamShowBits16(stream, 9, &code); 164 } 165 166 do 167 { 168 /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */ 169 MCBPC = PV_VlcDecMCBPC_com_intra(stream); 170 171 if (!VLC_ERROR_DETECTED(MCBPC)) 172 { 173 Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]); 174 video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3); 175 status = GetMBheaderDataPart_DQUANT_DC(video, &QP); 176 video->usePrevQP = 1; /* set it after the first coded MB 04/27/01 */ 177 } 178 else 179 { 180 /* Report the error to the application. 06/20/2000 */ 181 VideoDecoderErrorDetected(video); 182 video->mbnum = mb_start; 183 movePointerTo(stream, startFirstPart); 184 return PV_FAIL; 185 } 186 187 video->sliceNo[mbnum] = (uint8) slice_counter; 188 QPMB[mbnum] = QP; 189 video->mbnum = ++mbnum; 190 191 BitstreamShowBits16(stream, 9, &code); 192 while (code == 1) 193 { 194 PV_BitstreamFlushBits(stream, 9); 195 BitstreamShowBits16(stream, 9, &code); 196 } 197 /* have we reached the end of the video packet or vop? */ 198 status = BitstreamShowBits32(stream, DC_MARKER_LENGTH, &tmpvar); 199 200 } 201 while (tmpvar != DC_MARKER && video->mbnum < nTotalMB); 202 203 if (tmpvar == DC_MARKER) 204 { 205 PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH); 206 } 207 else 208 { 209 status = quickSearchDCM(stream); 210 if (status == PV_SUCCESS) 211 { 212 /* only way you can end up being here is in the last packet,and there is stuffing at 213 the end of the first partition */ 214 PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH); 215 } 216 else 217 { 218 /* Report the error to the application. 06/20/2000 */ 219 VideoDecoderErrorDetected(video); 220 movePointerTo(stream, startFirstPart); 221 video->mbnum = mb_start; 222 /* concealment will be taken care of in the upper layer */ 223 return PV_FAIL; 224 } 225 } 226 227 /* decode the second partition */ 228 startSecondPart = getPointer(stream); 229 230 mb_end = video->mbnum; 231 232 for (mbnum = mb_start; mbnum < mb_end; mbnum++) 233 { 234 MBtype = Mode[mbnum]; 235 /* No skipped mode in I-packets 3/1/2001 */ 236 video->mbnum = mbnum; 237 238 video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */ 239 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 240 /* there is always acdcpred in DataPart mode 04/10/01 */ 241 video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream); 242 243 CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* MODE_INTRA || MODE_INTRA_Q */ 244 if (CBPY < 0) 245 { 246 /* Report the error to the application. 06/20/2000 */ 247 VideoDecoderErrorDetected(video); 248 movePointerTo(stream, startSecondPart); /* */ 249 /* Conceal packet, 05/15/2000 */ 250 ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter); 251 return PV_FAIL; 252 } 253 254 video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2); 255 } 256 257 video->usePrevQP = 0; 258 259 for (mbnum = mb_start; mbnum < mb_end; mbnum++) 260 { 261 video->mbnum = mbnum; 262 263 video->mbnum_row = PV_GET_ROW(mbnum , nMBPerRow); /* This is needed if nbnum is read from the packet header */ 264 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 265 /* No skipped mode in I-packets 3/1/2001 */ 266 /* decode the DCT coeficients for the MB */ 267 status = GetMBData_DataPart(video); 268 if (status != PV_SUCCESS) 269 { 270 /* Report the error to the application. 06/20/2000 */ 271 VideoDecoderErrorDetected(video); 272 movePointerTo(stream, startSecondPart); /* */ 273 /* Conceal packet, 05/15/2000 */ 274 ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter); 275 return status; 276 } 277 video->usePrevQP = 1; /* 04/27/01 should be set after decoding first MB */ 278 } 279 280 valid_stuffing = validStuffing(stream); 281 if (!valid_stuffing) 282 { 283 VideoDecoderErrorDetected(video); 284 movePointerTo(stream, startSecondPart); 285 ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter); 286 return PV_FAIL; 287 } 288 return PV_SUCCESS; 289 } 290 291 292 /* ======================================================================== */ 293 /* Function : DecodeDataPart_P_VideoPacket() */ 294 /* Date : 04/25/2000 */ 295 /* Purpose : Decode Data Partitioned Mode Video Packet in P-VOP */ 296 /* In/out : */ 297 /* Return : PV_SUCCESS if successed, PV_FAIL if failed. */ 298 /* Modified : 09/18/2000, fast VlcDecode+Dequant */ 299 /* 04/13/2001, fixed MB_stuffing, new ACDC pred structure, */ 300 /* cleanup */ 301 /* 08/07/2001, remove MBzero */ 302 /* ======================================================================== */ 303 PV_STATUS DecodeDataPart_P_VideoPacket(VideoDecData *video, int slice_counter) 304 { 305 PV_STATUS status; 306 uint8 *Mode = video->headerInfo.Mode; 307 BitstreamDecVideo *stream = video->bitstream; 308 int nTotalMB = video->nTotalMB; 309 int mbnum, mb_start, mb_end; 310 int16 QP, *QPMB = video->QPMB; 311 int MBtype, CBPY; 312 Bool valid_stuffing; 313 int intra_MB; 314 uint32 tmpvar; 315 uint code; 316 int32 startFirstPart, startSecondPart; 317 int nMBPerRow = video->nMBPerRow; 318 uint8 *pbyte; 319 /* decode the first partition */ 320 startFirstPart = getPointer(stream); 321 mb_start = video->mbnum; 322 video->usePrevQP = 0; /* 04/27/01 */ 323 324 BitstreamShowBits16(stream, 10, &code); 325 while (code == 1) 326 { 327 PV_BitstreamFlushBits(stream, 10); 328 BitstreamShowBits16(stream, 10, &code); 329 } 330 331 do 332 { 333 /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */ 334 /* We have to discard stuffed MB header */ 335 336 status = GetMBheaderDataPart_P(video); 337 338 if (status != PV_SUCCESS) 339 { 340 /* Report the error to the application. 06/20/2000 */ 341 VideoDecoderErrorDetected(video); 342 movePointerTo(stream, startFirstPart); 343 video->mbnum = mb_start; 344 return PV_FAIL; 345 } 346 347 /* we must update slice_counter before motion vector decoding. */ 348 video->sliceNo[video->mbnum] = (uint8) slice_counter; 349 350 if (Mode[video->mbnum] & INTER_MASK) /* INTER || INTER_Q || INTER_4V */ 351 { 352 /* decode the motion vector (if there are any) */ 353 status = PV_GetMBvectors(video, Mode[video->mbnum]); 354 if (status != PV_SUCCESS) 355 { 356 /* Report the error to the application. 06/20/2000 */ 357 VideoDecoderErrorDetected(video); 358 movePointerTo(stream, startFirstPart); 359 video->mbnum = mb_start; 360 return PV_FAIL; 361 } 362 } 363 video->mbnum++; 364 365 video->mbnum_row = PV_GET_ROW(video->mbnum, nMBPerRow); /* This is needed if mbnum is read from the packet header */ 366 video->mbnum_col = video->mbnum - video->mbnum_row * nMBPerRow; 367 368 BitstreamShowBits16(stream, 10, &code); 369 while (code == 1) 370 { 371 PV_BitstreamFlushBits(stream, 10); 372 BitstreamShowBits16(stream, 10, &code); 373 } 374 /* have we reached the end of the video packet or vop? */ 375 status = BitstreamShowBits32(stream, MOTION_MARKER_COMB_LENGTH, &tmpvar); 376 /* if (status != PV_SUCCESS && status != PV_END_OF_BUFFER) return status; */ 377 } 378 while (tmpvar != MOTION_MARKER_COMB && video->mbnum < nTotalMB); 379 380 if (tmpvar == MOTION_MARKER_COMB) 381 { 382 PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH); 383 } 384 else 385 { 386 status = quickSearchMotionMarker(stream); 387 if (status == PV_SUCCESS) 388 { 389 /* only way you can end up being here is in the last packet,and there is stuffing at 390 the end of the first partition */ 391 PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH); 392 } 393 else 394 { 395 /* Report the error to the application. 06/20/2000 */ 396 VideoDecoderErrorDetected(video); 397 movePointerTo(stream, startFirstPart); 398 video->mbnum = mb_start; 399 /* concealment will be taken care of in the upper layer */ 400 return PV_FAIL; 401 } 402 } 403 404 /* decode the second partition */ 405 startSecondPart = getPointer(stream); 406 QP = video->currVop->quantizer; 407 408 mb_end = video->mbnum; 409 410 for (mbnum = mb_start; mbnum < mb_end; mbnum++) 411 { 412 MBtype = Mode[mbnum]; 413 414 if (MBtype == MODE_SKIPPED) 415 { 416 QPMB[mbnum] = QP; /* 03/01/01 */ 417 continue; 418 } 419 intra_MB = (MBtype & INTRA_MASK); /* (MBtype == MODE_INTRA || MBtype == MODE_INTRA_Q) */ 420 video->mbnum = mbnum; 421 video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */ 422 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 423 424 /* there is always acdcprediction in DataPart mode 04/10/01 */ 425 if (intra_MB) 426 { 427 video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream); 428 } 429 430 CBPY = PV_VlcDecCBPY(stream, intra_MB); 431 if (CBPY < 0) 432 { 433 /* Report the error to the application. 06/20/2000 */ 434 VideoDecoderErrorDetected(video); 435 /* Conceal second partition, 5/15/2000 */ 436 movePointerTo(stream, startSecondPart); 437 ConcealTexture_P(video, mb_start, mb_end, slice_counter); 438 return PV_FAIL; 439 } 440 441 video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2); 442 if (intra_MB || MBtype == MODE_INTER_Q) /* 04/26/01 */ 443 { 444 status = GetMBheaderDataPart_DQUANT_DC(video, &QP); 445 if (status != PV_SUCCESS) return status; 446 } 447 video->usePrevQP = 1; /* 04/27/01 */ 448 QPMB[mbnum] = QP; 449 } 450 451 video->usePrevQP = 0; /* 04/27/01 */ 452 453 for (mbnum = mb_start; mbnum < mb_end; mbnum++) 454 { 455 video->mbnum = mbnum; 456 video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */ 457 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 458 459 460 if (Mode[mbnum] != MODE_SKIPPED) 461 { 462 /* decode the DCT coeficients for the MB */ 463 status = GetMBData_DataPart(video); 464 if (status != PV_SUCCESS) 465 { 466 /* Report the error to the application. 06/20/2000 */ 467 VideoDecoderErrorDetected(video); 468 469 /* Conceal second partition, 5/15/2000 */ 470 movePointerTo(stream, startSecondPart); 471 ConcealTexture_P(video, mb_start, mb_end, slice_counter); 472 return status; 473 } 474 video->usePrevQP = 1; /* 04/27/01 */ 475 } 476 else 477 { // SKIPPED 478 479 /* Motion compensation and put it to video->mblock->pred_block */ 480 SkippedMBMotionComp(video); 481 482 //oscl_memset(video->predDCAC_row + video->mbnum_col, 0, sizeof(typeDCACStore)); /* SKIPPED_ACDC */ 483 //oscl_memset(video->predDCAC_col, 0, sizeof(typeDCACStore)); 484 /* 08/08/2005 */ 485 pbyte = (uint8*)(video->predDCAC_row + video->mbnum_col); 486 ZERO_OUT_64BYTES(pbyte); 487 pbyte = (uint8*)(video->predDCAC_col); 488 ZERO_OUT_64BYTES(pbyte); 489 490 } 491 } 492 493 valid_stuffing = validStuffing(stream); /* */ 494 if (!valid_stuffing) 495 { 496 VideoDecoderErrorDetected(video); 497 movePointerTo(stream, startSecondPart); /* */ 498 ConcealTexture_P(video, mb_start, mb_end, slice_counter); 499 500 return PV_FAIL; 501 } 502 return PV_SUCCESS; 503 } 504 505 506 /* ======================================================================== */ 507 /* Function : GetMBheaderDataPart_DQUANT_DC() */ 508 /* Date : 04/26/2000 */ 509 /* Purpose : Decode DQUANT and DC in Data Partitioned Mode for both */ 510 /* I-VOP and P-VOP. */ 511 /* In/out : */ 512 /* Return : PV_SUCCESS if successed, PV_FAIL if failed. */ 513 /* Modified : 02/13/2001 new ACDC prediction structure, */ 514 /* cleanup */ 515 /* ======================================================================== */ 516 PV_STATUS GetMBheaderDataPart_DQUANT_DC(VideoDecData *video, int16 *QP) 517 { 518 PV_STATUS status = PV_SUCCESS; 519 BitstreamDecVideo *stream = video->bitstream; 520 int mbnum = video->mbnum; 521 int intra_dc_vlc_thr = video->currVop->intraDCVlcThr; 522 uint8 *Mode = video->headerInfo.Mode; 523 int MBtype = Mode[mbnum]; 524 typeDCStore *DC = video->predDC + mbnum; 525 int comp; 526 Bool switched; 527 uint DQUANT; 528 int16 QP_tmp; 529 530 const static int DQ_tab[4] = { -1, -2, 1, 2}; 531 532 if (MBtype & Q_MASK) /* INTRA_Q || INTER_Q */ 533 { 534 DQUANT = BitstreamReadBits16(stream, 2); 535 *QP += DQ_tab[DQUANT]; 536 537 if (*QP < 1) *QP = 1; 538 else if (*QP > 31) *QP = 31; 539 } 540 if (MBtype & INTRA_MASK) /* INTRA || INTRA_Q */ /* no switch, code DC separately */ 541 { 542 QP_tmp = *QP; /* running QP 04/26/01*/ 543 switched = 0; 544 if (intra_dc_vlc_thr) /* 04/27/01 */ 545 { 546 if (video->usePrevQP) 547 QP_tmp = video->QPMB[mbnum-1]; 548 switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11); 549 } 550 if (!switched) 551 { 552 for (comp = 0; comp < 6; comp++) 553 { 554 status = PV_DecodePredictedIntraDC(comp, stream, (*DC + comp)); /* 03/01/01 */ 555 if (status != PV_SUCCESS) return PV_FAIL; 556 } 557 } 558 else 559 { 560 for (comp = 0; comp < 6; comp++) 561 { 562 (*DC)[comp] = 0; /* 04/26/01 needed for switched case*/ 563 } 564 } 565 } 566 return status; 567 } 568 569 570 /***********************************************************CommentBegin****** 571 * 04/25/2000 : Initial modification to the new PV Lib format. 572 * 04/17/2001 : new ACDC pred structure 573 ***********************************************************CommentEnd********/ 574 PV_STATUS GetMBheaderDataPart_P(VideoDecData *video) 575 { 576 BitstreamDecVideo *stream = video->bitstream; 577 int mbnum = video->mbnum; 578 uint8 *Mode = video->headerInfo.Mode; 579 typeDCStore *DC = video->predDC + mbnum; 580 uint no_dct_flag; 581 int comp; 582 int MCBPC; 583 584 no_dct_flag = BitstreamRead1Bits_INLINE(stream); 585 586 if (no_dct_flag) 587 { 588 /* skipped macroblock */ 589 Mode[mbnum] = MODE_SKIPPED; 590 591 for (comp = 0; comp < 6; comp++) 592 { 593 (*DC)[comp] = mid_gray; 594 /* ACDC REMOVE AC coefs are set in DecodeDataPart_P */ 595 } 596 } 597 else 598 { 599 /* coded macroblock */ 600 MCBPC = PV_VlcDecMCBPC_com_inter(stream); 601 602 if (VLC_ERROR_DETECTED(MCBPC)) 603 { 604 return PV_FAIL; 605 } 606 607 Mode[mbnum] = (uint8)MBtype_mode[MCBPC & 7]; 608 video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3); 609 } 610 611 return PV_SUCCESS; 612 } 613 614 615 /***********************************************************CommentBegin****** 616 * 04/17/01 new ACDC pred structure, reorganized code, cleanup 617 ***********************************************************CommentEnd********/ 618 PV_STATUS GetMBData_DataPart(VideoDecData *video) 619 { 620 int mbnum = video->mbnum; 621 int16 *dataBlock; 622 MacroBlock *mblock = video->mblock; 623 int QP = video->QPMB[mbnum]; 624 int32 offset; 625 PIXEL *c_comp; 626 int width = video->width; 627 int intra_dc_vlc_thr = video->currVop->intraDCVlcThr; 628 uint CBP = video->headerInfo.CBP[mbnum]; 629 uint8 mode = video->headerInfo.Mode[mbnum]; 630 int x_pos = video->mbnum_col; 631 typeDCStore *DC = video->predDC + mbnum; 632 int ncoeffs[6], *no_coeff = mblock->no_coeff; 633 int comp; 634 Bool switched; 635 int QP_tmp = QP; 636 637 int y_pos = video->mbnum_row; 638 #ifdef PV_POSTPROC_ON 639 uint8 *pp_mod[6]; 640 int TotalMB = video->nTotalMB; 641 int MB_in_width = video->nMBPerRow; 642 #endif 643 644 645 646 /***** 647 * Decoding of the 6 blocks (depending on transparent pattern) 648 *****/ 649 #ifdef PV_POSTPROC_ON 650 if (video->postFilterType != PV_NO_POST_PROC) 651 { 652 /** post-processing ***/ 653 pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1); 654 pp_mod[1] = pp_mod[0] + 1; 655 pp_mod[2] = pp_mod[0] + (MB_in_width << 1); 656 pp_mod[3] = pp_mod[2] + 1; 657 pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum; 658 pp_mod[5] = pp_mod[4] + TotalMB; 659 } 660 #endif 661 662 /* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */ 663 664 if (mode & INTRA_MASK) /* MODE_INTRA || mode == MODE_INTRA_Q */ 665 { 666 switched = 0; 667 if (intra_dc_vlc_thr) 668 { 669 if (video->usePrevQP) 670 QP_tmp = video->QPMB[mbnum-1]; /* running QP 04/26/01 */ 671 672 switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11); 673 } 674 675 mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE); /* ACDC 03/01/01 */ 676 mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE); 677 678 for (comp = 0; comp < 6; comp++) 679 { 680 dataBlock = mblock->block[comp]; /*, 10/20/2000 */ 681 682 dataBlock[0] = (*DC)[comp]; 683 684 ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp, 685 switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 686 687 if (VLC_ERROR_DETECTED(ncoeffs[comp])) /* */ 688 { 689 if (switched) 690 return PV_FAIL; 691 else 692 { 693 ncoeffs[comp] = 1; 694 oscl_memset((dataBlock + 1), 0, sizeof(int16)*63); 695 } 696 } 697 no_coeff[comp] = ncoeffs[comp]; 698 /* modified to new semaphore for post-proc */ 699 // Future work:: can be combined in the dequant function 700 // @todo Deblocking Semaphore for INTRA block 701 #ifdef PV_POSTPROC_ON 702 if (video->postFilterType != PV_NO_POST_PROC) 703 *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock); 704 #endif 705 } 706 MBlockIDCT(video); 707 } 708 else /* MODE INTER*/ 709 { 710 711 712 713 714 MBMotionComp(video, CBP); 715 offset = (int32)(y_pos << 4) * width + (x_pos << 4); 716 c_comp = video->currVop->yChan + offset; 717 718 719 for (comp = 0; comp < 4; comp++) 720 { 721 (*DC)[comp] = mid_gray; 722 723 if (CBP & (1 << (5 - comp))) 724 { 725 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, 726 mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 727 if (VLC_ERROR_DETECTED(ncoeffs[comp])) 728 return PV_FAIL; 729 730 731 BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp], 732 mblock->bitmapcol[comp], mblock->bitmaprow[comp]); 733 734 } 735 else 736 { 737 ncoeffs[comp] = 0; 738 } 739 740 /* @todo Deblocking Semaphore for INTRA block, for inter just test for ringing */ 741 #ifdef PV_POSTPROC_ON 742 if (video->postFilterType != PV_NO_POST_PROC) 743 *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0); 744 #endif 745 } 746 747 (*DC)[4] = mid_gray; 748 if (CBP & 2) 749 { 750 ncoeffs[4] = VlcDequantH263InterBlock(video, 4, 751 mblock->bitmapcol[4], &mblock->bitmaprow[4]); 752 if (VLC_ERROR_DETECTED(ncoeffs[4])) 753 return PV_FAIL; 754 755 BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4], 756 mblock->bitmapcol[4], mblock->bitmaprow[4]); 757 758 } 759 else 760 { 761 ncoeffs[4] = 0; 762 } 763 #ifdef PV_POSTPROC_ON 764 if (video->postFilterType != PV_NO_POST_PROC) 765 *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0); 766 #endif 767 (*DC)[5] = mid_gray; 768 if (CBP & 1) 769 { 770 ncoeffs[5] = VlcDequantH263InterBlock(video, 5, 771 mblock->bitmapcol[5], &mblock->bitmaprow[5]); 772 if (VLC_ERROR_DETECTED(ncoeffs[5])) 773 return PV_FAIL; 774 775 BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5], 776 mblock->bitmapcol[5], mblock->bitmaprow[5]); 777 778 } 779 else 780 { 781 ncoeffs[5] = 0; 782 } 783 #ifdef PV_POSTPROC_ON 784 if (video->postFilterType != PV_NO_POST_PROC) 785 *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0); 786 #endif 787 788 789 790 791 /* Motion compensation and put it to video->mblock->pred_block */ 792 } 793 return PV_SUCCESS; 794 } 795