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