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" /* video decoder function prototypes */
19#include "vlc_decode.h"
20#include "bitstream.h"
21#include "scaling.h"
22#include "mbtype_mode.h"
23
24#define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
25/* ======================================================================== */
26/*  Function : DecodeFrameCombinedMode()                                    */
27/*  Purpose  : Decode a frame of MPEG4 bitstream in combined mode.          */
28/*  In/out   :                                                              */
29/*  Return   :                                                              */
30/*  Modified :                                                              */
31/*                                                                          */
32/*      03/30/2000 : Cleaned up and optimized the code.             */
33/*      03/31/2000 : Added proper handling of MB stuffing.          */
34/*      04/13/2000 : Rewrote this combined mode path completely     */
35/*                           so that it handles "Combined Mode With Error   */
36/*                           Resilience."  Now the code resembles the       */
37/*                           pseudo codes in MPEG-4 standard better.        */
38/*      10/13/2000 : Add fast VLC+dequant                           */
39/*      04/13/2001 : fix MB_stuffing                               */
40/*      08/07/2001 : remove MBzero                                  */
41/* ======================================================================== */
42PV_STATUS DecodeFrameCombinedMode(VideoDecData *video)
43{
44    PV_STATUS status;
45    int mbnum;
46    Vop *currVop = video->currVop;
47    BitstreamDecVideo *stream = video->bitstream;
48    int shortVideoHeader = video->shortVideoHeader;
49    int16 QP, *QPMB = video->QPMB;
50    uint8 *Mode = video->headerInfo.Mode;
51    int nTotalMB = video->nTotalMB;
52    int nMBPerRow = video->nMBPerRow;
53    int slice_counter;
54    uint32 tmpvar, long_zero_bits;
55    uint code;
56    int valid_stuffing;
57    int resync_marker_length;
58    int stuffing_length;
59
60    /* add this for error resilient, 05/18/2000 */
61    int32 startPacket;
62    int mb_start;
63    /* copy and pad to prev_Vop for INTER coding */
64    switch (currVop->predictionType)
65    {
66        case I_VOP :
67//      oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB);
68            resync_marker_length = 17;
69            stuffing_length = 9;
70            break;
71        case P_VOP :
72            oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB);
73            oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB);
74//      oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB);
75            resync_marker_length = 16 + currVop->fcodeForward;
76            stuffing_length = 10;
77            break;
78        default :
79            mp4dec_log("DecodeFrameCombinedMode(): Vop type not supported.\n");
80            return PV_FAIL;
81    }
82#ifdef PV_ANNEX_IJKT_SUPPORT
83    if (video->shortVideoHeader)
84    {
85        if (video->advanced_INTRA)
86        {
87            if (video->modified_quant)
88            {
89                video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexIT;
90                video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader_AnnexT;
91            }
92            else
93            {
94                video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexI;
95                video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader;
96            }
97        }
98        else
99        {
100            if (video->modified_quant)
101            {
102                video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexT;
103            }
104            else
105            {
106                video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader;
107            }
108        }
109    }
110
111#endif
112
113    /** Initialize sliceNo ***/
114    mbnum = slice_counter = 0;
115//  oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB);
116    QP = video->currVop->quantizer;
117
118    do
119    {
120        /* This section is equivalent to motion_shape_texture() */
121        /*    in the MPEG-4 standard.     04/13/2000          */
122        mb_start = mbnum;
123        video->usePrevQP = 0;             /*  04/27/01 */
124        startPacket = getPointer(stream);
125
126#ifdef PV_ANNEX_IJKT_SUPPORT
127        if (video->modified_quant)
128        {
129            video->QP_CHR = MQ_chroma_QP_table[QP];
130        }
131        else
132        {
133            video->QP_CHR = QP;     /* ANNEX_T */
134        }
135#endif
136        /* remove any stuffing bits */
137        BitstreamShowBits16(stream, stuffing_length, &code);
138        while (code == 1)
139        {
140            PV_BitstreamFlushBits(stream, stuffing_length);
141            BitstreamShowBits16(stream, stuffing_length, &code);
142        }
143
144        do
145        {
146            /* we need video->mbnum in lower level functions */
147            video->mbnum = mbnum;
148            video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);
149            video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
150            /* assign slice number for each macroblocks */
151            video->sliceNo[mbnum] = (uint8) slice_counter;
152
153            /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
154            /* We have to discard stuffed MB header */
155            status = GetMBheader(video, &QP);
156
157            if (status != PV_SUCCESS)
158            {
159                VideoDecoderErrorDetected(video);
160                video->mbnum = mb_start;
161                movePointerTo(stream, (startPacket & -8));
162                break;
163            }
164
165            /* Store the QP value for later use in AC prediction */
166            QPMB[mbnum] = QP;
167
168            if (Mode[mbnum] != MODE_SKIPPED)
169            {
170                /* decode the DCT coeficients for the MB */
171                status = GetMBData(video);
172                if (status != PV_SUCCESS)
173                {
174                    VideoDecoderErrorDetected(video);
175                    video->mbnum = mb_start;
176                    movePointerTo(stream, (startPacket & -8));
177                    break;
178                }
179            }
180            else /* MODE_SKIPPED */
181            {
182                SkippedMBMotionComp(video); /*  08/04/05 */
183            }
184            // Motion compensation and put video->mblock->pred_block
185            mbnum++;
186
187            /* remove any stuffing bits */
188            BitstreamShowBits16(stream, stuffing_length, &code);
189            while (code == 1)
190            {
191                PV_BitstreamFlushBits(stream, stuffing_length);
192                BitstreamShowBits16(stream, stuffing_length, &code);
193            }
194
195            /* have we reached the end of the video packet or vop? */
196            if (shortVideoHeader)
197            {
198#ifdef PV_ANNEX_IJKT_SUPPORT
199                if (!video->slice_structure)
200                {
201#endif
202                    if (mbnum >= (int)(video->mbnum_row + 1)*video->nMBinGOB)   /*  10/11/01 */
203                    {
204                        if (mbnum >= nTotalMB) return PV_SUCCESS;
205                        status = BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
206
207                        if (tmpvar == GOB_RESYNC_MARKER)
208                        {
209                            break;
210                        }
211                        else
212                        {
213                            status = PV_BitstreamShowBitsByteAlign(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
214                            if (tmpvar == GOB_RESYNC_MARKER) break;
215                        }
216                    }
217#ifdef PV_ANNEX_IJKT_SUPPORT
218                }
219                else
220                {
221
222                    if (mbnum >= nTotalMB)  /* in case no valid stuffing  06/23/01 */
223                    {
224                        valid_stuffing = validStuffing_h263(stream);
225                        if (valid_stuffing == 0)
226                        {
227                            VideoDecoderErrorDetected(video);
228                            ConcealPacket(video, mb_start, nTotalMB, slice_counter);
229                        }
230                        return PV_SUCCESS;
231                    }
232                    /* ANNEX_K */
233                    PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
234                    if (tmpvar == RESYNC_MARKER)
235                    {
236                        valid_stuffing = validStuffing_h263(stream);
237                        if (valid_stuffing)
238                            break; /*  06/21/01 */
239                    }
240
241                }
242#endif
243            }
244            else
245            {
246                if (mbnum >= nTotalMB)  /* in case no valid stuffing  06/23/01 */
247                {
248                    /*  11/01/2002 if we are at the end of the frame and there is some garbage data
249                    at the end of the frame (i.e. no next startcode) break if the stuffing is valid */
250                    valid_stuffing = validStuffing(stream);
251                    if (valid_stuffing == 0)
252                    {
253                        /* end 11/01/2002 */
254                        VideoDecoderErrorDetected(video);
255                        ConcealPacket(video, mb_start, nTotalMB, slice_counter);
256                    }
257                    PV_BitstreamByteAlign(stream);
258                    return PV_SUCCESS;
259                }
260
261                status = PV_BitstreamShowBitsByteAlign(stream, 23, &tmpvar); /* this call is valid for f_code < 8 */
262                long_zero_bits = !tmpvar;
263
264                if ((tmpvar >> (23 - resync_marker_length)) == RESYNC_MARKER || long_zero_bits)
265                {
266                    valid_stuffing = validStuffing(stream);
267                    if (valid_stuffing)
268                        break; /*  06/21/01 */
269                }
270
271            }
272        }
273        while (TRUE);
274
275        if (shortVideoHeader)
276        { /* We need to check newgob to refresh quantizer */
277#ifdef PV_ANNEX_IJKT_SUPPORT
278            if (!video->slice_structure)
279            {
280#endif
281                while ((status = PV_GobHeader(video)) == PV_FAIL)
282                {
283                    if ((status = quickSearchGOBHeader(stream)) != PV_SUCCESS)
284                    {
285                        break;
286                    }
287                }
288
289                mbnum = currVop->gobNumber * video->nMBinGOB;
290#ifdef PV_ANNEX_IJKT_SUPPORT
291            }
292            else
293            {
294                while ((status = PV_H263SliceHeader(video, &mbnum)) == PV_FAIL)
295                {
296                    if ((status = quickSearchH263SliceHeader(stream)) != PV_SUCCESS)
297                    {
298                        break;
299                    }
300                }
301            }
302
303#endif
304        }
305        else
306        {
307            while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL)
308            {
309                if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS)
310                {
311                    break;
312                }
313            }
314        }
315
316        if (status == PV_END_OF_VOP)
317        {
318            mbnum = nTotalMB;
319        }
320
321        if (mbnum > video->mbnum + 1)
322        {
323            ConcealPacket(video, video->mbnum, mbnum, slice_counter);
324        }
325        QP = video->currVop->quantizer;
326        slice_counter++;
327        if (mbnum >= nTotalMB) break;
328
329    }
330    while (TRUE);
331    return PV_SUCCESS;
332}
333
334
335/* ============================================================================ */
336/*  Function : GetMBHeader()                                                    */
337/*  Purpose  : Decode MB header, not_coded, mcbpc, ac_pred_flag, cbpy, dquant.  */
338/*  In/out   :                                                                  */
339/*  Return   :                                                                  */
340/*  Modified :                                                                  */
341/*                                                                              */
342/*      3/29/00 : Changed the returned value and optimized the code.    */
343/*      4/01/01 : new ACDC prediction structure                         */
344/* ============================================================================ */
345PV_STATUS GetMBheader(VideoDecData *video, int16 *QP)
346{
347    BitstreamDecVideo *stream = video->bitstream;
348    int mbnum = video->mbnum;
349    uint8 *Mode = video->headerInfo.Mode;
350    int x_pos = video->mbnum_col;
351    typeDCStore *DC = video->predDC + mbnum;
352    typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
353    typeDCACStore *DCAC_col = video->predDCAC_col;
354    const static int16  DQ_tab[4] = { -1, -2, 1, 2};
355
356    int CBPY, CBPC;
357    int MBtype, VopType;
358    int MCBPC;
359    uint DQUANT;
360    int comp;
361    Bool mb_coded;
362
363    VopType = video->currVop->predictionType;
364    mb_coded = ((VopType == I_VOP) ? TRUE : !BitstreamRead1Bits_INLINE(stream));
365
366    if (!mb_coded)
367    {
368        /* skipped macroblock */
369        Mode[mbnum] = MODE_SKIPPED;
370        //oscl_memset(DCAC_row, 0, sizeof(typeDCACStore));   /*  SKIPPED_ACDC */
371        //oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
372        ZERO_OUT_64BYTES(DCAC_row);
373        ZERO_OUT_64BYTES(DCAC_col); /*  08/12/05 */
374
375        for (comp = 0; comp < 6; comp++)
376        {
377            (*DC)[comp] = mid_gray;
378        }
379    }
380    else
381    {
382        /* coded macroblock */
383        if (VopType == I_VOP)
384        {
385            MCBPC = PV_VlcDecMCBPC_com_intra(stream);
386        }
387        else
388        {
389#ifdef PV_ANNEX_IJKT_SUPPORT
390            if (!video->deblocking)
391            {
392                MCBPC = PV_VlcDecMCBPC_com_inter(stream);
393            }
394            else
395            {
396                MCBPC = PV_VlcDecMCBPC_com_inter_H263(stream);
397            }
398#else
399            MCBPC = PV_VlcDecMCBPC_com_inter(stream);
400#endif
401        }
402
403        if (VLC_ERROR_DETECTED(MCBPC))
404        {
405            return PV_FAIL;
406        }
407
408        Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]);
409        CBPC = (MCBPC >> 4) & 3;
410
411#ifdef PV_ANNEX_IJKT_SUPPORT
412        if (MBtype & INTRA_MASK)
413        {
414            if (!video->shortVideoHeader)
415            {
416                video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream);
417            }
418            else
419            {
420                if (video->advanced_INTRA)
421                {
422                    if (!BitstreamRead1Bits(stream))
423                    {
424                        video->acPredFlag[mbnum] = 0;
425                    }
426                    else
427                    {
428                        video->acPredFlag[mbnum] = 1;
429                        if (BitstreamRead1Bits(stream))
430                        {
431                            video->mblock->direction = 0;
432                        }
433                        else
434                        {
435                            video->mblock->direction = 1;
436                        }
437                    }
438                }
439                else
440                {
441                    video->acPredFlag[mbnum] = 0;
442                }
443            }
444        }
445#else
446        if ((MBtype & INTRA_MASK) && !video->shortVideoHeader)
447        {
448            video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream);
449        }
450        else
451        {
452            video->acPredFlag[mbnum] = 0;
453        }
454#endif
455        CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* INTRA || INTRA_Q */
456        if (CBPY < 0)
457        {
458            return PV_FAIL;
459        }
460
461        // GW 04/23/99
462        video->headerInfo.CBP[mbnum] = (uint8)(CBPY << 2 | (CBPC & 3));
463#ifdef PV_ANNEX_IJKT_SUPPORT
464        if (MBtype & Q_MASK)
465        {
466            if (!video->modified_quant)
467            {
468                DQUANT = BitstreamReadBits16(stream, 2);
469                *QP += DQ_tab[DQUANT];
470
471                if (*QP < 1) *QP = 1;
472                else if (*QP > 31) *QP = 31;
473                video->QP_CHR = *QP;  /* ANNEX_T */
474            }
475            else
476            {
477                if (BitstreamRead1Bits(stream))
478                {
479                    if (BitstreamRead1Bits(stream))
480                    {
481                        *QP += DQ_tab_Annex_T_11[*QP];
482                    }
483                    else
484                    {
485                        *QP += DQ_tab_Annex_T_10[*QP];
486                    }
487                    if (*QP < 1) *QP = 1;
488                    else if (*QP > 31) *QP = 31;
489                }
490                else
491                {
492                    *QP = (int16)BitstreamReadBits16(stream, 5);
493                }
494                video->QP_CHR =  MQ_chroma_QP_table[*QP];
495            }
496        }
497#else
498        if (MBtype & Q_MASK)
499        {
500            DQUANT = BitstreamReadBits16(stream, 2);
501            *QP += DQ_tab[DQUANT];
502
503            if (*QP < 1) *QP = 1;
504            else if (*QP > 31) *QP = 31;
505        }
506#endif
507    }
508    return PV_SUCCESS;
509}
510
511
512
513
514
515/***********************************************************CommentBegin******
516*       3/10/00  : initial modification to the
517*                new PV-Decoder Lib format.
518*       4/2/2000 : Cleanup and error-handling modification.  This
519*                   function has been divided into several sub-functions for
520*                   better coding style and maintainance reason.  I also
521*                   greatly shrunk the code size here.
522*       9/18/2000 : VlcDecode+Dequant optimization *
523*       4/01/2001 : new ACDC prediction structure
524*       3/29/2002 : removed GetIntraMB and GetInterMB
525***********************************************************CommentEnd********/
526PV_STATUS GetMBData(VideoDecData *video)
527{
528    BitstreamDecVideo *stream = video->bitstream;
529    int mbnum = video->mbnum;
530    MacroBlock *mblock = video->mblock;
531    int16 *dataBlock;
532    PIXEL *c_comp;
533    uint mode = video->headerInfo.Mode[mbnum];
534    uint CBP = video->headerInfo.CBP[mbnum];
535    typeDCStore *DC = video->predDC + mbnum;
536    int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
537    int16 QP = video->QPMB[mbnum];
538    int16 QP_tmp = QP;
539    int width = video->width;
540    int  comp;
541    int  switched;
542    int ncoeffs[6] = {0, 0, 0, 0, 0, 0};
543    int *no_coeff = mblock->no_coeff;
544    int16 DC_coeff;
545    PV_STATUS status;
546
547#ifdef PV_POSTPROC_ON
548    /* post-processing */
549    uint8 *pp_mod[6];
550    int TotalMB = video->nTotalMB;
551    int MB_in_width = video->nMBPerRow;
552#endif
553    int y_pos = video->mbnum_row;
554    int x_pos = video->mbnum_col;
555    int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4);
556
557    /* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */
558    /*  are chrominance blocks.   04/03/2000.                          */
559#ifdef PV_POSTPROC_ON
560    if (video->postFilterType != PV_NO_POST_PROC)
561    {
562        /** post-processing ***/
563        pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
564        pp_mod[1] = pp_mod[0] + 1;
565        pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
566        pp_mod[3] = pp_mod[2] + 1;
567        pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
568        pp_mod[5] = pp_mod[4] + TotalMB;
569    }
570#endif
571
572    /*  oscl_memset(mblock->block, 0, sizeof(typeMBStore));    Aug 9,2005 */
573
574    if (mode & INTRA_MASK) /* MODE_INTRA || MODE_INTRA_Q */
575    {
576        switched = 0;
577        if (intra_dc_vlc_thr)
578        {
579            if (video->usePrevQP)
580                QP_tmp = video->QPMB[mbnum-1];   /* running QP  04/26/01 */
581
582            switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
583        }
584
585        mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE);   /*  3/01/01 */
586        mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE);
587
588        for (comp = 0; comp < 6; comp++)
589        {
590            dataBlock = mblock->block[comp];    /* 10/20/2000 */
591
592            if (video->shortVideoHeader)
593            {
594#ifdef PV_ANNEX_IJKT_SUPPORT
595                if (!video->advanced_INTRA)
596                {
597#endif
598                    DC_coeff = (int16) BitstreamReadBits16_INLINE(stream, 8);
599
600                    if ((DC_coeff & 0x7f) == 0) /* 128 & 0  */
601                    {
602                        /* currently we will only signal FAIL for 128. We will ignore the 0 case  */
603                        if (DC_coeff == 128)
604                        {
605                            return PV_FAIL;
606                        }
607                        else
608                        {
609                            VideoDecoderErrorDetected(video);
610                        }
611                    }
612                    if (DC_coeff == 255)
613                    {
614                        DC_coeff = 128;
615                    }
616                    dataBlock[0] = (int16) DC_coeff;
617#ifdef PV_ANNEX_IJKT_SUPPORT
618                }
619#endif
620                ncoeffs[comp] = VlcDequantH263IntraBlock_SH(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
621
622            }
623            else
624            {
625                if (switched == 0)
626                {
627                    status = PV_DecodePredictedIntraDC(comp, stream, &DC_coeff);
628                    if (status != PV_SUCCESS) return PV_FAIL;
629
630                    dataBlock[0] = (int16) DC_coeff;
631                }
632                ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp,
633                                switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
634            }
635
636            if (VLC_ERROR_DETECTED(ncoeffs[comp]))
637            {
638                if (switched)
639                    return PV_FAIL;
640                else
641                {
642                    ncoeffs[comp] = 1;
643                    oscl_memset((dataBlock + 1), 0, sizeof(int16)*63);
644                }
645            }
646            no_coeff[comp] = ncoeffs[comp];
647
648#ifdef PV_POSTPROC_ON
649            if (video->postFilterType != PV_NO_POST_PROC)
650                *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
651#endif
652        }
653        MBlockIDCT(video);
654    }
655    else      /* INTER modes */
656    {   /*  moved it here Aug 15, 2005 */
657        /* decode the motion vector (if there are any) */
658        status = PV_GetMBvectors(video, mode);
659        if (status != PV_SUCCESS)
660        {
661            return status;
662        }
663
664
665        MBMotionComp(video, CBP);
666        c_comp  = video->currVop->yChan + offset;
667
668#ifdef PV_ANNEX_IJKT_SUPPORT
669        for (comp = 0; comp < 4; comp++)
670        {
671            (*DC)[comp] = mid_gray;
672            if (CBP & (1 << (5 - comp)))
673            {
674                ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
675                if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
676
677                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],
678                          mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
679
680#ifdef PV_POSTPROC_ON
681                /* for inter just test for ringing */
682                if (video->postFilterType != PV_NO_POST_PROC)
683                    *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
684#endif
685            }
686            else
687            {
688                /* no IDCT for all zeros blocks  03/28/2002 */
689                /*              BlockIDCT();                */
690#ifdef PV_POSTPROC_ON
691                if (video->postFilterType != PV_NO_POST_PROC)
692                    *pp_mod[comp] = 0;
693#endif
694            }
695        }
696
697        video->QPMB[mbnum] = video->QP_CHR;     /* ANNEX_T */
698
699
700
701        (*DC)[4] = mid_gray;
702        if (CBP & 2)
703        {
704            ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]);
705            if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL;
706
707            BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
708                      mblock->bitmapcol[4], mblock->bitmaprow[4]);
709
710#ifdef PV_POSTPROC_ON
711            /* for inter just test for ringing */
712            if (video->postFilterType != PV_NO_POST_PROC)
713                *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
714#endif
715        }
716        else
717        {
718            /* no IDCT for all zeros blocks  03/28/2002 */
719            /*              BlockIDCT();                */
720#ifdef PV_POSTPROC_ON
721            if (video->postFilterType != PV_NO_POST_PROC)
722                *pp_mod[4] = 0;
723#endif
724        }
725        (*DC)[5] = mid_gray;
726        if (CBP & 1)
727        {
728            ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
729            if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
730
731            BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
732                      mblock->bitmapcol[5], mblock->bitmaprow[5]);
733
734#ifdef PV_POSTPROC_ON
735            /* for inter just test for ringing */
736            if (video->postFilterType != PV_NO_POST_PROC)
737                *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
738#endif
739        }
740        else
741        {
742            /* no IDCT for all zeros blocks  03/28/2002 */
743            /*              BlockIDCT();                */
744#ifdef PV_POSTPROC_ON
745            if (video->postFilterType != PV_NO_POST_PROC)
746                *pp_mod[5] = 0;
747#endif
748        }
749        video->QPMB[mbnum] = QP;  /* restore the QP values  ANNEX_T*/
750#else
751        for (comp = 0; comp < 4; comp++)
752        {
753            (*DC)[comp] = mid_gray;
754            if (CBP & (1 << (5 - comp)))
755            {
756                ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
757                if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
758
759                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],
760                          mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
761
762#ifdef PV_POSTPROC_ON
763                /* for inter just test for ringing */
764                if (video->postFilterType != PV_NO_POST_PROC)
765                    *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
766#endif
767            }
768            else
769            {
770                /* no IDCT for all zeros blocks  03/28/2002 */
771                /*              BlockIDCT();                */
772#ifdef PV_POSTPROC_ON
773                if (video->postFilterType != PV_NO_POST_PROC)
774                    *pp_mod[comp] = 0;
775#endif
776            }
777        }
778
779        (*DC)[4] = mid_gray;
780        if (CBP & 2)
781        {
782            ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]);
783            if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL;
784
785            BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
786                      mblock->bitmapcol[4], mblock->bitmaprow[4]);
787
788#ifdef PV_POSTPROC_ON
789            /* for inter just test for ringing */
790            if (video->postFilterType != PV_NO_POST_PROC)
791                *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
792#endif
793        }
794        else
795        {
796            /* no IDCT for all zeros blocks  03/28/2002 */
797            /*              BlockIDCT();                */
798#ifdef PV_POSTPROC_ON
799            if (video->postFilterType != PV_NO_POST_PROC)
800                *pp_mod[4] = 0;
801#endif
802        }
803        (*DC)[5] = mid_gray;
804        if (CBP & 1)
805        {
806            ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
807            if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
808
809            BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
810                      mblock->bitmapcol[5], mblock->bitmaprow[5]);
811
812#ifdef PV_POSTPROC_ON
813            /* for inter just test for ringing */
814            if (video->postFilterType != PV_NO_POST_PROC)
815                *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
816#endif
817        }
818        else
819        {
820            /* no IDCT for all zeros blocks  03/28/2002 */
821            /*              BlockIDCT();                */
822#ifdef PV_POSTPROC_ON
823            if (video->postFilterType != PV_NO_POST_PROC)
824                *pp_mod[5] = 0;
825#endif
826#endif  // PV_ANNEX_IJKT_SUPPORT
827
828
829
830
831
832
833    }
834
835    video->usePrevQP = 1;          /* should be set after decoding the first Coded  04/27/01 */
836    return PV_SUCCESS;
837}
838
839
840
841