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 /* ======================================================================== */
DecodeFrameCombinedMode(VideoDecData * video)42 PV_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 /* ============================================================================ */
GetMBheader(VideoDecData * video,int16 * QP)345 PV_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********/
GetMBData(VideoDecData * video)526 PV_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     int y_pos = video->mbnum_row;
548     int x_pos = video->mbnum_col;
549     int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4);
550 
551     /* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */
552     /*  are chrominance blocks.   04/03/2000.                          */
553 
554     /*  oscl_memset(mblock->block, 0, sizeof(typeMBStore));    Aug 9,2005 */
555 
556     if (mode & INTRA_MASK) /* MODE_INTRA || MODE_INTRA_Q */
557     {
558         switched = 0;
559         if (intra_dc_vlc_thr)
560         {
561             if (video->usePrevQP)
562                 QP_tmp = video->QPMB[mbnum-1];   /* running QP  04/26/01 */
563 
564             switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
565         }
566 
567         mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE);   /*  3/01/01 */
568         mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE);
569 
570         for (comp = 0; comp < 6; comp++)
571         {
572             dataBlock = mblock->block[comp];    /* 10/20/2000 */
573 
574             if (video->shortVideoHeader)
575             {
576 #ifdef PV_ANNEX_IJKT_SUPPORT
577                 if (!video->advanced_INTRA)
578                 {
579 #endif
580                     DC_coeff = (int16) BitstreamReadBits16_INLINE(stream, 8);
581 
582                     if ((DC_coeff & 0x7f) == 0) /* 128 & 0  */
583                     {
584                         /* currently we will only signal FAIL for 128. We will ignore the 0 case  */
585                         if (DC_coeff == 128)
586                         {
587                             return PV_FAIL;
588                         }
589                         else
590                         {
591                             VideoDecoderErrorDetected(video);
592                         }
593                     }
594                     if (DC_coeff == 255)
595                     {
596                         DC_coeff = 128;
597                     }
598                     dataBlock[0] = (int16) DC_coeff;
599 #ifdef PV_ANNEX_IJKT_SUPPORT
600                 }
601 #endif
602                 ncoeffs[comp] = VlcDequantH263IntraBlock_SH(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
603 
604             }
605             else
606             {
607                 if (switched == 0)
608                 {
609                     status = PV_DecodePredictedIntraDC(comp, stream, &DC_coeff);
610                     if (status != PV_SUCCESS) return PV_FAIL;
611 
612                     dataBlock[0] = (int16) DC_coeff;
613                 }
614                 ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp,
615                                 switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
616             }
617 
618             if (VLC_ERROR_DETECTED(ncoeffs[comp]))
619             {
620                 if (switched)
621                     return PV_FAIL;
622                 else
623                 {
624                     ncoeffs[comp] = 1;
625                     oscl_memset((dataBlock + 1), 0, sizeof(int16)*63);
626                 }
627             }
628             no_coeff[comp] = ncoeffs[comp];
629 
630         }
631         MBlockIDCT(video);
632     }
633     else      /* INTER modes */
634     {   /*  moved it here Aug 15, 2005 */
635         /* decode the motion vector (if there are any) */
636         status = PV_GetMBvectors(video, mode);
637         if (status != PV_SUCCESS)
638         {
639             return status;
640         }
641 
642 
643         MBMotionComp(video, CBP);
644         c_comp  = video->currVop->yChan + offset;
645 
646 #ifdef PV_ANNEX_IJKT_SUPPORT
647         for (comp = 0; comp < 4; comp++)
648         {
649             (*DC)[comp] = mid_gray;
650             if (CBP & (1 << (5 - comp)))
651             {
652                 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
653                 if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
654 
655                 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],
656                           mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
657 
658             }
659         }
660 
661         video->QPMB[mbnum] = video->QP_CHR;     /* ANNEX_T */
662 
663 
664 
665         (*DC)[4] = mid_gray;
666         if (CBP & 2)
667         {
668             ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]);
669             if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL;
670 
671             BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
672                       mblock->bitmapcol[4], mblock->bitmaprow[4]);
673 
674         }
675         (*DC)[5] = mid_gray;
676         if (CBP & 1)
677         {
678             ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
679             if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
680 
681             BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
682                       mblock->bitmapcol[5], mblock->bitmaprow[5]);
683 
684         }
685         video->QPMB[mbnum] = QP;  /* restore the QP values  ANNEX_T*/
686 #else
687         for (comp = 0; comp < 4; comp++)
688         {
689             (*DC)[comp] = mid_gray;
690             if (CBP & (1 << (5 - comp)))
691             {
692                 ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
693                 if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
694 
695                 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],
696                           mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
697 
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         }
711         else
712         {
713             /* no IDCT for all zeros blocks  03/28/2002 */
714             /*              BlockIDCT();                */
715         }
716         (*DC)[5] = mid_gray;
717         if (CBP & 1)
718         {
719             ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
720             if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
721 
722             BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
723                       mblock->bitmapcol[5], mblock->bitmaprow[5]);
724 
725         }
726         else
727         {
728             /* no IDCT for all zeros blocks  03/28/2002 */
729             /*              BlockIDCT();                */
730 #endif  // PV_ANNEX_IJKT_SUPPORT
731 
732 
733 
734 
735 
736 
737     }
738 
739     video->usePrevQP = 1;          /* should be set after decoding the first Coded  04/27/01 */
740     return PV_SUCCESS;
741 }
742 
743 
744 
745