summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp')
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp1152
1 files changed, 1152 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
new file mode 100644
index 0000000..db13a48
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
@@ -0,0 +1,1152 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+#include "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "zigzag.h"
+
+
+typedef PV_STATUS(*VlcDecFuncP)(BitstreamDecVideo *stream, Tcoef *pTcoef);
+static const uint8 AC_rowcol[64] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ };
+static const uint8 mask[8] = /* for fast bitmap */
+ {128, 64, 32, 16, 8, 4, 2, 1};
+
+
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantMpegBlock -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization using Mpeg mode.
+ Date: 08/08/2000
+
+ Modified: 3/21/01
+ Added pre IDCT clipping, new ACDC prediction structure, ACDC prediction clipping,
+ 16-bit int case, removed multiple zigzaging
+******************************************************************************/
+
+#ifdef PV_SUPPORT_MAIN_PROFILE
+int VlcDequantMpegIntraBlock(void *vid, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ VideoDecData *video = (VideoDecData*) vid;
+ Vol *currVol = video->vol[video->currLayer];
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, j, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+ int direction;
+ const int *inv_zigzag;
+ /*** Quantizer ****/
+ int dc_scaler;
+ int sum;
+ int *qmat;
+ int32 temp;
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+
+
+ i = 1 - switched;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+ dc_scaler = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
+
+ /* enter the zero run decoding loop */
+ sum = 0;
+ qmat = currVol->iqmat;
+
+ /* perform only VLC decoding */
+ /* We cannot do DCACrecon before VLC decoding. 10/17/2000 */
+ doDCACPrediction(video, comp, datablock, &direction);
+ if (!ACpred_flag) direction = 0;
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6);
+ if (CBP & (1 << (5 - comp)))
+ {
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 1)
+ {
+ datablock[k] -= run_level.level;
+ }
+ else
+ {
+ datablock[k] += run_level.level;
+ }
+
+ if (AC_rowcol[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3;
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ sum ^= temp;
+ }
+
+ i++;
+ }
+ while (!last);
+
+ }
+ else
+ {
+ i = 1; /* 04/26/01 needed for switched case */
+ }
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+ if (ACpred_flag)
+ {
+
+ i = NCOEFF_BLOCK; /* otherwise, FAST IDCT won't work correctly, 10/18/2000 */
+
+ if (!direction) /* check vertical */
+ {
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ for (j = 0, k = 8; k < 64; k += 8, j++)
+ {
+ if (dcac_col[j] = datablock[k])
+ { /* ACDC clipping 03/26/01 */
+ if (datablock[k] > 2047) dcac_col[j] = 2047;
+ else if (datablock[k] < -2048) dcac_col[j] = -2048;
+
+ temp = (int32)dcac_col[j] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+
+ }
+ }
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+
+ }
+ else
+ {
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+
+ for (j = 0, k = 1; k < 8; k++, j++)
+ {
+ if (dcac_row[j] = datablock[k])
+ { /* ACDC clipping 03/26/01 */
+ if (datablock[k] > 2047) dcac_row[j] = 2047;
+ else if (datablock[k] < -2048) dcac_row[j] = -2048;
+
+ temp = (int32)dcac_row[j] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+ }
+ else
+ {
+
+ /* Store the qcoeff-values needed later for prediction */
+
+ dcac_row[0] = datablock[1]; /* ACDC, no need for clipping */
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+
+
+
+ if (datablock[0])
+ {
+ temp = (int32)datablock[0] * dc_scaler;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[0] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+ }
+
+ if ((sum & 1) == 0)
+ {
+ datablock[63] = datablock[63] ^ 0x1;
+#ifdef FAST_IDCT /* 7/5/01, need to update bitmap */
+ if (datablock[63])
+ bitmapcol[7] |= 1;
+#endif
+ i = (-64 & i) | NCOEFF_BLOCK; /* if i > -1 then i is set to NCOEFF_BLOCK */
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++)
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k];
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantMpegInterBlock -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization using Mpeg mode for INTER block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case, new ACDC prediction
+******************************************************************************/
+
+
+int VlcDequantMpegInterBlock(void *vid, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ VideoDecData *video = (VideoDecData*) vid;
+ BitstreamDecVideo *stream = video->bitstream;
+ Vol *currVol = video->vol[video->currLayer];
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int mbnum = video->mbnum;
+ int QP = video->QPMB[mbnum];
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+
+ /*** Quantizer ****/
+ int sum;
+ int *qmat;
+
+ int32 temp;
+
+ i = 0 ;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffInter;
+
+ /* enter the zero run decoding loop */
+ sum = 0;
+ qmat = currVol->niqmat;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ sum = 1; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ //return VLC_NO_LAST_BIT;
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ sum = 1; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ k = zigzag_inv[i];
+
+ if (run_level.sign == 1)
+ {
+ temp = (-(int32)(2 * run_level.level + 1) * qmat[k] * QP + 15) >> 4; /* 03/23/01 */
+ if (temp < -2048) temp = - 2048;
+ }
+ else
+ {
+ temp = ((int32)(2 * run_level.level + 1) * qmat[k] * QP) >> 4; /* 03/23/01 */
+ if (temp > 2047) temp = 2047;
+ }
+
+ datablock[k] = (int)temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ sum ^= temp;
+
+ i++;
+ }
+ while (!last);
+
+ if ((sum & 1) == 0)
+ {
+ datablock[63] = datablock[63] ^ 0x1;
+#ifdef FAST_IDCT /* 7/5/01, need to update bitmap */
+ if (datablock[63])
+ bitmapcol[7] |= 1;
+#endif
+ i = NCOEFF_BLOCK;
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* 07/19/01 */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k];
+ }
+ }
+ }
+#endif
+
+ return i;
+}
+#endif
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantIntraH263Block -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization in H.263 mode for INTRA block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case, removed multiple zigzaging
+******************************************************************************/
+
+
+int VlcDequantH263IntraBlock(VideoDecData *video, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, j, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+ int direction;
+ const int *inv_zigzag;
+
+ /*** Quantizer ****/
+ int dc_scaler;
+ int sgn_coeff;
+
+
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+ dc_scaler = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
+
+ /* perform only VLC decoding */
+ doDCACPrediction(video, comp, datablock, &direction);
+ if (!ACpred_flag) direction = 0;
+
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6); /* 04/17/01 */
+
+ i = 1;
+ if (CBP & (1 << (5 - comp)))
+ {
+ i = 1 - switched;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 1)
+ {
+ datablock[k] -= run_level.level;
+ sgn_coeff = -1;
+ }
+ else
+ {
+ datablock[k] += run_level.level;
+ sgn_coeff = 1;
+ }
+
+
+ if (AC_rowcol[k]) /* 10/25/2000 */
+ {
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ }
+
+ i++;
+ }
+ while (!last);
+
+ }
+
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+ if (ACpred_flag)
+ {
+
+ i = NCOEFF_BLOCK; /* otherwise, FAST IDCT won't work correctly, 10/18/2000 */
+
+ if (!direction) /* check vertical */
+ {
+
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ for (j = 0, k = 8; k < 64; k += 8, j++)
+ {
+ dcac_col[j] = datablock[k];
+ if (dcac_col[j])
+ {
+ if (datablock[k] > 0)
+ {
+ if (datablock[k] > 2047) dcac_col[j] = 2047;
+ sgn_coeff = 1;
+ }
+ else
+ {
+ if (datablock[k] < -2048) dcac_col[j] = -2048;
+ sgn_coeff = -1;
+ }
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+
+ }
+ }
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ }
+ else
+ {
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+
+ for (j = 0, k = 1; k < 8; k++, j++)
+ {
+ dcac_row[j] = datablock[k];
+ if (dcac_row[j])
+ {
+ if (datablock[k] > 0)
+ {
+ if (datablock[k] > 2047) dcac_row[j] = 2047;
+ sgn_coeff = 1;
+ }
+ else
+ {
+ if (datablock[k] < -2048) dcac_row[j] = -2048;
+ sgn_coeff = -1;
+ }
+
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+ }
+ else
+ {
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+ }
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+
+ temp = (int32)datablock[0] * dc_scaler;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[0] = (int16)temp;
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* if i > 10 then k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+}
+
+int VlcDequantH263IntraBlock_SH(VideoDecData *video, int comp, uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /*, 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int16 QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ int direction;
+ const int *inv_zigzag;
+#endif
+ /*** Quantizer ****/
+
+
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+ i = 1;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (comp > 3) /* ANNEX_T */
+ {
+ QP = video->QP_CHR;
+ }
+ if (!video->advanced_INTRA)
+ {
+#endif
+
+ if ((CBP & (1 << (5 - comp))) == 0)
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] = 128;
+ bitmapcol[1] = bitmapcol[2] = bitmapcol[3] = bitmapcol[4] = bitmapcol[5] = bitmapcol[6] = bitmapcol[7] = 0;
+#endif
+ datablock[0] <<= 3; /* no need to clip */
+ return 1;//ncoeffs;
+ }
+ else
+ {
+ /* enter the zero run decoding loop */
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+ k = zigzag_inv[i];
+
+ if (run_level.sign == 0)
+ {
+ temp = (int32)QP * (2 * run_level.level + 1) - 1 + (QP & 1);
+ if (temp > 2047) temp = 2047;
+ }
+ else
+ {
+ temp = -(int32)QP * (2 * run_level.level + 1) + 1 - (QP & 1);
+ if (temp < -2048) temp = -2048;
+ }
+
+
+ datablock[k] = (int16) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ i++;
+ }
+ while (!last);
+
+ }
+ /* no ACDC prediction when ACDC disable */
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+ datablock[0] <<= 3; /* no need to clip 09/18/2001 */
+ }
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ }
+ else /* advanced_INTRA mode */
+ {
+ i = 1;
+ doDCACPrediction_I(video, comp, datablock);
+ /* perform only VLC decoding */
+ if (!ACpred_flag)
+ {
+ direction = 0;
+ }
+ else
+ {
+ direction = video->mblock->direction;
+ }
+
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6); /* 04/17/01 */
+
+ if (CBP & (1 << (5 - comp)))
+ {
+ i = 0;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 0)
+ {
+ datablock[k] += (int16)QP * 2 * run_level.level;
+ if (datablock[k] > 2047) datablock[k] = 2047;
+ }
+ else
+ {
+ datablock[k] -= (int16)QP * 2 * run_level.level;
+ if (datablock[k] < -2048) datablock[k] = -2048;
+ }
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+
+ i++;
+ }
+ while (!last);
+
+ }
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+
+ if (ACpred_flag)
+ {
+ i = NCOEFF_BLOCK;
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ bitmapcol[k] |= 128;
+ }
+
+ if (datablock[k<<3])
+ {
+ bitmapcol[0] |= mask[k];
+ }
+ }
+ }
+
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+
+ datablock[0] |= 1;
+ if (datablock[0] < 0)
+ {
+ datablock[0] = 0;
+ }
+ }
+ }
+#endif
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* if i > 10 then k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+}
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantInterH263Block -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization in H.263 mode for INTER block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case
+******************************************************************************/
+
+
+int VlcDequantH263InterBlock(VideoDecData *video, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ int QP = video->QPMB[mbnum];
+
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+
+ /*** Quantizer ****/
+
+
+ i = 0;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffInter;
+
+ /* enter the zero run decoding loop */
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+
+
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = -1;
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ i = -1;
+ last = 1;
+ break;
+ }
+
+ if (run_level.sign == 0)
+ {
+ temp = (int32)QP * (2 * run_level.level + 1) - 1 + (QP & 1);
+ if (temp > 2047) temp = 2047;
+
+ }
+ else
+ {
+ temp = -(int32)QP * (2 * run_level.level + 1) + 1 - (QP & 1);
+ if (temp < -2048) temp = -2048;
+ }
+
+ k = zigzag_inv[i];
+ datablock[k] = (int16)temp;
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ i++;
+ }
+ while (!last);
+
+#ifdef FAST_IDCT
+ if (i > 10) /* 07/19/01 */
+ {
+ for (k = 1; k < 4; k++) /* if (i > 10 ) k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+ return i;
+}
+