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