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 "mp4dec_lib.h"
     19 #include "vlc_decode.h"
     20 #include "bitstream.h"
     21 #include "scaling.h"
     22 #include "mbtype_mode.h"
     23 #include "idct.h"
     24 
     25 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
     26 /* ======================================================================== */
     27 /*  Function : DecodeFrameDataPartMode()                                    */
     28 /*  Purpose  : Decode a frame of MPEG4 bitstream in datapartitioning mode.  */
     29 /*  In/out   :                                                              */
     30 /*  Return   :                                                              */
     31 /*  Modified :                                                              */
     32 /*                                                                          */
     33 /*      04/25/2000 : Rewrite the data partitioning path completely  */
     34 /*                           according to the pseudo codes in MPEG-4        */
     35 /*                           standard.                                      */
     36 /*  Modified : 09/18/2000 add fast VlcDecode+Dequant                    */
     37 /*             04/17/2001 cleanup                                       */
     38 /* ======================================================================== */
     39 PV_STATUS DecodeFrameDataPartMode(VideoDecData *video)
     40 {
     41     PV_STATUS status;
     42     Vop *currVop = video->currVop;
     43     BitstreamDecVideo *stream = video->bitstream;
     44 
     45     int nMBPerRow = video->nMBPerRow;
     46 
     47     int vopType = currVop->predictionType;
     48     int mbnum;
     49     int nTotalMB = video->nTotalMB;
     50     int slice_counter;
     51     int resync_marker_length;
     52 
     53     /* copy and pad to prev_Vop for INTER coding */
     54     switch (vopType)
     55     {
     56         case I_VOP :
     57 //      oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB);
     58             resync_marker_length = 17;
     59             break;
     60         case P_VOP :
     61             oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB);
     62             oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB);
     63 //      oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB);
     64             resync_marker_length = 16 + currVop->fcodeForward;
     65             break;
     66         default :
     67             mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n");
     68             return PV_FAIL;
     69     }
     70 
     71     /** Initialize sliceNo ***/
     72     mbnum = slice_counter = 0;
     73 //  oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB);
     74 
     75     do
     76     {
     77         /* This section is equivalent to motion_shape_texture() */
     78         /* in the MPEG-4 standard.            04/13/2000      */
     79         video->mbnum = mbnum;
     80         video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);   /*  This is needed if nbnum is read from the packet header */
     81         video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
     82 
     83         switch (vopType)
     84         {
     85             case I_VOP :
     86                 status = DecodeDataPart_I_VideoPacket(video, slice_counter);
     87                 break;
     88 
     89             case P_VOP :
     90                 status = DecodeDataPart_P_VideoPacket(video, slice_counter);
     91                 break;
     92 
     93             default :
     94                 mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n");
     95                 return PV_FAIL;
     96         }
     97 
     98         while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL)
     99         {
    100             if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS)
    101             {
    102                 break;
    103             }
    104         }
    105 
    106         if (status == PV_END_OF_VOP)
    107         {
    108             mbnum = nTotalMB;
    109         }
    110 
    111         if (mbnum > video->mbnum + 1)
    112         {
    113             ConcealPacket(video, video->mbnum, mbnum, slice_counter);
    114         }
    115         slice_counter++;
    116         if (mbnum >= nTotalMB)
    117         {
    118             break;
    119         }
    120 
    121 
    122     }
    123     while (TRUE);
    124 
    125     return PV_SUCCESS;
    126 }
    127 
    128 
    129 /* ======================================================================== */
    130 /*  Function : DecodeDataPart_I_VideoPacket()                               */
    131 /*  Date     : 04/25/2000                                                   */
    132 /*  Purpose  : Decode Data Partitioned Mode Video Packet in I-VOP           */
    133 /*  In/out   :                                                              */
    134 /*  Return   : PV_SUCCESS if successed, PV_FAIL if failed.                  */
    135 /*  Modified : 09/18/2000 add fast VlcDecode+Dequant                    */
    136 /*             04/01/2001 fixed MB_stuffing, removed unnecessary code   */
    137 /* ======================================================================== */
    138 PV_STATUS DecodeDataPart_I_VideoPacket(VideoDecData *video, int slice_counter)
    139 {
    140     PV_STATUS status;
    141     uint8 *Mode = video->headerInfo.Mode;
    142     BitstreamDecVideo *stream = video->bitstream;
    143     int  nTotalMB = video->nTotalMB;
    144     int  mbnum, mb_start, mb_end;
    145     int16 QP, *QPMB = video->QPMB;
    146     int  MBtype, MCBPC, CBPY;
    147     uint32 tmpvar;
    148     uint code;
    149     int nMBPerRow = video->nMBPerRow;
    150     Bool valid_stuffing;
    151     int32 startSecondPart, startFirstPart = getPointer(stream);
    152 
    153     /* decode the first partition */
    154     QP = video->currVop->quantizer;
    155     mb_start = mbnum = video->mbnum;
    156     video->usePrevQP = 0;         /*  04/27/01 */
    157 
    158 
    159     BitstreamShowBits16(stream, 9, &code);
    160     while (code == 1)
    161     {
    162         PV_BitstreamFlushBits(stream, 9);
    163         BitstreamShowBits16(stream, 9, &code);
    164     }
    165 
    166     do
    167     {
    168         /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
    169         MCBPC = PV_VlcDecMCBPC_com_intra(stream);
    170 
    171         if (!VLC_ERROR_DETECTED(MCBPC))
    172         {
    173             Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]);
    174             video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3);
    175             status = GetMBheaderDataPart_DQUANT_DC(video, &QP);
    176             video->usePrevQP = 1;        /* set it after the first coded MB      04/27/01 */
    177         }
    178         else
    179         {
    180             /* Report the error to the application.   06/20/2000 */
    181             VideoDecoderErrorDetected(video);
    182             video->mbnum = mb_start;
    183             movePointerTo(stream, startFirstPart);
    184             return PV_FAIL;
    185         }
    186 
    187         video->sliceNo[mbnum] = (uint8) slice_counter;
    188         QPMB[mbnum] = QP;
    189         video->mbnum = ++mbnum;
    190 
    191         BitstreamShowBits16(stream, 9, &code);
    192         while (code == 1)
    193         {
    194             PV_BitstreamFlushBits(stream, 9);
    195             BitstreamShowBits16(stream, 9, &code);
    196         }
    197         /* have we reached the end of the video packet or vop? */
    198         status = BitstreamShowBits32(stream, DC_MARKER_LENGTH, &tmpvar);
    199 
    200     }
    201     while (tmpvar != DC_MARKER && video->mbnum < nTotalMB);
    202 
    203     if (tmpvar == DC_MARKER)
    204     {
    205         PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH);
    206     }
    207     else
    208     {
    209         status = quickSearchDCM(stream);
    210         if (status == PV_SUCCESS)
    211         {
    212             /* only way you can end up being here is in the last packet,and there is stuffing at
    213             the end of the first partition */
    214             PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH);
    215         }
    216         else
    217         {
    218             /* Report the error to the application.   06/20/2000 */
    219             VideoDecoderErrorDetected(video);
    220             movePointerTo(stream, startFirstPart);
    221             video->mbnum = mb_start;
    222             /* concealment will be taken care of in the upper layer */
    223             return PV_FAIL;
    224         }
    225     }
    226 
    227     /* decode the second partition */
    228     startSecondPart = getPointer(stream);
    229 
    230     mb_end = video->mbnum;
    231 
    232     for (mbnum = mb_start; mbnum < mb_end; mbnum++)
    233     {
    234         MBtype = Mode[mbnum];
    235         /* No skipped mode in I-packets  3/1/2001    */
    236         video->mbnum = mbnum;
    237 
    238         video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);   /*  This is needed if nbnum is read from the packet header */
    239         video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
    240         /* there is always acdcpred in DataPart mode  04/10/01 */
    241         video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream);
    242 
    243         CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* MODE_INTRA || MODE_INTRA_Q */
    244         if (CBPY < 0)
    245         {
    246             /* Report the error to the application.   06/20/2000 */
    247             VideoDecoderErrorDetected(video);
    248             movePointerTo(stream, startSecondPart); /*  */
    249             /* Conceal packet,  05/15/2000 */
    250             ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
    251             return PV_FAIL;
    252         }
    253 
    254         video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2);
    255     }
    256 
    257     video->usePrevQP = 0;
    258 
    259     for (mbnum = mb_start; mbnum < mb_end; mbnum++)
    260     {
    261         video->mbnum = mbnum;
    262 
    263         video->mbnum_row = PV_GET_ROW(mbnum , nMBPerRow);  /*  This is needed if nbnum is read from the packet header */
    264         video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
    265         /* No skipped mode in I-packets  3/1/2001    */
    266         /* decode the DCT coeficients for the MB */
    267         status = GetMBData_DataPart(video);
    268         if (status != PV_SUCCESS)
    269         {
    270             /* Report the error to the application.   06/20/2000 */
    271             VideoDecoderErrorDetected(video);
    272             movePointerTo(stream, startSecondPart); /*  */
    273             /* Conceal packet,  05/15/2000 */
    274             ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
    275             return status;
    276         }
    277         video->usePrevQP = 1;           /*  04/27/01 should be set after decoding first MB */
    278     }
    279 
    280     valid_stuffing = validStuffing(stream);
    281     if (!valid_stuffing)
    282     {
    283         VideoDecoderErrorDetected(video);
    284         movePointerTo(stream, startSecondPart);
    285         ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
    286         return PV_FAIL;
    287     }
    288     return PV_SUCCESS;
    289 }
    290 
    291 
    292 /* ======================================================================== */
    293 /*  Function : DecodeDataPart_P_VideoPacket()                               */
    294 /*  Date     : 04/25/2000                                                   */
    295 /*  Purpose  : Decode Data Partitioned Mode Video Packet in P-VOP           */
    296 /*  In/out   :                                                              */
    297 /*  Return   : PV_SUCCESS if successed, PV_FAIL if failed.                  */
    298 /*  Modified :   09/18/2000,  fast VlcDecode+Dequant                        */
    299 /*              04/13/2001,  fixed MB_stuffing, new ACDC pred structure,  */
    300 /*                              cleanup                                     */
    301 /*              08/07/2001,  remove MBzero                              */
    302 /* ======================================================================== */
    303 PV_STATUS DecodeDataPart_P_VideoPacket(VideoDecData *video, int slice_counter)
    304 {
    305     PV_STATUS status;
    306     uint8 *Mode = video->headerInfo.Mode;
    307     BitstreamDecVideo *stream = video->bitstream;
    308     int nTotalMB = video->nTotalMB;
    309     int mbnum, mb_start, mb_end;
    310     int16 QP, *QPMB = video->QPMB;
    311     int MBtype, CBPY;
    312     Bool valid_stuffing;
    313     int intra_MB;
    314     uint32 tmpvar;
    315     uint code;
    316     int32  startFirstPart, startSecondPart;
    317     int nMBPerRow = video->nMBPerRow;
    318     uint8 *pbyte;
    319     /* decode the first partition */
    320     startFirstPart = getPointer(stream);
    321     mb_start = video->mbnum;
    322     video->usePrevQP = 0;            /*  04/27/01 */
    323 
    324     BitstreamShowBits16(stream, 10, &code);
    325     while (code == 1)
    326     {
    327         PV_BitstreamFlushBits(stream, 10);
    328         BitstreamShowBits16(stream, 10, &code);
    329     }
    330 
    331     do
    332     {
    333         /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
    334         /* We have to discard stuffed MB header */
    335 
    336         status = GetMBheaderDataPart_P(video);
    337 
    338         if (status != PV_SUCCESS)
    339         {
    340             /* Report the error to the application.   06/20/2000 */
    341             VideoDecoderErrorDetected(video);
    342             movePointerTo(stream, startFirstPart);
    343             video->mbnum = mb_start;
    344             return PV_FAIL;
    345         }
    346 
    347         /* we must update slice_counter before motion vector decoding.   */
    348         video->sliceNo[video->mbnum] = (uint8) slice_counter;
    349 
    350         if (Mode[video->mbnum] & INTER_MASK) /* INTER || INTER_Q || INTER_4V */
    351         {
    352             /* decode the motion vector (if there are any) */
    353             status = PV_GetMBvectors(video, Mode[video->mbnum]);
    354             if (status != PV_SUCCESS)
    355             {
    356                 /* Report the error to the application.   06/20/2000 */
    357                 VideoDecoderErrorDetected(video);
    358                 movePointerTo(stream, startFirstPart);
    359                 video->mbnum = mb_start;
    360                 return PV_FAIL;
    361             }
    362         }
    363         video->mbnum++;
    364 
    365         video->mbnum_row = PV_GET_ROW(video->mbnum, nMBPerRow);   /*  This is needed if mbnum is read from the packet header */
    366         video->mbnum_col = video->mbnum - video->mbnum_row * nMBPerRow;
    367 
    368         BitstreamShowBits16(stream, 10, &code);
    369         while (code == 1)
    370         {
    371             PV_BitstreamFlushBits(stream, 10);
    372             BitstreamShowBits16(stream, 10, &code);
    373         }
    374         /* have we reached the end of the video packet or vop? */
    375         status = BitstreamShowBits32(stream, MOTION_MARKER_COMB_LENGTH, &tmpvar);
    376         /*      if (status != PV_SUCCESS && status != PV_END_OF_BUFFER) return status;  */
    377     }
    378     while (tmpvar != MOTION_MARKER_COMB && video->mbnum < nTotalMB);
    379 
    380     if (tmpvar == MOTION_MARKER_COMB)
    381     {
    382         PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH);
    383     }
    384     else
    385     {
    386         status = quickSearchMotionMarker(stream);
    387         if (status == PV_SUCCESS)
    388         {
    389             /* only way you can end up being here is in the last packet,and there is stuffing at
    390             the end of the first partition */
    391             PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH);
    392         }
    393         else
    394         {
    395             /* Report the error to the application.   06/20/2000 */
    396             VideoDecoderErrorDetected(video);
    397             movePointerTo(stream, startFirstPart);
    398             video->mbnum = mb_start;
    399             /* concealment will be taken care of in the upper layer  */
    400             return PV_FAIL;
    401         }
    402     }
    403 
    404     /* decode the second partition */
    405     startSecondPart = getPointer(stream);
    406     QP = video->currVop->quantizer;
    407 
    408     mb_end = video->mbnum;
    409 
    410     for (mbnum = mb_start; mbnum < mb_end; mbnum++)
    411     {
    412         MBtype = Mode[mbnum];
    413 
    414         if (MBtype == MODE_SKIPPED)
    415         {
    416             QPMB[mbnum] = QP; /*  03/01/01 */
    417             continue;
    418         }
    419         intra_MB = (MBtype & INTRA_MASK); /* (MBtype == MODE_INTRA || MBtype == MODE_INTRA_Q) */
    420         video->mbnum = mbnum;
    421         video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);   /*  This is needed if nbnum is read from the packet header */
    422         video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
    423 
    424         /* there is always acdcprediction in DataPart mode    04/10/01 */
    425         if (intra_MB)
    426         {
    427             video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream);
    428         }
    429 
    430         CBPY = PV_VlcDecCBPY(stream, intra_MB);
    431         if (CBPY < 0)
    432         {
    433             /* Report the error to the application.   06/20/2000 */
    434             VideoDecoderErrorDetected(video);
    435             /* Conceal second partition,  5/15/2000 */
    436             movePointerTo(stream, startSecondPart);
    437             ConcealTexture_P(video, mb_start, mb_end, slice_counter);
    438             return PV_FAIL;
    439         }
    440 
    441         video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2);
    442         if (intra_MB || MBtype == MODE_INTER_Q)                     /*  04/26/01 */
    443         {
    444             status = GetMBheaderDataPart_DQUANT_DC(video, &QP);
    445             if (status != PV_SUCCESS) return status;
    446         }
    447         video->usePrevQP = 1;        /*  04/27/01 */
    448         QPMB[mbnum] = QP;
    449     }
    450 
    451     video->usePrevQP = 0;  /*  04/27/01 */
    452 
    453     for (mbnum = mb_start; mbnum < mb_end; mbnum++)
    454     {
    455         video->mbnum = mbnum;
    456         video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);  /*  This is needed if nbnum is read from the packet header */
    457         video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
    458 
    459 
    460         if (Mode[mbnum] != MODE_SKIPPED)
    461         {
    462             /* decode the DCT coeficients for the MB */
    463             status = GetMBData_DataPart(video);
    464             if (status != PV_SUCCESS)
    465             {
    466                 /* Report the error to the application.   06/20/2000 */
    467                 VideoDecoderErrorDetected(video);
    468 
    469                 /* Conceal second partition,  5/15/2000 */
    470                 movePointerTo(stream, startSecondPart);
    471                 ConcealTexture_P(video, mb_start, mb_end, slice_counter);
    472                 return status;
    473             }
    474             video->usePrevQP = 1;  /*  04/27/01 */
    475         }
    476         else
    477         {   // SKIPPED
    478 
    479             /* Motion compensation and put it to video->mblock->pred_block */
    480             SkippedMBMotionComp(video);
    481 
    482             //oscl_memset(video->predDCAC_row + video->mbnum_col, 0, sizeof(typeDCACStore)); /*  SKIPPED_ACDC */
    483             //oscl_memset(video->predDCAC_col, 0, sizeof(typeDCACStore));
    484             /*  08/08/2005 */
    485             pbyte = (uint8*)(video->predDCAC_row + video->mbnum_col);
    486             ZERO_OUT_64BYTES(pbyte);
    487             pbyte = (uint8*)(video->predDCAC_col);
    488             ZERO_OUT_64BYTES(pbyte);
    489 
    490         }
    491     }
    492 
    493     valid_stuffing = validStuffing(stream);   /*  */
    494     if (!valid_stuffing)
    495     {
    496         VideoDecoderErrorDetected(video);
    497         movePointerTo(stream, startSecondPart); /*  */
    498         ConcealTexture_P(video, mb_start, mb_end, slice_counter);
    499 
    500         return PV_FAIL;
    501     }
    502     return PV_SUCCESS;
    503 }
    504 
    505 
    506 /* ======================================================================== */
    507 /*  Function : GetMBheaderDataPart_DQUANT_DC()                              */
    508 /*  Date     : 04/26/2000                                                   */
    509 /*  Purpose  : Decode DQUANT and DC in Data Partitioned Mode for both       */
    510 /*             I-VOP and P-VOP.                                             */
    511 /*  In/out   :                                                              */
    512 /*  Return   : PV_SUCCESS if successed, PV_FAIL if failed.                  */
    513 /*  Modified : 02/13/2001 new ACDC prediction structure,        */
    514 /*                                       cleanup                            */
    515 /* ======================================================================== */
    516 PV_STATUS GetMBheaderDataPart_DQUANT_DC(VideoDecData *video, int16 *QP)
    517 {
    518     PV_STATUS status = PV_SUCCESS;
    519     BitstreamDecVideo *stream = video->bitstream;
    520     int mbnum = video->mbnum;
    521     int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
    522     uint8 *Mode = video->headerInfo.Mode;
    523     int  MBtype = Mode[mbnum];
    524     typeDCStore *DC = video->predDC + mbnum;
    525     int  comp;
    526     Bool switched;
    527     uint  DQUANT;
    528     int16 QP_tmp;
    529 
    530     const static int  DQ_tab[4] = { -1, -2, 1, 2};
    531 
    532     if (MBtype & Q_MASK)             /* INTRA_Q || INTER_Q */
    533     {
    534         DQUANT = BitstreamReadBits16(stream, 2);
    535         *QP += DQ_tab[DQUANT];
    536 
    537         if (*QP < 1) *QP = 1;
    538         else if (*QP > 31) *QP = 31;
    539     }
    540     if (MBtype & INTRA_MASK)  /* INTRA || INTRA_Q */ /* no switch, code DC separately */
    541     {
    542         QP_tmp = *QP;                      /* running QP  04/26/01*/
    543         switched = 0;
    544         if (intra_dc_vlc_thr)                 /*  04/27/01 */
    545         {
    546             if (video->usePrevQP)
    547                 QP_tmp = video->QPMB[mbnum-1];
    548             switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
    549         }
    550         if (!switched)
    551         {
    552             for (comp = 0; comp < 6; comp++)
    553             {
    554                 status = PV_DecodePredictedIntraDC(comp, stream, (*DC + comp));   /*  03/01/01 */
    555                 if (status != PV_SUCCESS) return PV_FAIL;
    556             }
    557         }
    558         else
    559         {
    560             for (comp = 0; comp < 6; comp++)
    561             {
    562                 (*DC)[comp] = 0;   /*  04/26/01 needed for switched case*/
    563             }
    564         }
    565     }
    566     return status;
    567 }
    568 
    569 
    570 /***********************************************************CommentBegin******
    571 *       04/25/2000 : Initial modification to the new PV Lib format.
    572 *       04/17/2001 : new ACDC pred structure
    573 ***********************************************************CommentEnd********/
    574 PV_STATUS GetMBheaderDataPart_P(VideoDecData *video)
    575 {
    576     BitstreamDecVideo *stream = video->bitstream;
    577     int mbnum = video->mbnum;
    578     uint8 *Mode = video->headerInfo.Mode;
    579     typeDCStore *DC = video->predDC + mbnum;
    580     uint no_dct_flag;
    581     int comp;
    582     int MCBPC;
    583 
    584     no_dct_flag = BitstreamRead1Bits_INLINE(stream);
    585 
    586     if (no_dct_flag)
    587     {
    588         /* skipped macroblock */
    589         Mode[mbnum] = MODE_SKIPPED;
    590 
    591         for (comp = 0; comp < 6; comp++)
    592         {
    593             (*DC)[comp] = mid_gray;
    594             /*  ACDC REMOVE AC coefs are set in DecodeDataPart_P */
    595         }
    596     }
    597     else
    598     {
    599         /* coded macroblock */
    600         MCBPC = PV_VlcDecMCBPC_com_inter(stream);
    601 
    602         if (VLC_ERROR_DETECTED(MCBPC))
    603         {
    604             return PV_FAIL;
    605         }
    606 
    607         Mode[mbnum] = (uint8)MBtype_mode[MCBPC & 7];
    608         video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3);
    609     }
    610 
    611     return PV_SUCCESS;
    612 }
    613 
    614 
    615 /***********************************************************CommentBegin******
    616 *       04/17/01  new ACDC pred structure, reorganized code, cleanup
    617 ***********************************************************CommentEnd********/
    618 PV_STATUS GetMBData_DataPart(VideoDecData *video)
    619 {
    620     int mbnum = video->mbnum;
    621     int16 *dataBlock;
    622     MacroBlock *mblock = video->mblock;
    623     int QP = video->QPMB[mbnum];
    624     int32 offset;
    625     PIXEL *c_comp;
    626     int width = video->width;
    627     int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
    628     uint CBP = video->headerInfo.CBP[mbnum];
    629     uint8 mode = video->headerInfo.Mode[mbnum];
    630     int x_pos = video->mbnum_col;
    631     typeDCStore *DC = video->predDC + mbnum;
    632     int  ncoeffs[6], *no_coeff = mblock->no_coeff;
    633     int  comp;
    634     Bool  switched;
    635     int QP_tmp = QP;
    636 
    637     int y_pos = video->mbnum_row;
    638 #ifdef PV_POSTPROC_ON
    639     uint8 *pp_mod[6];
    640     int TotalMB = video->nTotalMB;
    641     int MB_in_width = video->nMBPerRow;
    642 #endif
    643 
    644 
    645 
    646     /*****
    647     *     Decoding of the 6 blocks (depending on transparent pattern)
    648     *****/
    649 #ifdef PV_POSTPROC_ON
    650     if (video->postFilterType != PV_NO_POST_PROC)
    651     {
    652         /** post-processing ***/
    653         pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
    654         pp_mod[1] = pp_mod[0] + 1;
    655         pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
    656         pp_mod[3] = pp_mod[2] + 1;
    657         pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
    658         pp_mod[5] = pp_mod[4] + TotalMB;
    659     }
    660 #endif
    661 
    662     /*  oscl_memset(mblock->block, 0, sizeof(typeMBStore));    Aug 9,2005 */
    663 
    664     if (mode & INTRA_MASK) /* MODE_INTRA || mode == MODE_INTRA_Q */
    665     {
    666         switched = 0;
    667         if (intra_dc_vlc_thr)
    668         {
    669             if (video->usePrevQP)
    670                 QP_tmp = video->QPMB[mbnum-1];   /* running QP  04/26/01 */
    671 
    672             switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
    673         }
    674 
    675         mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE);     /*   ACDC 03/01/01 */
    676         mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE);
    677 
    678         for (comp = 0; comp < 6; comp++)
    679         {
    680             dataBlock = mblock->block[comp];    /*, 10/20/2000 */
    681 
    682             dataBlock[0] = (*DC)[comp];
    683 
    684             ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp,
    685                             switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
    686 
    687             if (VLC_ERROR_DETECTED(ncoeffs[comp]))         /*  */
    688             {
    689                 if (switched)
    690                     return PV_FAIL;
    691                 else
    692                 {
    693                     ncoeffs[comp] = 1;
    694                     oscl_memset((dataBlock + 1), 0, sizeof(int16)*63);
    695                 }
    696             }
    697             no_coeff[comp] = ncoeffs[comp];
    698             /*  modified to new semaphore for post-proc */
    699             // Future work:: can be combined in the dequant function
    700             // @todo Deblocking Semaphore for INTRA block
    701 #ifdef PV_POSTPROC_ON
    702             if (video->postFilterType != PV_NO_POST_PROC)
    703                 *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
    704 #endif
    705         }
    706         MBlockIDCT(video);
    707     }
    708     else /* MODE INTER*/
    709     {
    710 
    711 
    712 
    713 
    714         MBMotionComp(video, CBP);
    715         offset = (int32)(y_pos << 4) * width + (x_pos << 4);
    716         c_comp  = video->currVop->yChan + offset;
    717 
    718 
    719         for (comp = 0; comp < 4; comp++)
    720         {
    721             (*DC)[comp] = mid_gray;
    722 
    723             if (CBP & (1 << (5 - comp)))
    724             {
    725                 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp,
    726                                 mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
    727                 if (VLC_ERROR_DETECTED(ncoeffs[comp]))
    728                     return PV_FAIL;
    729 
    730 
    731                 BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
    732                           mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
    733 
    734             }
    735             else
    736             {
    737                 ncoeffs[comp] = 0;
    738             }
    739 
    740             /*  @todo Deblocking Semaphore for INTRA block, for inter just test for ringing  */
    741 #ifdef PV_POSTPROC_ON
    742             if (video->postFilterType != PV_NO_POST_PROC)
    743                 *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
    744 #endif
    745         }
    746 
    747         (*DC)[4] = mid_gray;
    748         if (CBP & 2)
    749         {
    750             ncoeffs[4] = VlcDequantH263InterBlock(video, 4,
    751                                                   mblock->bitmapcol[4], &mblock->bitmaprow[4]);
    752             if (VLC_ERROR_DETECTED(ncoeffs[4]))
    753                 return PV_FAIL;
    754 
    755             BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
    756                       mblock->bitmapcol[4], mblock->bitmaprow[4]);
    757 
    758         }
    759         else
    760         {
    761             ncoeffs[4] = 0;
    762         }
    763 #ifdef PV_POSTPROC_ON
    764         if (video->postFilterType != PV_NO_POST_PROC)
    765             *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
    766 #endif
    767         (*DC)[5] = mid_gray;
    768         if (CBP & 1)
    769         {
    770             ncoeffs[5] = VlcDequantH263InterBlock(video, 5,
    771                                                   mblock->bitmapcol[5], &mblock->bitmaprow[5]);
    772             if (VLC_ERROR_DETECTED(ncoeffs[5]))
    773                 return PV_FAIL;
    774 
    775             BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
    776                       mblock->bitmapcol[5], mblock->bitmaprow[5]);
    777 
    778         }
    779         else
    780         {
    781             ncoeffs[5] = 0;
    782         }
    783 #ifdef PV_POSTPROC_ON
    784         if (video->postFilterType != PV_NO_POST_PROC)
    785             *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
    786 #endif
    787 
    788 
    789 
    790 
    791         /* Motion compensation and put it to video->mblock->pred_block */
    792     }
    793     return PV_SUCCESS;
    794 }
    795