1 /** 2 * 3 * File Name: omxVCM4P2_DecodeBlockCoef_Intra.c 4 * OpenMAX DL: v1.0.2 5 * Revision: 9641 6 * Date: Thursday, February 7, 2008 7 * 8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 9 * 10 * 11 * 12 * Description: 13 * Contains modules for intra reconstruction 14 * 15 */ 16 17 #include "omxtypes.h" 18 #include "armOMX.h" 19 #include "omxVC.h" 20 21 #include "armCOMM.h" 22 #include "armVC.h" 23 24 /** 25 * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1) 26 * 27 * Description: 28 * Decodes the INTRA block coefficients. Inverse quantization, inversely 29 * zigzag positioning, and IDCT, with appropriate clipping on each step, are 30 * performed on the coefficients. The results are then placed in the output 31 * frame/plane on a pixel basis. Note: This function will be used only when 32 * at least one non-zero AC coefficient of current block exists in the bit 33 * stream. The DC only condition will be handled in another function. 34 * 35 * 36 * Input Arguments: 37 * 38 * ppBitStream - pointer to the pointer to the current byte in the bit 39 * stream buffer. There is no boundary check for the bit stream 40 * buffer. 41 * pBitOffset - pointer to the bit position in the byte pointed to by 42 * *ppBitStream. *pBitOffset is valid within [0-7]. 43 * step - width of the destination plane 44 * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on 45 * an 8-byte boundary. 46 * pCoefBufCol - pointer to the coefficient column buffer; must be aligned 47 * on an 8-byte boundary. 48 * curQP - quantization parameter of the macroblock which the current block 49 * belongs to 50 * pQPBuf - pointer to the quantization parameter buffer 51 * blockIndex - block index indicating the component type and position as 52 * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5. 53 * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a 54 * mechanism to switch between two VLC for coding of Intra DC 55 * coefficients as per [ISO14496-2], Table 6-21. 56 * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if 57 * the ac coefficients of the first row or first column are 58 * differentially coded for intra coded macroblock. 59 * shortVideoHeader - binary flag indicating presence of 60 * short_video_header; shortVideoHeader==1 selects linear intra DC 61 * mode, and shortVideoHeader==0 selects non linear intra DC mode. 62 * 63 * Output Arguments: 64 * 65 * ppBitStream - *ppBitStream is updated after the block is decoded, so 66 * that it points to the current byte in the bit stream buffer 67 * pBitOffset - *pBitOffset is updated so that it points to the current bit 68 * position in the byte pointed by *ppBitStream 69 * pDst - pointer to the block in the destination plane; must be aligned on 70 * an 8-byte boundary. 71 * pCoefBufRow - pointer to the updated coefficient row buffer. 72 * pCoefBufCol - pointer to the updated coefficient column buffer Note: 73 * The coefficient buffers must be updated in accordance with the 74 * update procedure defined in section 6.2.2. 75 * 76 * Return Value: 77 * 78 * OMX_Sts_NoErr - no error 79 * OMX_Sts_BadArgErr - bad arguments, if: 80 * - At least one of the following pointers is NULL: 81 * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol, 82 * pQPBuf, pDst. 83 * - *pBitOffset exceeds [0,7] 84 * - curQP exceeds (1, 31) 85 * - blockIndex exceeds [0,5] 86 * - step is not the multiple of 8 87 * - a pointer alignment requirement was violated. 88 * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra. 89 * 90 */ 91 92 OMXResult omxVCM4P2_DecodeBlockCoef_Intra( 93 const OMX_U8 ** ppBitStream, 94 OMX_INT *pBitOffset, 95 OMX_U8 *pDst, 96 OMX_INT step, 97 OMX_S16 *pCoefBufRow, 98 OMX_S16 *pCoefBufCol, 99 OMX_U8 curQP, 100 const OMX_U8 *pQPBuf, 101 OMX_INT blockIndex, 102 OMX_INT intraDCVLC, 103 OMX_INT ACPredFlag, 104 OMX_INT shortVideoHeader 105 ) 106 { 107 OMX_S16 tempBuf1[79], tempBuf2[79]; 108 OMX_S16 *pTempBuf1, *pTempBuf2; 109 OMX_INT predDir, predACDir, i, j, count; 110 OMX_INT predQP; 111 OMXVCM4P2VideoComponent videoComp; 112 OMXResult errorCode; 113 114 /* Argument error checks */ 115 armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); 116 armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); 117 armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); 118 armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); 119 armRetArgErrIf(pCoefBufRow == NULL, OMX_Sts_BadArgErr); 120 armRetArgErrIf(pCoefBufCol == NULL, OMX_Sts_BadArgErr); 121 armRetArgErrIf(pQPBuf == NULL, OMX_Sts_BadArgErr); 122 armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr); 123 armRetArgErrIf(((curQP <= 0) || (curQP >= 32)), OMX_Sts_BadArgErr); 124 armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr); 125 armRetArgErrIf((blockIndex < 0) || (blockIndex > 5), OMX_Sts_BadArgErr); 126 armRetArgErrIf((step % 8) != 0, OMX_Sts_BadArgErr); 127 128 129 /* Aligning the local buffers */ 130 pTempBuf1 = armAlignTo16Bytes(tempBuf1); 131 pTempBuf2 = armAlignTo16Bytes(tempBuf2); 132 133 /* Setting the AC prediction direction and prediction direction */ 134 armVCM4P2_SetPredDir( 135 blockIndex, 136 pCoefBufRow, 137 pCoefBufCol, 138 &predDir, 139 &predQP, 140 pQPBuf); 141 142 predACDir = predDir; 143 144 armRetArgErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr); 145 146 if (ACPredFlag == 0) 147 { 148 predACDir = OMX_VC_NONE; 149 } 150 151 /* Setting the videoComp */ 152 if (blockIndex <= 3) 153 { 154 videoComp = OMX_VC_LUMINANCE; 155 } 156 else 157 { 158 videoComp = OMX_VC_CHROMINANCE; 159 } 160 161 162 /* VLD and zigzag */ 163 if (intraDCVLC == 1) 164 { 165 errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC( 166 ppBitStream, 167 pBitOffset, 168 pTempBuf1, 169 predACDir, 170 shortVideoHeader, 171 videoComp); 172 armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); 173 } 174 else 175 { 176 errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC( 177 ppBitStream, 178 pBitOffset, 179 pTempBuf1, 180 predACDir, 181 shortVideoHeader); 182 armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); 183 } 184 185 /* AC DC prediction */ 186 errorCode = omxVCM4P2_PredictReconCoefIntra( 187 pTempBuf1, 188 pCoefBufRow, 189 pCoefBufCol, 190 curQP, 191 predQP, 192 predDir, 193 ACPredFlag, 194 videoComp); 195 armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); 196 197 /* Dequantization */ 198 errorCode = omxVCM4P2_QuantInvIntra_I( 199 pTempBuf1, 200 curQP, 201 videoComp, 202 shortVideoHeader); 203 armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); 204 205 /* Inverse transform */ 206 errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2); 207 armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); 208 209 /* Placing the linear array into the destination plane and clipping 210 it to 0 to 255 */ 211 for (j = 0, count = 0; j < 8; j++) 212 { 213 for(i = 0; i < 8; i++, count++) 214 { 215 pDst[i] = armClip (0, 255, pTempBuf2[count]); 216 } 217 pDst += step; 218 } 219 220 return OMX_Sts_NoErr; 221 } 222 223 /* End of file */ 224 225 226