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
19commented out by macro definition or function pointers. */
20
21#include <string.h>
22
23#include "avcdec_lib.h"
24#include "avcdec_bitstream.h"
25
26const 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() */
29AVCDec_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 */
116AVCDec_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 */
280AVCDec_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 */
389AVCDec_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
448void 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
479void 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
510void 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
550void 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[] */
567void 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
588void 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 */
617AVCDec_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}
715AVCDec_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