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