/* ------------------------------------------------------------------ * 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; }