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 #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