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" /* video decoder function prototypes */ 19 #include "vlc_decode.h" 20 #include "bitstream.h" 21 #include "scaling.h" 22 #include "mbtype_mode.h" 23 24 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT 25 /* ======================================================================== */ 26 /* Function : DecodeFrameCombinedMode() */ 27 /* Purpose : Decode a frame of MPEG4 bitstream in combined mode. */ 28 /* In/out : */ 29 /* Return : */ 30 /* Modified : */ 31 /* */ 32 /* 03/30/2000 : Cleaned up and optimized the code. */ 33 /* 03/31/2000 : Added proper handling of MB stuffing. */ 34 /* 04/13/2000 : Rewrote this combined mode path completely */ 35 /* so that it handles "Combined Mode With Error */ 36 /* Resilience." Now the code resembles the */ 37 /* pseudo codes in MPEG-4 standard better. */ 38 /* 10/13/2000 : Add fast VLC+dequant */ 39 /* 04/13/2001 : fix MB_stuffing */ 40 /* 08/07/2001 : remove MBzero */ 41 /* ======================================================================== */ 42 PV_STATUS DecodeFrameCombinedMode(VideoDecData *video) 43 { 44 PV_STATUS status; 45 int mbnum; 46 Vop *currVop = video->currVop; 47 BitstreamDecVideo *stream = video->bitstream; 48 int shortVideoHeader = video->shortVideoHeader; 49 int16 QP, *QPMB = video->QPMB; 50 uint8 *Mode = video->headerInfo.Mode; 51 int nTotalMB = video->nTotalMB; 52 int nMBPerRow = video->nMBPerRow; 53 int slice_counter; 54 uint32 tmpvar, long_zero_bits; 55 uint code; 56 int valid_stuffing; 57 int resync_marker_length; 58 int stuffing_length; 59 60 /* add this for error resilient, 05/18/2000 */ 61 int32 startPacket; 62 int mb_start; 63 /* copy and pad to prev_Vop for INTER coding */ 64 switch (currVop->predictionType) 65 { 66 case I_VOP : 67 // oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB); 68 resync_marker_length = 17; 69 stuffing_length = 9; 70 break; 71 case P_VOP : 72 oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB); 73 oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB); 74 // oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB); 75 resync_marker_length = 16 + currVop->fcodeForward; 76 stuffing_length = 10; 77 break; 78 default : 79 mp4dec_log("DecodeFrameCombinedMode(): Vop type not supported.\n"); 80 return PV_FAIL; 81 } 82 #ifdef PV_ANNEX_IJKT_SUPPORT 83 if (video->shortVideoHeader) 84 { 85 if (video->advanced_INTRA) 86 { 87 if (video->modified_quant) 88 { 89 video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexIT; 90 video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader_AnnexT; 91 } 92 else 93 { 94 video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexI; 95 video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader; 96 } 97 } 98 else 99 { 100 if (video->modified_quant) 101 { 102 video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexT; 103 } 104 else 105 { 106 video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader; 107 } 108 } 109 } 110 111 #endif 112 113 /** Initialize sliceNo ***/ 114 mbnum = slice_counter = 0; 115 // oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB); 116 QP = video->currVop->quantizer; 117 118 do 119 { 120 /* This section is equivalent to motion_shape_texture() */ 121 /* in the MPEG-4 standard. 04/13/2000 */ 122 mb_start = mbnum; 123 video->usePrevQP = 0; /* 04/27/01 */ 124 startPacket = getPointer(stream); 125 126 #ifdef PV_ANNEX_IJKT_SUPPORT 127 if (video->modified_quant) 128 { 129 video->QP_CHR = MQ_chroma_QP_table[QP]; 130 } 131 else 132 { 133 video->QP_CHR = QP; /* ANNEX_T */ 134 } 135 #endif 136 /* remove any stuffing bits */ 137 BitstreamShowBits16(stream, stuffing_length, &code); 138 while (code == 1) 139 { 140 PV_BitstreamFlushBits(stream, stuffing_length); 141 BitstreamShowBits16(stream, stuffing_length, &code); 142 } 143 144 do 145 { 146 /* we need video->mbnum in lower level functions */ 147 video->mbnum = mbnum; 148 video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); 149 video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow; 150 /* assign slice number for each macroblocks */ 151 video->sliceNo[mbnum] = (uint8) slice_counter; 152 153 /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */ 154 /* We have to discard stuffed MB header */ 155 status = GetMBheader(video, &QP); 156 157 if (status != PV_SUCCESS) 158 { 159 VideoDecoderErrorDetected(video); 160 video->mbnum = mb_start; 161 movePointerTo(stream, (startPacket & -8)); 162 break; 163 } 164 165 /* Store the QP value for later use in AC prediction */ 166 QPMB[mbnum] = QP; 167 168 if (Mode[mbnum] != MODE_SKIPPED) 169 { 170 /* decode the DCT coeficients for the MB */ 171 status = GetMBData(video); 172 if (status != PV_SUCCESS) 173 { 174 VideoDecoderErrorDetected(video); 175 video->mbnum = mb_start; 176 movePointerTo(stream, (startPacket & -8)); 177 break; 178 } 179 } 180 else /* MODE_SKIPPED */ 181 { 182 SkippedMBMotionComp(video); /* 08/04/05 */ 183 } 184 // Motion compensation and put video->mblock->pred_block 185 mbnum++; 186 187 /* remove any stuffing bits */ 188 BitstreamShowBits16(stream, stuffing_length, &code); 189 while (code == 1) 190 { 191 PV_BitstreamFlushBits(stream, stuffing_length); 192 BitstreamShowBits16(stream, stuffing_length, &code); 193 } 194 195 /* have we reached the end of the video packet or vop? */ 196 if (shortVideoHeader) 197 { 198 #ifdef PV_ANNEX_IJKT_SUPPORT 199 if (!video->slice_structure) 200 { 201 #endif 202 if (mbnum >= (int)(video->mbnum_row + 1)*video->nMBinGOB) /* 10/11/01 */ 203 { 204 if (mbnum >= nTotalMB) return PV_SUCCESS; 205 status = BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar); 206 207 if (tmpvar == GOB_RESYNC_MARKER) 208 { 209 break; 210 } 211 else 212 { 213 status = PV_BitstreamShowBitsByteAlign(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar); 214 if (tmpvar == GOB_RESYNC_MARKER) break; 215 } 216 } 217 #ifdef PV_ANNEX_IJKT_SUPPORT 218 } 219 else 220 { 221 222 if (mbnum >= nTotalMB) /* in case no valid stuffing 06/23/01 */ 223 { 224 valid_stuffing = validStuffing_h263(stream); 225 if (valid_stuffing == 0) 226 { 227 VideoDecoderErrorDetected(video); 228 ConcealPacket(video, mb_start, nTotalMB, slice_counter); 229 } 230 return PV_SUCCESS; 231 } 232 /* ANNEX_K */ 233 PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar); 234 if (tmpvar == RESYNC_MARKER) 235 { 236 valid_stuffing = validStuffing_h263(stream); 237 if (valid_stuffing) 238 break; /* 06/21/01 */ 239 } 240 241 } 242 #endif 243 } 244 else 245 { 246 if (mbnum >= nTotalMB) /* in case no valid stuffing 06/23/01 */ 247 { 248 /* 11/01/2002 if we are at the end of the frame and there is some garbage data 249 at the end of the frame (i.e. no next startcode) break if the stuffing is valid */ 250 valid_stuffing = validStuffing(stream); 251 if (valid_stuffing == 0) 252 { 253 /* end 11/01/2002 */ 254 VideoDecoderErrorDetected(video); 255 ConcealPacket(video, mb_start, nTotalMB, slice_counter); 256 } 257 PV_BitstreamByteAlign(stream); 258 return PV_SUCCESS; 259 } 260 261 status = PV_BitstreamShowBitsByteAlign(stream, 23, &tmpvar); /* this call is valid for f_code < 8 */ 262 long_zero_bits = !tmpvar; 263 264 if ((tmpvar >> (23 - resync_marker_length)) == RESYNC_MARKER || long_zero_bits) 265 { 266 valid_stuffing = validStuffing(stream); 267 if (valid_stuffing) 268 break; /* 06/21/01 */ 269 } 270 271 } 272 } 273 while (TRUE); 274 275 if (shortVideoHeader) 276 { /* We need to check newgob to refresh quantizer */ 277 #ifdef PV_ANNEX_IJKT_SUPPORT 278 if (!video->slice_structure) 279 { 280 #endif 281 while ((status = PV_GobHeader(video)) == PV_FAIL) 282 { 283 if ((status = quickSearchGOBHeader(stream)) != PV_SUCCESS) 284 { 285 break; 286 } 287 } 288 289 mbnum = currVop->gobNumber * video->nMBinGOB; 290 #ifdef PV_ANNEX_IJKT_SUPPORT 291 } 292 else 293 { 294 while ((status = PV_H263SliceHeader(video, &mbnum)) == PV_FAIL) 295 { 296 if ((status = quickSearchH263SliceHeader(stream)) != PV_SUCCESS) 297 { 298 break; 299 } 300 } 301 } 302 303 #endif 304 } 305 else 306 { 307 while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL) 308 { 309 if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS) 310 { 311 break; 312 } 313 } 314 } 315 316 if (status == PV_END_OF_VOP) 317 { 318 mbnum = nTotalMB; 319 } 320 321 if (mbnum > video->mbnum + 1) 322 { 323 ConcealPacket(video, video->mbnum, mbnum, slice_counter); 324 } 325 QP = video->currVop->quantizer; 326 slice_counter++; 327 if (mbnum >= nTotalMB) break; 328 329 } 330 while (TRUE); 331 return PV_SUCCESS; 332 } 333 334 335 /* ============================================================================ */ 336 /* Function : GetMBHeader() */ 337 /* Purpose : Decode MB header, not_coded, mcbpc, ac_pred_flag, cbpy, dquant. */ 338 /* In/out : */ 339 /* Return : */ 340 /* Modified : */ 341 /* */ 342 /* 3/29/00 : Changed the returned value and optimized the code. */ 343 /* 4/01/01 : new ACDC prediction structure */ 344 /* ============================================================================ */ 345 PV_STATUS GetMBheader(VideoDecData *video, int16 *QP) 346 { 347 BitstreamDecVideo *stream = video->bitstream; 348 int mbnum = video->mbnum; 349 uint8 *Mode = video->headerInfo.Mode; 350 int x_pos = video->mbnum_col; 351 typeDCStore *DC = video->predDC + mbnum; 352 typeDCACStore *DCAC_row = video->predDCAC_row + x_pos; 353 typeDCACStore *DCAC_col = video->predDCAC_col; 354 const static int16 DQ_tab[4] = { -1, -2, 1, 2}; 355 356 int CBPY, CBPC; 357 int MBtype, VopType; 358 int MCBPC; 359 uint DQUANT; 360 int comp; 361 Bool mb_coded; 362 363 VopType = video->currVop->predictionType; 364 mb_coded = ((VopType == I_VOP) ? TRUE : !BitstreamRead1Bits_INLINE(stream)); 365 366 if (!mb_coded) 367 { 368 /* skipped macroblock */ 369 Mode[mbnum] = MODE_SKIPPED; 370 //oscl_memset(DCAC_row, 0, sizeof(typeDCACStore)); /* SKIPPED_ACDC */ 371 //oscl_memset(DCAC_col, 0, sizeof(typeDCACStore)); 372 ZERO_OUT_64BYTES(DCAC_row); 373 ZERO_OUT_64BYTES(DCAC_col); /* 08/12/05 */ 374 375 for (comp = 0; comp < 6; comp++) 376 { 377 (*DC)[comp] = mid_gray; 378 } 379 } 380 else 381 { 382 /* coded macroblock */ 383 if (VopType == I_VOP) 384 { 385 MCBPC = PV_VlcDecMCBPC_com_intra(stream); 386 } 387 else 388 { 389 #ifdef PV_ANNEX_IJKT_SUPPORT 390 if (!video->deblocking) 391 { 392 MCBPC = PV_VlcDecMCBPC_com_inter(stream); 393 } 394 else 395 { 396 MCBPC = PV_VlcDecMCBPC_com_inter_H263(stream); 397 } 398 #else 399 MCBPC = PV_VlcDecMCBPC_com_inter(stream); 400 #endif 401 } 402 403 if (VLC_ERROR_DETECTED(MCBPC)) 404 { 405 return PV_FAIL; 406 } 407 408 Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]); 409 CBPC = (MCBPC >> 4) & 3; 410 411 #ifdef PV_ANNEX_IJKT_SUPPORT 412 if (MBtype & INTRA_MASK) 413 { 414 if (!video->shortVideoHeader) 415 { 416 video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream); 417 } 418 else 419 { 420 if (video->advanced_INTRA) 421 { 422 if (!BitstreamRead1Bits(stream)) 423 { 424 video->acPredFlag[mbnum] = 0; 425 } 426 else 427 { 428 video->acPredFlag[mbnum] = 1; 429 if (BitstreamRead1Bits(stream)) 430 { 431 video->mblock->direction = 0; 432 } 433 else 434 { 435 video->mblock->direction = 1; 436 } 437 } 438 } 439 else 440 { 441 video->acPredFlag[mbnum] = 0; 442 } 443 } 444 } 445 #else 446 if ((MBtype & INTRA_MASK) && !video->shortVideoHeader) 447 { 448 video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream); 449 } 450 else 451 { 452 video->acPredFlag[mbnum] = 0; 453 } 454 #endif 455 CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* INTRA || INTRA_Q */ 456 if (CBPY < 0) 457 { 458 return PV_FAIL; 459 } 460 461 // GW 04/23/99 462 video->headerInfo.CBP[mbnum] = (uint8)(CBPY << 2 | (CBPC & 3)); 463 #ifdef PV_ANNEX_IJKT_SUPPORT 464 if (MBtype & Q_MASK) 465 { 466 if (!video->modified_quant) 467 { 468 DQUANT = BitstreamReadBits16(stream, 2); 469 *QP += DQ_tab[DQUANT]; 470 471 if (*QP < 1) *QP = 1; 472 else if (*QP > 31) *QP = 31; 473 video->QP_CHR = *QP; /* ANNEX_T */ 474 } 475 else 476 { 477 if (BitstreamRead1Bits(stream)) 478 { 479 if (BitstreamRead1Bits(stream)) 480 { 481 *QP += DQ_tab_Annex_T_11[*QP]; 482 } 483 else 484 { 485 *QP += DQ_tab_Annex_T_10[*QP]; 486 } 487 if (*QP < 1) *QP = 1; 488 else if (*QP > 31) *QP = 31; 489 } 490 else 491 { 492 *QP = (int16)BitstreamReadBits16(stream, 5); 493 } 494 video->QP_CHR = MQ_chroma_QP_table[*QP]; 495 } 496 } 497 #else 498 if (MBtype & Q_MASK) 499 { 500 DQUANT = BitstreamReadBits16(stream, 2); 501 *QP += DQ_tab[DQUANT]; 502 503 if (*QP < 1) *QP = 1; 504 else if (*QP > 31) *QP = 31; 505 } 506 #endif 507 } 508 return PV_SUCCESS; 509 } 510 511 512 513 514 515 /***********************************************************CommentBegin****** 516 * 3/10/00 : initial modification to the 517 * new PV-Decoder Lib format. 518 * 4/2/2000 : Cleanup and error-handling modification. This 519 * function has been divided into several sub-functions for 520 * better coding style and maintainance reason. I also 521 * greatly shrunk the code size here. 522 * 9/18/2000 : VlcDecode+Dequant optimization * 523 * 4/01/2001 : new ACDC prediction structure 524 * 3/29/2002 : removed GetIntraMB and GetInterMB 525 ***********************************************************CommentEnd********/ 526 PV_STATUS GetMBData(VideoDecData *video) 527 { 528 BitstreamDecVideo *stream = video->bitstream; 529 int mbnum = video->mbnum; 530 MacroBlock *mblock = video->mblock; 531 int16 *dataBlock; 532 PIXEL *c_comp; 533 uint mode = video->headerInfo.Mode[mbnum]; 534 uint CBP = video->headerInfo.CBP[mbnum]; 535 typeDCStore *DC = video->predDC + mbnum; 536 int intra_dc_vlc_thr = video->currVop->intraDCVlcThr; 537 int16 QP = video->QPMB[mbnum]; 538 int16 QP_tmp = QP; 539 int width = video->width; 540 int comp; 541 int switched; 542 int ncoeffs[6] = {0, 0, 0, 0, 0, 0}; 543 int *no_coeff = mblock->no_coeff; 544 int16 DC_coeff; 545 PV_STATUS status; 546 547 #ifdef PV_POSTPROC_ON 548 /* post-processing */ 549 uint8 *pp_mod[6]; 550 int TotalMB = video->nTotalMB; 551 int MB_in_width = video->nMBPerRow; 552 #endif 553 int y_pos = video->mbnum_row; 554 int x_pos = video->mbnum_col; 555 int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4); 556 557 /* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */ 558 /* are chrominance blocks. 04/03/2000. */ 559 #ifdef PV_POSTPROC_ON 560 if (video->postFilterType != PV_NO_POST_PROC) 561 { 562 /** post-processing ***/ 563 pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1); 564 pp_mod[1] = pp_mod[0] + 1; 565 pp_mod[2] = pp_mod[0] + (MB_in_width << 1); 566 pp_mod[3] = pp_mod[2] + 1; 567 pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum; 568 pp_mod[5] = pp_mod[4] + TotalMB; 569 } 570 #endif 571 572 /* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */ 573 574 if (mode & INTRA_MASK) /* MODE_INTRA || MODE_INTRA_Q */ 575 { 576 switched = 0; 577 if (intra_dc_vlc_thr) 578 { 579 if (video->usePrevQP) 580 QP_tmp = video->QPMB[mbnum-1]; /* running QP 04/26/01 */ 581 582 switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11); 583 } 584 585 mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE); /* 3/01/01 */ 586 mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE); 587 588 for (comp = 0; comp < 6; comp++) 589 { 590 dataBlock = mblock->block[comp]; /* 10/20/2000 */ 591 592 if (video->shortVideoHeader) 593 { 594 #ifdef PV_ANNEX_IJKT_SUPPORT 595 if (!video->advanced_INTRA) 596 { 597 #endif 598 DC_coeff = (int16) BitstreamReadBits16_INLINE(stream, 8); 599 600 if ((DC_coeff & 0x7f) == 0) /* 128 & 0 */ 601 { 602 /* currently we will only signal FAIL for 128. We will ignore the 0 case */ 603 if (DC_coeff == 128) 604 { 605 return PV_FAIL; 606 } 607 else 608 { 609 VideoDecoderErrorDetected(video); 610 } 611 } 612 if (DC_coeff == 255) 613 { 614 DC_coeff = 128; 615 } 616 dataBlock[0] = (int16) DC_coeff; 617 #ifdef PV_ANNEX_IJKT_SUPPORT 618 } 619 #endif 620 ncoeffs[comp] = VlcDequantH263IntraBlock_SH(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 621 622 } 623 else 624 { 625 if (switched == 0) 626 { 627 status = PV_DecodePredictedIntraDC(comp, stream, &DC_coeff); 628 if (status != PV_SUCCESS) return PV_FAIL; 629 630 dataBlock[0] = (int16) DC_coeff; 631 } 632 ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp, 633 switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 634 } 635 636 if (VLC_ERROR_DETECTED(ncoeffs[comp])) 637 { 638 if (switched) 639 return PV_FAIL; 640 else 641 { 642 ncoeffs[comp] = 1; 643 oscl_memset((dataBlock + 1), 0, sizeof(int16)*63); 644 } 645 } 646 no_coeff[comp] = ncoeffs[comp]; 647 648 #ifdef PV_POSTPROC_ON 649 if (video->postFilterType != PV_NO_POST_PROC) 650 *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock); 651 #endif 652 } 653 MBlockIDCT(video); 654 } 655 else /* INTER modes */ 656 { /* moved it here Aug 15, 2005 */ 657 /* decode the motion vector (if there are any) */ 658 status = PV_GetMBvectors(video, mode); 659 if (status != PV_SUCCESS) 660 { 661 return status; 662 } 663 664 665 MBMotionComp(video, CBP); 666 c_comp = video->currVop->yChan + offset; 667 668 #ifdef PV_ANNEX_IJKT_SUPPORT 669 for (comp = 0; comp < 4; comp++) 670 { 671 (*DC)[comp] = mid_gray; 672 if (CBP & (1 << (5 - comp))) 673 { 674 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 675 if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL; 676 677 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], 678 mblock->bitmapcol[comp], mblock->bitmaprow[comp]); 679 680 #ifdef PV_POSTPROC_ON 681 /* for inter just test for ringing */ 682 if (video->postFilterType != PV_NO_POST_PROC) 683 *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0); 684 #endif 685 } 686 else 687 { 688 /* no IDCT for all zeros blocks 03/28/2002 */ 689 /* BlockIDCT(); */ 690 #ifdef PV_POSTPROC_ON 691 if (video->postFilterType != PV_NO_POST_PROC) 692 *pp_mod[comp] = 0; 693 #endif 694 } 695 } 696 697 video->QPMB[mbnum] = video->QP_CHR; /* ANNEX_T */ 698 699 700 701 (*DC)[4] = mid_gray; 702 if (CBP & 2) 703 { 704 ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]); 705 if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL; 706 707 BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4], 708 mblock->bitmapcol[4], mblock->bitmaprow[4]); 709 710 #ifdef PV_POSTPROC_ON 711 /* for inter just test for ringing */ 712 if (video->postFilterType != PV_NO_POST_PROC) 713 *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0); 714 #endif 715 } 716 else 717 { 718 /* no IDCT for all zeros blocks 03/28/2002 */ 719 /* BlockIDCT(); */ 720 #ifdef PV_POSTPROC_ON 721 if (video->postFilterType != PV_NO_POST_PROC) 722 *pp_mod[4] = 0; 723 #endif 724 } 725 (*DC)[5] = mid_gray; 726 if (CBP & 1) 727 { 728 ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]); 729 if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL; 730 731 BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5], 732 mblock->bitmapcol[5], mblock->bitmaprow[5]); 733 734 #ifdef PV_POSTPROC_ON 735 /* for inter just test for ringing */ 736 if (video->postFilterType != PV_NO_POST_PROC) 737 *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0); 738 #endif 739 } 740 else 741 { 742 /* no IDCT for all zeros blocks 03/28/2002 */ 743 /* BlockIDCT(); */ 744 #ifdef PV_POSTPROC_ON 745 if (video->postFilterType != PV_NO_POST_PROC) 746 *pp_mod[5] = 0; 747 #endif 748 } 749 video->QPMB[mbnum] = QP; /* restore the QP values ANNEX_T*/ 750 #else 751 for (comp = 0; comp < 4; comp++) 752 { 753 (*DC)[comp] = mid_gray; 754 if (CBP & (1 << (5 - comp))) 755 { 756 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]); 757 if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL; 758 759 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], 760 mblock->bitmapcol[comp], mblock->bitmaprow[comp]); 761 762 #ifdef PV_POSTPROC_ON 763 /* for inter just test for ringing */ 764 if (video->postFilterType != PV_NO_POST_PROC) 765 *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0); 766 #endif 767 } 768 else 769 { 770 /* no IDCT for all zeros blocks 03/28/2002 */ 771 /* BlockIDCT(); */ 772 #ifdef PV_POSTPROC_ON 773 if (video->postFilterType != PV_NO_POST_PROC) 774 *pp_mod[comp] = 0; 775 #endif 776 } 777 } 778 779 (*DC)[4] = mid_gray; 780 if (CBP & 2) 781 { 782 ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]); 783 if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL; 784 785 BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4], 786 mblock->bitmapcol[4], mblock->bitmaprow[4]); 787 788 #ifdef PV_POSTPROC_ON 789 /* for inter just test for ringing */ 790 if (video->postFilterType != PV_NO_POST_PROC) 791 *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0); 792 #endif 793 } 794 else 795 { 796 /* no IDCT for all zeros blocks 03/28/2002 */ 797 /* BlockIDCT(); */ 798 #ifdef PV_POSTPROC_ON 799 if (video->postFilterType != PV_NO_POST_PROC) 800 *pp_mod[4] = 0; 801 #endif 802 } 803 (*DC)[5] = mid_gray; 804 if (CBP & 1) 805 { 806 ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]); 807 if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL; 808 809 BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5], 810 mblock->bitmapcol[5], mblock->bitmaprow[5]); 811 812 #ifdef PV_POSTPROC_ON 813 /* for inter just test for ringing */ 814 if (video->postFilterType != PV_NO_POST_PROC) 815 *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0); 816 #endif 817 } 818 else 819 { 820 /* no IDCT for all zeros blocks 03/28/2002 */ 821 /* BlockIDCT(); */ 822 #ifdef PV_POSTPROC_ON 823 if (video->postFilterType != PV_NO_POST_PROC) 824 *pp_mod[5] = 0; 825 #endif 826 #endif // PV_ANNEX_IJKT_SUPPORT 827 828 829 830 831 832 833 } 834 835 video->usePrevQP = 1; /* should be set after decoding the first Coded 04/27/01 */ 836 return PV_SUCCESS; 837 } 838 839 840 841