Home | History | Annotate | Download | only in src
      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