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 "avcenc_lib.h" 19 20 21 AVCEnc_Status AVCEncodeSlice(AVCEncObject *encvid) 22 { 23 AVCEnc_Status status = AVCENC_SUCCESS; 24 AVCCommonObj *video = encvid->common; 25 AVCPicParamSet *pps = video->currPicParams; 26 AVCSliceHeader *sliceHdr = video->sliceHdr; 27 AVCMacroblock *currMB ; 28 AVCEncBitstream *stream = encvid->bitstream; 29 uint slice_group_id; 30 int CurrMbAddr, slice_type; 31 32 slice_type = video->slice_type; 33 34 /* set the first mb in slice */ 35 video->mbNum = CurrMbAddr = sliceHdr->first_mb_in_slice;// * (1+video->MbaffFrameFlag); 36 slice_group_id = video->MbToSliceGroupMap[CurrMbAddr]; 37 38 video->mb_skip_run = 0; 39 40 /* while loop , see subclause 7.3.4 */ 41 while (1) 42 { 43 video->mbNum = CurrMbAddr; 44 currMB = video->currMB = &(video->mblock[CurrMbAddr]); 45 currMB->slice_id = video->slice_id; // for deblocking 46 47 video->mb_x = CurrMbAddr % video->PicWidthInMbs; 48 video->mb_y = CurrMbAddr / video->PicWidthInMbs; 49 50 /* initialize QP for this MB here*/ 51 /* calculate currMB->QPy */ 52 RCInitMBQP(encvid); 53 54 /* check the availability of neighboring macroblocks */ 55 InitNeighborAvailability(video, CurrMbAddr); 56 57 /* Assuming that InitNeighborAvailability has been called prior to this function */ 58 video->intraAvailA = video->intraAvailB = video->intraAvailC = video->intraAvailD = 0; 59 /* this is necessary for all subsequent intra search */ 60 61 if (!video->currPicParams->constrained_intra_pred_flag) 62 { 63 video->intraAvailA = video->mbAvailA; 64 video->intraAvailB = video->mbAvailB; 65 video->intraAvailC = video->mbAvailC; 66 video->intraAvailD = video->mbAvailD; 67 } 68 else 69 { 70 if (video->mbAvailA) 71 { 72 video->intraAvailA = video->mblock[video->mbAddrA].mb_intra; 73 } 74 if (video->mbAvailB) 75 { 76 video->intraAvailB = video->mblock[video->mbAddrB].mb_intra ; 77 } 78 if (video->mbAvailC) 79 { 80 video->intraAvailC = video->mblock[video->mbAddrC].mb_intra; 81 } 82 if (video->mbAvailD) 83 { 84 video->intraAvailD = video->mblock[video->mbAddrD].mb_intra; 85 } 86 } 87 88 /* encode_one_macroblock() */ 89 status = EncodeMB(encvid); 90 if (status != AVCENC_SUCCESS) 91 { 92 break; 93 } 94 95 /* go to next MB */ 96 CurrMbAddr++; 97 98 while ((uint)video->MbToSliceGroupMap[CurrMbAddr] != slice_group_id && 99 (uint)CurrMbAddr < video->PicSizeInMbs) 100 { 101 CurrMbAddr++; 102 } 103 104 if ((uint)CurrMbAddr >= video->PicSizeInMbs) 105 { 106 /* end of slice, return, but before that check to see if there are other slices 107 to be encoded. */ 108 encvid->currSliceGroup++; 109 if (encvid->currSliceGroup > (int)pps->num_slice_groups_minus1) /* no more slice group */ 110 { 111 status = AVCENC_PICTURE_READY; 112 break; 113 } 114 else 115 { 116 /* find first_mb_num for the next slice */ 117 CurrMbAddr = 0; 118 while (video->MbToSliceGroupMap[CurrMbAddr] != encvid->currSliceGroup && 119 (uint)CurrMbAddr < video->PicSizeInMbs) 120 { 121 CurrMbAddr++; 122 } 123 if ((uint)CurrMbAddr >= video->PicSizeInMbs) 124 { 125 status = AVCENC_SLICE_EMPTY; /* error, one slice group has no MBs in it */ 126 } 127 128 video->mbNum = CurrMbAddr; 129 status = AVCENC_SUCCESS; 130 break; 131 } 132 } 133 } 134 135 if (video->mb_skip_run > 0) 136 { 137 /* write skip_run */ 138 if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE) 139 { 140 ue_v(stream, video->mb_skip_run); 141 video->mb_skip_run = 0; 142 } 143 else /* shouldn't happen */ 144 { 145 status = AVCENC_FAIL; 146 } 147 } 148 149 return status; 150 } 151 152 153 AVCEnc_Status EncodeMB(AVCEncObject *encvid) 154 { 155 AVCEnc_Status status = AVCENC_SUCCESS; 156 AVCCommonObj *video = encvid->common; 157 AVCPictureData *currPic = video->currPic; 158 AVCFrameIO *currInput = encvid->currInput; 159 AVCMacroblock *currMB = video->currMB; 160 AVCMacroblock *MB_A, *MB_B; 161 AVCEncBitstream *stream = encvid->bitstream; 162 AVCRateControl *rateCtrl = encvid->rateCtrl; 163 uint8 *cur, *curL, *curCb, *curCr; 164 uint8 *orgL, *orgCb, *orgCr, *org4; 165 int CurrMbAddr = video->mbNum; 166 int picPitch = currPic->pitch; 167 int orgPitch = currInput->pitch; 168 int x_position = (video->mb_x << 4); 169 int y_position = (video->mb_y << 4); 170 int offset; 171 int b8, b4, blkidx; 172 AVCResidualType resType; 173 int slice_type; 174 int numcoeff; /* output from residual_block_cavlc */ 175 int cost16, cost8; 176 177 int num_bits, start_mb_bits, start_text_bits; 178 179 slice_type = video->slice_type; 180 181 /* now, point to the reconstructed frame */ 182 offset = y_position * picPitch + x_position; 183 curL = currPic->Sl + offset; 184 orgL = currInput->YCbCr[0] + offset; 185 offset = (offset + x_position) >> 2; 186 curCb = currPic->Scb + offset; 187 curCr = currPic->Scr + offset; 188 orgCb = currInput->YCbCr[1] + offset; 189 orgCr = currInput->YCbCr[2] + offset; 190 191 if (orgPitch != picPitch) 192 { 193 offset = y_position * (orgPitch - picPitch); 194 orgL += offset; 195 offset >>= 2; 196 orgCb += offset; 197 orgCr += offset; 198 } 199 200 /******* determine MB prediction mode *******/ 201 if (encvid->intraSearch[CurrMbAddr]) 202 { 203 MBIntraSearch(encvid, CurrMbAddr, curL, picPitch); 204 } 205 /******* This part should be determined somehow ***************/ 206 if (currMB->mbMode == AVC_I_PCM) 207 { 208 /* write down mb_type and PCM data */ 209 /* and copy from currInput to currPic */ 210 status = EncodeIntraPCM(encvid); 211 212 213 return status; 214 } 215 216 /****** for intra prediction, pred is already done *******/ 217 /****** for I4, the recon is ready and Xfrm coefs are ready to be encoded *****/ 218 219 //RCCalculateMAD(encvid,currMB,orgL,orgPitch); // no need to re-calculate MAD for Intra 220 // not used since totalSAD is used instead 221 222 /* compute the prediction */ 223 /* output is video->pred_block */ 224 if (!currMB->mb_intra) 225 { 226 AVCMBMotionComp(encvid, video); /* perform prediction and residue calculation */ 227 /* we can do the loop here and call dct_luma */ 228 video->pred_pitch = picPitch; 229 currMB->CBP = 0; 230 cost16 = 0; 231 cur = curL; 232 org4 = orgL; 233 234 for (b8 = 0; b8 < 4; b8++) 235 { 236 cost8 = 0; 237 238 for (b4 = 0; b4 < 4; b4++) 239 { 240 blkidx = blkIdx2blkXY[b8][b4]; 241 video->pred_block = cur; 242 numcoeff = dct_luma(encvid, blkidx, cur, org4, &cost8); 243 currMB->nz_coeff[blkidx] = numcoeff; 244 if (numcoeff) 245 { 246 video->cbp4x4 |= (1 << blkidx); 247 currMB->CBP |= (1 << b8); 248 } 249 250 if (b4&1) 251 { 252 cur += ((picPitch << 2) - 4); 253 org4 += ((orgPitch << 2) - 4); 254 } 255 else 256 { 257 cur += 4; 258 org4 += 4; 259 } 260 } 261 262 /* move the IDCT part out of dct_luma to accommodate the check 263 for coeff_cost. */ 264 265 if ((currMB->CBP&(1 << b8)) && (cost8 <= _LUMA_COEFF_COST_)) 266 { 267 cost8 = 0; // reset it 268 269 currMB->CBP ^= (1 << b8); 270 blkidx = blkIdx2blkXY[b8][0]; 271 272 currMB->nz_coeff[blkidx] = 0; 273 currMB->nz_coeff[blkidx+1] = 0; 274 currMB->nz_coeff[blkidx+4] = 0; 275 currMB->nz_coeff[blkidx+5] = 0; 276 } 277 278 cost16 += cost8; 279 280 if (b8&1) 281 { 282 cur -= 8; 283 org4 -= 8; 284 } 285 else 286 { 287 cur += (8 - (picPitch << 3)); 288 org4 += (8 - (orgPitch << 3)); 289 } 290 } 291 292 /* after the whole MB, we do another check for coeff_cost */ 293 if ((currMB->CBP&0xF) && (cost16 <= _LUMA_MB_COEFF_COST_)) 294 { 295 currMB->CBP = 0; // reset it to zero 296 memset(currMB->nz_coeff, 0, sizeof(uint8)*16); 297 } 298 299 // now we do IDCT 300 MBInterIdct(video, curL, currMB, picPitch); 301 302 // video->pred_block = video->pred + 256; 303 } 304 else /* Intra prediction */ 305 { 306 encvid->numIntraMB++; 307 308 if (currMB->mbMode == AVC_I16) /* do prediction for the whole macroblock */ 309 { 310 currMB->CBP = 0; 311 /* get the prediction from encvid->pred_i16 */ 312 dct_luma_16x16(encvid, curL, orgL); 313 } 314 video->pred_block = encvid->pred_ic[currMB->intra_chroma_pred_mode]; 315 } 316 317 /* chrominance */ 318 /* not need to do anything, the result is in encvid->pred_ic 319 chroma dct must be aware that prediction block can come from either intra or inter. */ 320 321 dct_chroma(encvid, curCb, orgCb, 0); 322 323 dct_chroma(encvid, curCr, orgCr, 1); 324 325 326 /* 4.1 if there's nothing in there, video->mb_skip_run++ */ 327 /* 4.2 if coded, check if there is a run of skipped MB, encodes it, 328 set video->QPyprev = currMB->QPy; */ 329 330 /* 5. vlc encode */ 331 332 /* check for skipped macroblock, INTER only */ 333 if (!currMB->mb_intra) 334 { 335 /* decide whether this MB (for inter MB) should be skipped if there's nothing left. */ 336 if (!currMB->CBP && currMB->NumMbPart == 1 && currMB->QPy == video->QPy) 337 { 338 if (currMB->MBPartPredMode[0][0] == AVC_Pred_L0 && currMB->ref_idx_L0[0] == 0) 339 { 340 MB_A = &video->mblock[video->mbAddrA]; 341 MB_B = &video->mblock[video->mbAddrB]; 342 343 if (!video->mbAvailA || !video->mbAvailB) 344 { 345 if (currMB->mvL0[0] == 0) /* both mv components are zeros.*/ 346 { 347 currMB->mbMode = AVC_SKIP; 348 video->mvd_l0[0][0][0] = 0; 349 video->mvd_l0[0][0][1] = 0; 350 } 351 } 352 else 353 { 354 if ((MB_A->ref_idx_L0[1] == 0 && MB_A->mvL0[3] == 0) || 355 (MB_B->ref_idx_L0[2] == 0 && MB_B->mvL0[12] == 0)) 356 { 357 if (currMB->mvL0[0] == 0) /* both mv components are zeros.*/ 358 { 359 currMB->mbMode = AVC_SKIP; 360 video->mvd_l0[0][0][0] = 0; 361 video->mvd_l0[0][0][1] = 0; 362 } 363 } 364 else if (video->mvd_l0[0][0][0] == 0 && video->mvd_l0[0][0][1] == 0) 365 { 366 currMB->mbMode = AVC_SKIP; 367 } 368 } 369 } 370 371 if (currMB->mbMode == AVC_SKIP) 372 { 373 video->mb_skip_run++; 374 375 /* set parameters */ 376 /* not sure whether we need the followings */ 377 if (slice_type == AVC_P_SLICE) 378 { 379 currMB->mbMode = AVC_SKIP; 380 currMB->MbPartWidth = currMB->MbPartHeight = 16; 381 currMB->MBPartPredMode[0][0] = AVC_Pred_L0; 382 currMB->NumMbPart = 1; 383 currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] = 384 currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1; 385 currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] = 386 currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth; 387 currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] = 388 currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight; 389 390 } 391 else if (slice_type == AVC_B_SLICE) 392 { 393 currMB->mbMode = AVC_SKIP; 394 currMB->MbPartWidth = currMB->MbPartHeight = 8; 395 currMB->MBPartPredMode[0][0] = AVC_Direct; 396 currMB->NumMbPart = -1; 397 } 398 399 /* for skipped MB, always look at the first entry in RefPicList */ 400 currMB->RefIdx[0] = currMB->RefIdx[1] = 401 currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx; 402 403 /* do not return yet, need to do some copies */ 404 } 405 } 406 } 407 /* non-skipped MB */ 408 409 410 /************* START ENTROPY CODING *************************/ 411 412 start_mb_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left; 413 414 /* encode mb_type, mb_pred, sub_mb_pred, CBP */ 415 if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE && currMB->mbMode != AVC_SKIP) 416 { 417 //if(!pps->entropy_coding_mode_flag) ALWAYS true 418 { 419 ue_v(stream, video->mb_skip_run); 420 video->mb_skip_run = 0; 421 } 422 } 423 424 if (currMB->mbMode != AVC_SKIP) 425 { 426 status = EncodeMBHeader(currMB, encvid); 427 if (status != AVCENC_SUCCESS) 428 { 429 return status; 430 } 431 } 432 433 start_text_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left; 434 435 /**** now decoding part *******/ 436 resType = AVC_Luma; 437 438 /* DC transform for luma I16 mode */ 439 if (currMB->mbMode == AVC_I16) 440 { 441 /* vlc encode level/run */ 442 status = enc_residual_block(encvid, AVC_Intra16DC, encvid->numcoefdc, currMB); 443 if (status != AVCENC_SUCCESS) 444 { 445 return status; 446 } 447 resType = AVC_Intra16AC; 448 } 449 450 /* VLC encoding for luma */ 451 for (b8 = 0; b8 < 4; b8++) 452 { 453 if (currMB->CBP&(1 << b8)) 454 { 455 for (b4 = 0; b4 < 4; b4++) 456 { 457 /* vlc encode level/run */ 458 status = enc_residual_block(encvid, resType, (b8 << 2) + b4, currMB); 459 if (status != AVCENC_SUCCESS) 460 { 461 return status; 462 } 463 } 464 } 465 } 466 467 /* chroma */ 468 if (currMB->CBP & (3 << 4)) /* chroma DC residual present */ 469 { 470 for (b8 = 0; b8 < 2; b8++) /* for iCbCr */ 471 { 472 /* vlc encode level/run */ 473 status = enc_residual_block(encvid, AVC_ChromaDC, encvid->numcoefcdc[b8] + (b8 << 3), currMB); 474 if (status != AVCENC_SUCCESS) 475 { 476 return status; 477 } 478 } 479 } 480 481 if (currMB->CBP & (2 << 4)) 482 { 483 /* AC part */ 484 for (b8 = 0; b8 < 2; b8++) /* for iCbCr */ 485 { 486 for (b4 = 0; b4 < 4; b4++) /* for each block inside Cb or Cr */ 487 { 488 /* vlc encode level/run */ 489 status = enc_residual_block(encvid, AVC_ChromaAC, 16 + (b8 << 2) + b4, currMB); 490 if (status != AVCENC_SUCCESS) 491 { 492 return status; 493 } 494 } 495 } 496 } 497 498 499 num_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left; 500 501 RCPostMB(video, rateCtrl, start_text_bits - start_mb_bits, 502 num_bits - start_text_bits); 503 504 // num_bits -= start_mb_bits; 505 // fprintf(fdebug,"MB #%d: %d bits\n",CurrMbAddr,num_bits); 506 // fclose(fdebug); 507 return status; 508 } 509 510 /* copy the content from predBlock back to the reconstructed YUV frame */ 511 void Copy_MB(uint8 *curL, uint8 *curCb, uint8 *curCr, uint8 *predBlock, int picPitch) 512 { 513 int j, offset; 514 uint32 *dst, *dst2, *src; 515 516 dst = (uint32*)curL; 517 src = (uint32*)predBlock; 518 519 offset = (picPitch - 16) >> 2; 520 521 for (j = 0; j < 16; j++) 522 { 523 *dst++ = *src++; 524 *dst++ = *src++; 525 *dst++ = *src++; 526 *dst++ = *src++; 527 528 dst += offset; 529 } 530 531 dst = (uint32*)curCb; 532 dst2 = (uint32*)curCr; 533 offset >>= 1; 534 535 for (j = 0; j < 8; j++) 536 { 537 *dst++ = *src++; 538 *dst++ = *src++; 539 *dst2++ = *src++; 540 *dst2++ = *src++; 541 542 dst += offset; 543 dst2 += offset; 544 } 545 return ; 546 } 547 548 /* encode mb_type, mb_pred, sub_mb_pred, CBP */ 549 /* decide whether this MB (for inter MB) should be skipped */ 550 AVCEnc_Status EncodeMBHeader(AVCMacroblock *currMB, AVCEncObject *encvid) 551 { 552 AVCEnc_Status status = AVCENC_SUCCESS; 553 uint mb_type; 554 AVCCommonObj *video = encvid->common; 555 AVCEncBitstream *stream = encvid->bitstream; 556 557 if (currMB->CBP > 47) /* chroma CBP is 11 */ 558 { 559 currMB->CBP -= 16; /* remove the 5th bit from the right */ 560 } 561 562 mb_type = InterpretMBType(currMB, video->slice_type); 563 564 status = ue_v(stream, mb_type); 565 566 if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0) 567 { 568 status = sub_mb_pred(video, currMB, stream); 569 } 570 else 571 { 572 status = mb_pred(video, currMB, stream) ; 573 } 574 575 if (currMB->mbMode != AVC_I16) 576 { 577 /* decode coded_block_pattern */ 578 status = EncodeCBP(currMB, stream); 579 } 580 581 /* calculate currMB->mb_qp_delta = currMB->QPy - video->QPyprev */ 582 if (currMB->CBP > 0 || currMB->mbMode == AVC_I16) 583 { 584 status = se_v(stream, currMB->QPy - video->QPy); 585 video->QPy = currMB->QPy; /* = (video->QPyprev + currMB->mb_qp_delta + 52)%52; */ 586 // no need video->QPc = currMB->QPc; 587 } 588 else 589 { 590 if (currMB->QPy != video->QPy) // current QP is not the same as previous QP 591 { 592 /* restore these values */ 593 RCRestoreQP(currMB, video, encvid); 594 } 595 } 596 597 return status; 598 } 599 600 601 /* inputs are mbMode, mb_intra, i16Mode, CBP, NumMbPart, MbPartWidth, MbPartHeight */ 602 uint InterpretMBType(AVCMacroblock *currMB, int slice_type) 603 { 604 int CBP_chrom; 605 int mb_type;// part1, part2, part3; 606 // const static int MapParts2Type[2][3][3]={{{4,8,12},{10,6,14},{16,18,20}}, 607 // {{5,9,13},{11,7,15},{17,19,21}}}; 608 609 if (currMB->mb_intra) 610 { 611 if (currMB->mbMode == AVC_I4) 612 { 613 mb_type = 0; 614 } 615 else if (currMB->mbMode == AVC_I16) 616 { 617 CBP_chrom = (currMB->CBP & 0x30); 618 if (currMB->CBP&0xF) 619 { 620 currMB->CBP |= 0xF; /* either 0x0 or 0xF */ 621 mb_type = 13; 622 } 623 else 624 { 625 mb_type = 1; 626 } 627 mb_type += (CBP_chrom >> 2) + currMB->i16Mode; 628 } 629 else /* if(currMB->mbMode == AVC_I_PCM) */ 630 { 631 mb_type = 25; 632 } 633 } 634 else 635 { /* P-MB *//* note that the order of the enum AVCMBMode cannot be changed 636 since we use it here. */ 637 mb_type = currMB->mbMode - AVC_P16; 638 } 639 640 if (slice_type == AVC_P_SLICE) 641 { 642 if (currMB->mb_intra) 643 { 644 mb_type += 5; 645 } 646 } 647 // following codes have not been tested yet, not needed. 648 /* else if(slice_type == AVC_B_SLICE) 649 { 650 if(currMB->mbMode == AVC_BDirect16) 651 { 652 mb_type = 0; 653 } 654 else if(currMB->mbMode == AVC_P16) 655 { 656 mb_type = currMB->MBPartPredMode[0][0] + 1; // 1 or 2 657 } 658 else if(currMB->mbMode == AVC_P8) 659 { 660 mb_type = 26; 661 } 662 else if(currMB->mbMode == AVC_P8ref0) 663 { 664 mb_type = 27; 665 } 666 else 667 { 668 part1 = currMB->mbMode - AVC_P16x8; 669 part2 = currMB->MBPartPredMode[0][0]; 670 part3 = currMB->MBPartPredMode[1][0]; 671 mb_type = MapParts2Type[part1][part2][part3]; 672 } 673 } 674 675 if(slice_type == AVC_SI_SLICE) 676 { 677 mb_type++; 678 } 679 */ 680 return (uint)mb_type; 681 } 682 683 //const static int mbPart2raster[3][4] = {{0,0,0,0},{1,1,0,0},{1,0,1,0}}; 684 685 /* see subclause 7.3.5.1 */ 686 AVCEnc_Status mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream) 687 { 688 AVCEnc_Status status = AVCENC_SUCCESS; 689 int mbPartIdx; 690 AVCSliceHeader *sliceHdr = video->sliceHdr; 691 int max_ref_idx; 692 uint code; 693 694 if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16) 695 { 696 if (currMB->mbMode == AVC_I4) 697 { 698 /* perform prediction to get the actual intra 4x4 pred mode */ 699 EncodeIntra4x4Mode(video, currMB, stream); 700 /* output will be in currMB->i4Mode[4][4] */ 701 } 702 703 /* assume already set from MBPrediction() */ 704 status = ue_v(stream, currMB->intra_chroma_pred_mode); 705 } 706 else if (currMB->MBPartPredMode[0][0] != AVC_Direct) 707 { 708 709 memset(currMB->ref_idx_L0, 0, sizeof(int16)*4); 710 711 /* see subclause 7.4.5.1 for the range of ref_idx_lX */ 712 max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1; 713 /* if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag) 714 max_ref_idx = 2*sliceHdr->num_ref_idx_l0_active_minus1 + 1; 715 */ 716 /* decode ref index for L0 */ 717 if (sliceHdr->num_ref_idx_l0_active_minus1 > 0) 718 { 719 for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++) 720 { 721 if (/*(sliceHdr->num_ref_idx_l0_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/ 722 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1) 723 { 724 code = currMB->ref_idx_L0[mbPartIdx]; 725 status = te_v(stream, code, max_ref_idx); 726 } 727 } 728 } 729 730 /* see subclause 7.4.5.1 for the range of ref_idx_lX */ 731 max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1; 732 /* if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag) 733 max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1; 734 */ 735 /* decode ref index for L1 */ 736 if (sliceHdr->num_ref_idx_l1_active_minus1 > 0) 737 { 738 for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++) 739 { 740 if (/*(sliceHdr->num_ref_idx_l1_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/ 741 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0) 742 { 743 status = te_v(stream, currMB->ref_idx_L1[mbPartIdx], max_ref_idx); 744 } 745 } 746 } 747 748 /* encode mvd_l0 */ 749 for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++) 750 { 751 if (currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1) 752 { 753 status = se_v(stream, video->mvd_l0[mbPartIdx][0][0]); 754 status = se_v(stream, video->mvd_l0[mbPartIdx][0][1]); 755 } 756 } 757 /* encode mvd_l1 */ 758 for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++) 759 { 760 if (currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0) 761 { 762 status = se_v(stream, video->mvd_l1[mbPartIdx][0][0]); 763 status = se_v(stream, video->mvd_l1[mbPartIdx][0][1]); 764 } 765 } 766 } 767 768 return status; 769 } 770 771 /* see subclause 7.3.5.2 */ 772 AVCEnc_Status sub_mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream) 773 { 774 AVCEnc_Status status = AVCENC_SUCCESS; 775 int mbPartIdx, subMbPartIdx; 776 AVCSliceHeader *sliceHdr = video->sliceHdr; 777 uint max_ref_idx; 778 uint slice_type = video->slice_type; 779 uint sub_mb_type[4]; 780 781 /* this should move somewhere else where we don't have to make this check */ 782 if (currMB->mbMode == AVC_P8ref0) 783 { 784 memset(currMB->ref_idx_L0, 0, sizeof(int16)*4); 785 } 786 787 /* we have to check the values to make sure they are valid */ 788 /* assign values to currMB->sub_mb_type[] */ 789 if (slice_type == AVC_P_SLICE) 790 { 791 InterpretSubMBTypeP(currMB, sub_mb_type); 792 } 793 /* no need to check for B-slice 794 else if(slice_type == AVC_B_SLICE) 795 { 796 InterpretSubMBTypeB(currMB,sub_mb_type); 797 }*/ 798 799 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 800 { 801 status = ue_v(stream, sub_mb_type[mbPartIdx]); 802 } 803 804 /* see subclause 7.4.5.1 for the range of ref_idx_lX */ 805 max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1; 806 /* if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag) 807 max_ref_idx = 2*sliceHdr->num_ref_idx_l0_active_minus1 + 1; */ 808 809 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 810 { 811 if ((sliceHdr->num_ref_idx_l0_active_minus1 > 0 /*|| currMB->mb_field_decoding_flag*/) && 812 currMB->mbMode != AVC_P8ref0 && /*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/ 813 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1) 814 { 815 status = te_v(stream, currMB->ref_idx_L0[mbPartIdx], max_ref_idx); 816 } 817 /* used in deblocking */ 818 currMB->RefIdx[mbPartIdx] = video->RefPicList0[currMB->ref_idx_L0[mbPartIdx]]->RefIdx; 819 } 820 /* see subclause 7.4.5.1 for the range of ref_idx_lX */ 821 max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1; 822 /* if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag) 823 max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1;*/ 824 825 if (sliceHdr->num_ref_idx_l1_active_minus1 > 0) 826 { 827 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 828 { 829 if (/*(sliceHdr->num_ref_idx_l1_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/ 830 /*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/ 831 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0) 832 { 833 status = te_v(stream, currMB->ref_idx_L1[mbPartIdx], max_ref_idx); 834 } 835 } 836 } 837 838 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 839 { 840 if (/*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/ 841 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1) 842 { 843 for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++) 844 { 845 status = se_v(stream, video->mvd_l0[mbPartIdx][subMbPartIdx][0]); 846 status = se_v(stream, video->mvd_l0[mbPartIdx][subMbPartIdx][1]); 847 } 848 } 849 } 850 851 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 852 { 853 if (/*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/ 854 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0) 855 { 856 for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++) 857 { 858 status = se_v(stream, video->mvd_l1[mbPartIdx][subMbPartIdx][0]); 859 status = se_v(stream, video->mvd_l1[mbPartIdx][subMbPartIdx][1]); 860 } 861 } 862 } 863 864 return status; 865 } 866 867 /* input is mblock->sub_mb_type[] */ 868 void InterpretSubMBTypeP(AVCMacroblock *mblock, uint *sub_mb_type) 869 { 870 int i; 871 /* see enum AVCMBType declaration */ 872 /*const static AVCSubMBMode map2subMbMode[4] = {AVC_8x8,AVC_8x4,AVC_4x8,AVC_4x4}; 873 const static int map2subPartWidth[4] = {8,8,4,4}; 874 const static int map2subPartHeight[4] = {8,4,8,4}; 875 const static int map2numSubPart[4] = {1,2,2,4};*/ 876 877 for (i = 0; i < 4 ; i++) 878 { 879 sub_mb_type[i] = mblock->subMbMode[i] - AVC_8x8; 880 } 881 882 return ; 883 } 884 885 void InterpretSubMBTypeB(AVCMacroblock *mblock, uint *sub_mb_type) 886 { 887 int i; 888 /* see enum AVCMBType declaration */ 889 /* const static AVCSubMBMode map2subMbMode[13] = {AVC_BDirect8,AVC_8x8,AVC_8x8, 890 AVC_8x8,AVC_8x4,AVC_4x8,AVC_8x4,AVC_4x8,AVC_8x4,AVC_4x8,AVC_4x4,AVC_4x4,AVC_4x4}; 891 const static int map2subPartWidth[13] = {4,8,8,8,8,4,8,4,8,4,4,4,4}; 892 const static int map2subPartHeight[13] = {4,8,8,8,4,8,4,8,4,8,4,4,4}; 893 const static int map2numSubPart[13] = {4,1,1,1,2,2,2,2,2,2,4,4,4}; 894 const static int map2predMode[13] = {3,0,1,2,0,0,1,1,2,2,0,1,2};*/ 895 896 for (i = 0; i < 4 ; i++) 897 { 898 if (mblock->subMbMode[i] == AVC_BDirect8) 899 { 900 sub_mb_type[i] = 0; 901 } 902 else if (mblock->subMbMode[i] == AVC_8x8) 903 { 904 sub_mb_type[i] = 1 + mblock->MBPartPredMode[i][0]; 905 } 906 else if (mblock->subMbMode[i] == AVC_4x4) 907 { 908 sub_mb_type[i] = 10 + mblock->MBPartPredMode[i][0]; 909 } 910 else 911 { 912 sub_mb_type[i] = 4 + (mblock->MBPartPredMode[i][0] << 1) + (mblock->subMbMode[i] - AVC_8x4); 913 } 914 } 915 916 return ; 917 } 918 919 /* see subclause 8.3.1 */ 920 AVCEnc_Status EncodeIntra4x4Mode(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream) 921 { 922 int intra4x4PredModeA = 0; 923 int intra4x4PredModeB, predIntra4x4PredMode; 924 int component, SubBlock_indx, block_x, block_y; 925 int dcOnlyPredictionFlag; 926 uint flag; 927 int rem = 0; 928 int mode; 929 int bindx = 0; 930 931 for (component = 0; component < 4; component++) /* partition index */ 932 { 933 block_x = ((component & 1) << 1); 934 block_y = ((component >> 1) << 1); 935 936 for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++) /* sub-partition index */ 937 { 938 dcOnlyPredictionFlag = 0; 939 if (block_x > 0) 940 { 941 intra4x4PredModeA = currMB->i4Mode[(block_y << 2) + block_x - 1 ]; 942 } 943 else 944 { 945 if (video->intraAvailA) 946 { 947 if (video->mblock[video->mbAddrA].mbMode == AVC_I4) 948 { 949 intra4x4PredModeA = video->mblock[video->mbAddrA].i4Mode[(block_y << 2) + 3]; 950 } 951 else 952 { 953 intra4x4PredModeA = AVC_I4_DC; 954 } 955 } 956 else 957 { 958 dcOnlyPredictionFlag = 1; 959 } 960 } 961 962 if (block_y > 0) 963 { 964 intra4x4PredModeB = currMB->i4Mode[((block_y-1) << 2) + block_x]; 965 } 966 else 967 { 968 if (video->intraAvailB) 969 { 970 if (video->mblock[video->mbAddrB].mbMode == AVC_I4) 971 { 972 intra4x4PredModeB = video->mblock[video->mbAddrB].i4Mode[(3 << 2) + block_x]; 973 } 974 else 975 { 976 intra4x4PredModeB = AVC_I4_DC; 977 } 978 } 979 else 980 { 981 dcOnlyPredictionFlag = 1; 982 } 983 } 984 985 if (dcOnlyPredictionFlag) 986 { 987 intra4x4PredModeA = intra4x4PredModeB = AVC_I4_DC; 988 } 989 990 predIntra4x4PredMode = AVC_MIN(intra4x4PredModeA, intra4x4PredModeB); 991 992 flag = 0; 993 mode = currMB->i4Mode[(block_y<<2)+block_x]; 994 995 if (mode == (AVCIntra4x4PredMode)predIntra4x4PredMode) 996 { 997 flag = 1; 998 } 999 else if (mode < predIntra4x4PredMode) 1000 { 1001 rem = mode; 1002 } 1003 else 1004 { 1005 rem = mode - 1; 1006 } 1007 1008 BitstreamWrite1Bit(stream, flag); 1009 1010 if (!flag) 1011 { 1012 BitstreamWriteBits(stream, 3, rem); 1013 } 1014 1015 bindx++; 1016 block_y += (SubBlock_indx & 1) ; 1017 block_x += (1 - 2 * (SubBlock_indx & 1)) ; 1018 } 1019 } 1020 1021 return AVCENC_SUCCESS; 1022 } 1023 1024 1025 1026