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 /* Note for optimization: syntax decoding or operations related to B_SLICE should be
     19 commented out by macro definition or function pointers. */
     20 
     21 #include <string.h>
     22 
     23 #include "avcdec_lib.h"
     24 #include "avcdec_bitstream.h"
     25 
     26 const static int mbPart2raster[3][4] = {{0, 0, 0, 0}, {1, 1, 0, 0}, {1, 0, 1, 0}};
     27 /* decode_frame_slice() */
     28 /* decode_one_slice() */
     29 AVCDec_Status DecodeSlice(AVCDecObject *decvid)
     30 {
     31     AVCDec_Status status;
     32     AVCCommonObj *video = decvid->common;
     33     AVCSliceHeader *sliceHdr = video->sliceHdr;
     34     AVCMacroblock *currMB ;
     35     AVCDecBitstream *stream = decvid->bitstream;
     36     uint slice_group_id;
     37     uint CurrMbAddr, moreDataFlag;
     38 
     39     /* set the first mb in slice */
     40     CurrMbAddr = sliceHdr->first_mb_in_slice;
     41     slice_group_id = video->MbToSliceGroupMap[CurrMbAddr];
     42 
     43     if ((CurrMbAddr && (CurrMbAddr != (uint)(video->mbNum + 1))) && video->currSeqParams->constrained_set1_flag == 1)
     44     {
     45         ConcealSlice(decvid, video->mbNum, CurrMbAddr);
     46     }
     47 
     48     moreDataFlag = 1;
     49     video->mb_skip_run = -1;
     50 
     51 
     52     /* while loop , see subclause 7.3.4 */
     53     do
     54     {
     55         if (CurrMbAddr >= video->PicSizeInMbs)
     56         {
     57             return AVCDEC_FAIL;
     58         }
     59 
     60         currMB = video->currMB = &(video->mblock[CurrMbAddr]);
     61         video->mbNum = CurrMbAddr;
     62         currMB->slice_id = video->slice_id;  //  slice
     63 
     64         /* we can remove this check if we don't support Mbaff. */
     65         /* we can wrap below into an initMB() function which will also
     66         do necessary reset of macroblock related parameters. */
     67 
     68         video->mb_x = CurrMbAddr % video->PicWidthInMbs;
     69         video->mb_y = CurrMbAddr / video->PicWidthInMbs;
     70 
     71         /* check the availability of neighboring macroblocks */
     72         InitNeighborAvailability(video, CurrMbAddr);
     73 
     74         /* read_macroblock and decode_one_macroblock() */
     75         status = DecodeMB(decvid);
     76         if (status != AVCDEC_SUCCESS)
     77         {
     78             return status;
     79         }
     80 #ifdef MB_BASED_DEBLOCK
     81         if (video->currPicParams->num_slice_groups_minus1 == 0)
     82         {
     83             MBInLoopDeblock(video); /* MB-based deblocking */
     84         }
     85         else    /* this mode cannot be used if the number of slice group is not one. */
     86         {
     87             return AVCDEC_FAIL;
     88         }
     89 #endif
     90         video->numMBs--;
     91 
     92         moreDataFlag = more_rbsp_data(stream);
     93 
     94 
     95         /* go to next MB */
     96         while (++CurrMbAddr < video->PicSizeInMbs && video->MbToSliceGroupMap[CurrMbAddr] != (int)slice_group_id)
     97         {
     98         }
     99 
    100     }
    101     while ((moreDataFlag && video->numMBs > 0) || video->mb_skip_run > 0); /* even if no more data, but last few MBs are skipped */
    102 
    103     if (video->numMBs == 0)
    104     {
    105         video->newPic = TRUE;
    106         video->mbNum = 0;  // _Conceal
    107         return AVCDEC_PICTURE_READY;
    108     }
    109 
    110     return AVCDEC_SUCCESS;
    111 }
    112 
    113 /* read MB mode and motion vectors */
    114 /* perform Intra/Inter prediction and residue */
    115 /* update video->mb_skip_run */
    116 AVCDec_Status DecodeMB(AVCDecObject *decvid)
    117 {
    118     AVCDec_Status status;
    119     AVCCommonObj *video = decvid->common;
    120     AVCDecBitstream *stream = decvid->bitstream;
    121     AVCMacroblock *currMB = video->currMB;
    122     uint mb_type;
    123     int slice_type = video->slice_type;
    124     int temp;
    125 
    126     currMB->QPy = video->QPy;
    127     currMB->QPc = video->QPc;
    128 
    129     if (slice_type == AVC_P_SLICE)
    130     {
    131         if (video->mb_skip_run < 0)
    132         {
    133             ue_v(stream, (uint *)&(video->mb_skip_run));
    134         }
    135 
    136         if (video->mb_skip_run == 0)
    137         {
    138             /* this will not handle the case where the slice ends with a mb_skip_run == 0 and no following MB data  */
    139             ue_v(stream, &mb_type);
    140             if (mb_type > 30)
    141             {
    142                 return AVCDEC_FAIL;
    143             }
    144             InterpretMBModeP(currMB, mb_type);
    145             video->mb_skip_run = -1;
    146         }
    147         else
    148         {
    149             /* see subclause 7.4.4 for more details on how
    150             mb_field_decoding_flag is derived in case of skipped MB */
    151 
    152             currMB->mb_intra = FALSE;
    153 
    154             currMB->mbMode = AVC_SKIP;
    155             currMB->MbPartWidth = currMB->MbPartHeight = 16;
    156             currMB->NumMbPart = 1;
    157             currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] =
    158                                           currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1; //
    159             currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] =
    160                                             currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth;
    161             currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] =
    162                                              currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight;
    163 
    164             memset(currMB->nz_coeff, 0, sizeof(uint8)*NUM_BLKS_IN_MB);
    165 
    166             currMB->CBP = 0;
    167             video->cbp4x4 = 0;
    168             /* for skipped MB, always look at the first entry in RefPicList */
    169             currMB->RefIdx[0] = currMB->RefIdx[1] =
    170                                     currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx;
    171             InterMBPrediction(video);
    172             video->mb_skip_run--;
    173             return AVCDEC_SUCCESS;
    174         }
    175 
    176     }
    177     else
    178     {
    179         /* Then decode mode and MV */
    180         ue_v(stream, &mb_type);
    181         if (mb_type > 25)
    182         {
    183             return AVCDEC_FAIL;
    184         }
    185         InterpretMBModeI(currMB, mb_type);
    186     }
    187 
    188 
    189     if (currMB->mbMode != AVC_I_PCM)
    190     {
    191 
    192         if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0)
    193         {
    194             status = sub_mb_pred(video, currMB, stream);
    195         }
    196         else
    197         {
    198             status = mb_pred(video, currMB, stream) ;
    199         }
    200 
    201         if (status != AVCDEC_SUCCESS)
    202         {
    203             return status;
    204         }
    205 
    206         if (currMB->mbMode != AVC_I16)
    207         {
    208             /* decode coded_block_pattern */
    209             status = DecodeCBP(currMB, stream);
    210             if (status != AVCDEC_SUCCESS)
    211             {
    212                 return status;
    213             }
    214         }
    215 
    216         if (currMB->CBP > 0 || currMB->mbMode == AVC_I16)
    217         {
    218             se_v(stream, &temp);
    219             if (temp)
    220             {
    221                 temp += (video->QPy + 52);
    222                 currMB->QPy = video->QPy = temp - 52 * (temp * 79 >> 12);
    223                 if (currMB->QPy > 51 || currMB->QPy < 0)
    224                 {
    225                     video->QPy = AVC_CLIP3(0, 51, video->QPy);
    226 //                  return AVCDEC_FAIL;
    227                 }
    228                 video->QPy_div_6 = (video->QPy * 43) >> 8;
    229                 video->QPy_mod_6 = video->QPy - 6 * video->QPy_div_6;
    230                 currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->QPy + video->currPicParams->chroma_qp_index_offset)];
    231                 video->QPc_div_6 = (video->QPc * 43) >> 8;
    232                 video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6;
    233             }
    234         }
    235         /* decode residue and inverse transform */
    236         status = residual(decvid, currMB);
    237         if (status != AVCDEC_SUCCESS)
    238         {
    239             return status;
    240         }
    241     }
    242     else
    243     {
    244         if (stream->bitcnt & 7)
    245         {
    246             BitstreamByteAlign(stream);
    247         }
    248         /* decode pcm_byte[i] */
    249         DecodeIntraPCM(video, stream);
    250 
    251         currMB->QPy = 0;  /* necessary for deblocking */ // _OPTIMIZE
    252         currMB->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->currPicParams->chroma_qp_index_offset)];
    253 
    254         /* default values, don't know if really needed */
    255         currMB->CBP = 0x3F;
    256         video->cbp4x4 = 0xFFFF;
    257         currMB->mb_intra = TRUE;
    258         memset(currMB->nz_coeff, 16, sizeof(uint8)*NUM_BLKS_IN_MB);
    259         return AVCDEC_SUCCESS;
    260     }
    261 
    262 
    263     /* do Intra/Inter prediction, together with the residue compensation */
    264     /* This part should be common between the skip and no-skip */
    265     if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16)
    266     {
    267         IntraMBPrediction(video);
    268     }
    269     else
    270     {
    271         InterMBPrediction(video);
    272     }
    273 
    274 
    275 
    276     return AVCDEC_SUCCESS;
    277 }
    278 
    279 /* see subclause 7.3.5.1 */
    280 AVCDec_Status mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
    281 {
    282     int mbPartIdx;
    283     AVCSliceHeader *sliceHdr = video->sliceHdr;
    284     uint max_ref_idx;
    285     const int *temp_0;
    286     int16 *temp_1;
    287     uint code;
    288 
    289     if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16)
    290     {
    291 
    292         video->intraAvailA = video->intraAvailB = video->intraAvailC = video->intraAvailD = 0;
    293 
    294         if (!video->currPicParams->constrained_intra_pred_flag)
    295         {
    296             video->intraAvailA = video->mbAvailA;
    297             video->intraAvailB = video->mbAvailB;
    298             video->intraAvailC = video->mbAvailC;
    299             video->intraAvailD = video->mbAvailD;
    300         }
    301         else
    302         {
    303             if (video->mbAvailA)
    304             {
    305                 video->intraAvailA = video->mblock[video->mbAddrA].mb_intra;
    306             }
    307             if (video->mbAvailB)
    308             {
    309                 video->intraAvailB = video->mblock[video->mbAddrB].mb_intra ;
    310             }
    311             if (video->mbAvailC)
    312             {
    313                 video->intraAvailC = video->mblock[video->mbAddrC].mb_intra;
    314             }
    315             if (video->mbAvailD)
    316             {
    317                 video->intraAvailD = video->mblock[video->mbAddrD].mb_intra;
    318             }
    319         }
    320 
    321 
    322         if (currMB->mbMode == AVC_I4)
    323         {
    324             /* perform prediction to get the actual intra 4x4 pred mode */
    325             DecodeIntra4x4Mode(video, currMB, stream);
    326             /* output will be in currMB->i4Mode[4][4] */
    327         }
    328 
    329         ue_v(stream, &code);
    330 
    331         if (code > 3)
    332         {
    333             return AVCDEC_FAIL; /* out of range */
    334         }
    335         currMB->intra_chroma_pred_mode = (AVCIntraChromaPredMode)code;
    336     }
    337     else
    338     {
    339 
    340         memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
    341 
    342         /* see subclause 7.4.5.1 for the range of ref_idx_lX */
    343 //      max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
    344         max_ref_idx = video->refList0Size - 1;
    345 
    346         /* decode ref index for L0 */
    347         if (sliceHdr->num_ref_idx_l0_active_minus1 > 0)
    348         {
    349             for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
    350             {
    351                 te_v(stream, &code, max_ref_idx);
    352                 if (code > (uint)max_ref_idx)
    353                 {
    354                     return AVCDEC_FAIL;
    355                 }
    356                 currMB->ref_idx_L0[mbPartIdx] = code;
    357             }
    358         }
    359 
    360         /* populate ref_idx_L0 */
    361         temp_0 = &mbPart2raster[currMB->mbMode-AVC_P16][0];
    362         temp_1 = &currMB->ref_idx_L0[3];
    363 
    364         *temp_1-- = currMB->ref_idx_L0[*temp_0++];
    365         *temp_1-- = currMB->ref_idx_L0[*temp_0++];
    366         *temp_1-- = currMB->ref_idx_L0[*temp_0++];
    367         *temp_1-- = currMB->ref_idx_L0[*temp_0++];
    368 
    369         /* Global reference index, these values are used in deblock */
    370         currMB->RefIdx[0] = video->RefPicList0[currMB->ref_idx_L0[0]]->RefIdx;
    371         currMB->RefIdx[1] = video->RefPicList0[currMB->ref_idx_L0[1]]->RefIdx;
    372         currMB->RefIdx[2] = video->RefPicList0[currMB->ref_idx_L0[2]]->RefIdx;
    373         currMB->RefIdx[3] = video->RefPicList0[currMB->ref_idx_L0[3]]->RefIdx;
    374 
    375         /* see subclause 7.4.5.1 for the range of ref_idx_lX */
    376         max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
    377         /* decode mvd_l0 */
    378         for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
    379         {
    380             se_v(stream, &(video->mvd_l0[mbPartIdx][0][0]));
    381             se_v(stream, &(video->mvd_l0[mbPartIdx][0][1]));
    382         }
    383     }
    384 
    385     return AVCDEC_SUCCESS;
    386 }
    387 
    388 /* see subclause 7.3.5.2 */
    389 AVCDec_Status sub_mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
    390 {
    391     int mbPartIdx, subMbPartIdx;
    392     AVCSliceHeader *sliceHdr = video->sliceHdr;
    393     uint max_ref_idx;
    394     uint sub_mb_type[4];
    395     uint code;
    396 
    397     memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
    398 
    399     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    400     {
    401         ue_v(stream, &(sub_mb_type[mbPartIdx]));
    402         if (sub_mb_type[mbPartIdx] > 3)
    403         {
    404             return AVCDEC_FAIL;
    405         }
    406 
    407     }
    408     /* we have to check the values to make sure they are valid  */
    409     /* assign values to currMB->sub_mb_type[], currMB->MBPartPredMode[][x] */
    410 
    411     InterpretSubMBModeP(currMB, sub_mb_type);
    412 
    413 
    414     /* see subclause 7.4.5.1 for the range of ref_idx_lX */
    415 //      max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
    416     max_ref_idx = video->refList0Size - 1;
    417 
    418     if (sliceHdr->num_ref_idx_l0_active_minus1 > 0 && currMB->mbMode != AVC_P8ref0)
    419     {
    420         for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    421         {
    422             te_v(stream, (uint*)&code, max_ref_idx);
    423             if (code > max_ref_idx)
    424             {
    425                 return AVCDEC_FAIL;
    426             }
    427             currMB->ref_idx_L0[mbPartIdx] = code;
    428         }
    429     }
    430     /* see subclause 7.4.5.1 for the range of ref_idx_lX */
    431 
    432     max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
    433     /*  if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
    434             max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1;*/
    435     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    436     {
    437         for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
    438         {
    439             se_v(stream, &(video->mvd_l0[mbPartIdx][subMbPartIdx][0]));
    440             se_v(stream, &(video->mvd_l0[mbPartIdx][subMbPartIdx][1]));
    441         }
    442         /* used in deblocking */
    443         currMB->RefIdx[mbPartIdx] = video->RefPicList0[currMB->ref_idx_L0[mbPartIdx]]->RefIdx;
    444     }
    445     return AVCDEC_SUCCESS;
    446 }
    447 
    448 void InterpretMBModeI(AVCMacroblock *mblock, uint mb_type)
    449 {
    450     mblock->NumMbPart = 1;
    451 
    452     mblock->mb_intra = TRUE;
    453 
    454     if (mb_type == 0) /* I_4x4 */
    455     {
    456         mblock->mbMode = AVC_I4;
    457     }
    458     else if (mb_type < 25) /* I_PCM */
    459     {
    460         mblock->mbMode = AVC_I16;
    461         mblock->i16Mode = (AVCIntra16x16PredMode)((mb_type - 1) & 0x3);
    462         if (mb_type > 12)
    463         {
    464             mblock->CBP = (((mb_type - 13) >> 2) << 4) + 0x0F;
    465         }
    466         else
    467         {
    468             mblock->CBP = ((mb_type - 1) >> 2) << 4;
    469         }
    470     }
    471     else
    472     {
    473         mblock->mbMode = AVC_I_PCM;
    474     }
    475 
    476     return ;
    477 }
    478 
    479 void InterpretMBModeP(AVCMacroblock *mblock, uint mb_type)
    480 {
    481     const static int map2PartWidth[5] = {16, 16, 8, 8, 8};
    482     const static int map2PartHeight[5] = {16, 8, 16, 8, 8};
    483     const static int map2NumPart[5] = {1, 2, 2, 4, 4};
    484     const static AVCMBMode map2mbMode[5] = {AVC_P16, AVC_P16x8, AVC_P8x16, AVC_P8, AVC_P8ref0};
    485 
    486     mblock->mb_intra = FALSE;
    487     if (mb_type < 5)
    488     {
    489         mblock->mbMode = map2mbMode[mb_type];
    490         mblock->MbPartWidth = map2PartWidth[mb_type];
    491         mblock->MbPartHeight = map2PartHeight[mb_type];
    492         mblock->NumMbPart = map2NumPart[mb_type];
    493         mblock->NumSubMbPart[0] = mblock->NumSubMbPart[1] =
    494                                       mblock->NumSubMbPart[2] = mblock->NumSubMbPart[3] = 1;
    495         mblock->SubMbPartWidth[0] = mblock->SubMbPartWidth[1] =
    496                                         mblock->SubMbPartWidth[2] = mblock->SubMbPartWidth[3] = mblock->MbPartWidth;
    497         mblock->SubMbPartHeight[0] = mblock->SubMbPartHeight[1] =
    498                                          mblock->SubMbPartHeight[2] = mblock->SubMbPartHeight[3] = mblock->MbPartHeight;
    499     }
    500     else
    501     {
    502         InterpretMBModeI(mblock, mb_type - 5);
    503         /* set MV and Ref_Idx codes of Intra blocks in P-slices  */
    504         memset(mblock->mvL0, 0, sizeof(int32)*16);
    505         mblock->ref_idx_L0[0] = mblock->ref_idx_L0[1] = mblock->ref_idx_L0[2] = mblock->ref_idx_L0[3] = -1;
    506     }
    507     return ;
    508 }
    509 
    510 void InterpretMBModeB(AVCMacroblock *mblock, uint mb_type)
    511 {
    512     const static int map2PartWidth[23] = {8, 16, 16, 16, 16, 8, 16, 8, 16, 8,
    513                                           16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 8
    514                                          };
    515     const static int map2PartHeight[23] = {8, 16, 16, 16, 8, 16, 8, 16, 8,
    516                                            16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8
    517                                           };
    518     /* see enum AVCMBType declaration */
    519     const static AVCMBMode map2mbMode[23] = {AVC_BDirect16, AVC_P16, AVC_P16, AVC_P16,
    520                                             AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16,
    521                                             AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16,
    522                                             AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P16x8, AVC_P8x16, AVC_P8
    523                                             };
    524     const static int map2PredMode1[23] = {3, 0, 1, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, -1};
    525     const static int map2PredMode2[23] = { -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, -1};
    526     const static int map2NumPart[23] = { -1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4};
    527 
    528     mblock->mb_intra = FALSE;
    529 
    530     if (mb_type < 23)
    531     {
    532         mblock->mbMode = map2mbMode[mb_type];
    533         mblock->NumMbPart = map2NumPart[mb_type];
    534         mblock->MBPartPredMode[0][0] = (AVCPredMode)map2PredMode1[mb_type];
    535         if (mblock->NumMbPart > 1)
    536         {
    537             mblock->MBPartPredMode[1][0] = (AVCPredMode)map2PredMode2[mb_type];
    538         }
    539         mblock->MbPartWidth = map2PartWidth[mb_type];
    540         mblock->MbPartHeight = map2PartHeight[mb_type];
    541     }
    542     else
    543     {
    544         InterpretMBModeI(mblock, mb_type - 23);
    545     }
    546 
    547     return ;
    548 }
    549 
    550 void InterpretMBModeSI(AVCMacroblock *mblock, uint mb_type)
    551 {
    552     mblock->mb_intra = TRUE;
    553 
    554     if (mb_type == 0)
    555     {
    556         mblock->mbMode = AVC_SI4;
    557         /* other values are N/A */
    558     }
    559     else
    560     {
    561         InterpretMBModeI(mblock, mb_type - 1);
    562     }
    563     return ;
    564 }
    565 
    566 /* input is mblock->sub_mb_type[] */
    567 void InterpretSubMBModeP(AVCMacroblock *mblock, uint *sub_mb_type)
    568 {
    569     int i,  sub_type;
    570     /* see enum AVCMBType declaration */
    571 //  const static AVCSubMBMode map2subMbMode[4] = {AVC_8x8,AVC_8x4,AVC_4x8,AVC_4x4};
    572     const static int map2subPartWidth[4] = {8, 8, 4, 4};
    573     const static int map2subPartHeight[4] = {8, 4, 8, 4};
    574     const static int map2numSubPart[4] = {1, 2, 2, 4};
    575 
    576     for (i = 0; i < 4 ; i++)
    577     {
    578         sub_type = (int) sub_mb_type[i];
    579         //  mblock->subMbMode[i] = map2subMbMode[sub_type];
    580         mblock->NumSubMbPart[i] = map2numSubPart[sub_type];
    581         mblock->SubMbPartWidth[i] = map2subPartWidth[sub_type];
    582         mblock->SubMbPartHeight[i] = map2subPartHeight[sub_type];
    583     }
    584 
    585     return ;
    586 }
    587 
    588 void InterpretSubMBModeB(AVCMacroblock *mblock, uint *sub_mb_type)
    589 {
    590     int i, j, sub_type;
    591     /* see enum AVCMBType declaration */
    592     const static AVCSubMBMode map2subMbMode[13] = {AVC_BDirect8, AVC_8x8, AVC_8x8,
    593             AVC_8x8, AVC_8x4, AVC_4x8, AVC_8x4, AVC_4x8, AVC_8x4, AVC_4x8, AVC_4x4, AVC_4x4, AVC_4x4
    594                                                   };
    595     const static int map2subPartWidth[13] = {4, 8, 8, 8, 8, 4, 8, 4, 8, 4, 4, 4, 4};
    596     const static int map2subPartHeight[13] = {4, 8, 8, 8, 4, 8, 4, 8, 4, 8, 4, 4, 4};
    597     const static int map2numSubPart[13] = {1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4};
    598     const static int map2predMode[13] = {3, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2};
    599 
    600     for (i = 0; i < 4 ; i++)
    601     {
    602         sub_type = (int) sub_mb_type[i];
    603         mblock->subMbMode[i] = map2subMbMode[sub_type];
    604         mblock->NumSubMbPart[i] = map2numSubPart[sub_type];
    605         mblock->SubMbPartWidth[i] = map2subPartWidth[sub_type];
    606         mblock->SubMbPartHeight[i] = map2subPartHeight[sub_type];
    607         for (j = 0; j < 4; j++)
    608         {
    609             mblock->MBPartPredMode[i][j] = (AVCPredMode)map2predMode[sub_type];
    610         }
    611     }
    612 
    613     return ;
    614 }
    615 
    616 /* see subclause 8.3.1 */
    617 AVCDec_Status DecodeIntra4x4Mode(AVCCommonObj *video, AVCMacroblock *currMB, AVCDecBitstream *stream)
    618 {
    619     int intra4x4PredModeA = 0, intra4x4PredModeB = 0, predIntra4x4PredMode = 0;
    620     int component, SubBlock_indx, block_x, block_y;
    621     int dcOnlyPredictionFlag;
    622     uint    prev_intra4x4_pred_mode_flag[16];
    623     int     rem_intra4x4_pred_mode[16];
    624     int bindx = 0;
    625 
    626     for (component = 0; component < 4; component++) /* partition index */
    627     {
    628         block_x = ((component & 1) << 1);
    629         block_y = ((component >> 1) << 1);
    630 
    631         for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++) /* sub-partition index */
    632         {
    633             BitstreamRead1Bit(stream, &(prev_intra4x4_pred_mode_flag[bindx]));
    634 
    635             if (!prev_intra4x4_pred_mode_flag[bindx])
    636             {
    637                 BitstreamReadBits(stream, 3, (uint*)&(rem_intra4x4_pred_mode[bindx]));
    638             }
    639 
    640             dcOnlyPredictionFlag = 0;
    641             if (block_x > 0)
    642             {
    643                 intra4x4PredModeA = currMB->i4Mode[(block_y << 2) + block_x - 1 ];
    644             }
    645             else
    646             {
    647                 if (video->intraAvailA)
    648                 {
    649                     if (video->mblock[video->mbAddrA].mbMode == AVC_I4)
    650                     {
    651                         intra4x4PredModeA = video->mblock[video->mbAddrA].i4Mode[(block_y << 2) + 3];
    652                     }
    653                     else
    654                     {
    655                         intra4x4PredModeA = AVC_I4_DC;
    656                     }
    657                 }
    658                 else
    659                 {
    660                     dcOnlyPredictionFlag = 1;
    661                 }
    662             }
    663 
    664             if (block_y > 0)
    665             {
    666                 intra4x4PredModeB = currMB->i4Mode[((block_y-1) << 2) + block_x];
    667             }
    668             else
    669             {
    670                 if (video->intraAvailB)
    671                 {
    672                     if (video->mblock[video->mbAddrB].mbMode == AVC_I4)
    673                     {
    674                         intra4x4PredModeB = video->mblock[video->mbAddrB].i4Mode[(3 << 2) + block_x];
    675                     }
    676                     else
    677                     {
    678                         intra4x4PredModeB = AVC_I4_DC;
    679                     }
    680                 }
    681                 else
    682                 {
    683                     dcOnlyPredictionFlag = 1;
    684                 }
    685             }
    686 
    687             if (dcOnlyPredictionFlag)
    688             {
    689                 intra4x4PredModeA = intra4x4PredModeB = AVC_I4_DC;
    690             }
    691 
    692             predIntra4x4PredMode = AVC_MIN(intra4x4PredModeA, intra4x4PredModeB);
    693             if (prev_intra4x4_pred_mode_flag[bindx])
    694             {
    695                 currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)predIntra4x4PredMode;
    696             }
    697             else
    698             {
    699                 if (rem_intra4x4_pred_mode[bindx] < predIntra4x4PredMode)
    700                 {
    701                     currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)rem_intra4x4_pred_mode[bindx];
    702                 }
    703                 else
    704                 {
    705                     currMB->i4Mode[(block_y<<2)+block_x] = (AVCIntra4x4PredMode)(rem_intra4x4_pred_mode[bindx] + 1);
    706                 }
    707             }
    708             bindx++;
    709             block_y += (SubBlock_indx & 1) ;
    710             block_x += (1 - 2 * (SubBlock_indx & 1)) ;
    711         }
    712     }
    713     return AVCDEC_SUCCESS;
    714 }
    715 AVCDec_Status ConcealSlice(AVCDecObject *decvid, int mbnum_start, int mbnum_end)
    716 {
    717     AVCCommonObj *video = decvid->common;
    718     AVCMacroblock *currMB ;
    719 
    720     int CurrMbAddr;
    721 
    722     if (video->RefPicList0[0] == NULL)
    723     {
    724         return AVCDEC_FAIL;
    725     }
    726 
    727     for (CurrMbAddr = mbnum_start; CurrMbAddr < mbnum_end; CurrMbAddr++)
    728     {
    729         currMB = video->currMB = &(video->mblock[CurrMbAddr]);
    730         video->mbNum = CurrMbAddr;
    731         currMB->slice_id = video->slice_id++;  //  slice
    732 
    733         /* we can remove this check if we don't support Mbaff. */
    734         /* we can wrap below into an initMB() function which will also
    735         do necessary reset of macroblock related parameters. */
    736 
    737         video->mb_x = CurrMbAddr % video->PicWidthInMbs;
    738         video->mb_y = CurrMbAddr / video->PicWidthInMbs;
    739 
    740         /* check the availability of neighboring macroblocks */
    741         InitNeighborAvailability(video, CurrMbAddr);
    742 
    743         currMB->mb_intra = FALSE;
    744 
    745         currMB->mbMode = AVC_SKIP;
    746         currMB->MbPartWidth = currMB->MbPartHeight = 16;
    747 
    748         currMB->NumMbPart = 1;
    749         currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] =
    750                                       currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1;
    751         currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] =
    752                                         currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth;
    753         currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] =
    754                                          currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight;
    755         currMB->QPy = 26;
    756         currMB->QPc = 26;
    757         memset(currMB->nz_coeff, 0, sizeof(uint8)*NUM_BLKS_IN_MB);
    758 
    759         currMB->CBP = 0;
    760         video->cbp4x4 = 0;
    761         /* for skipped MB, always look at the first entry in RefPicList */
    762         currMB->RefIdx[0] = currMB->RefIdx[1] =
    763                                 currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx;
    764         InterMBPrediction(video);
    765 
    766         video->numMBs--;
    767 
    768     }
    769 
    770     return AVCDEC_SUCCESS;
    771 }
    772 
    773