diff options
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.cpp | 1152 |
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; +} + |