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