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