1 /** 2 * 3 * File Name: armVCM4P2_ACDCPredict.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 module for DC/AC coefficient prediction 14 * 15 */ 16 17 #include "omxtypes.h" 18 #include "armOMX.h" 19 20 #include "armVC.h" 21 #include "armCOMM.h" 22 23 /** 24 * Function: armVCM4P2_ACDCPredict 25 * 26 * Description: 27 * Performs adaptive DC/AC coefficient prediction for an intra block. Prior 28 * to the function call, prediction direction (predDir) should be selected 29 * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2. 30 * 31 * Remarks: 32 * 33 * Parameters: 34 * [in] pSrcDst pointer to the coefficient buffer which contains 35 * the quantized coefficient residuals (PQF) of the 36 * current block 37 * [in] pPredBufRow pointer to the coefficient row buffer 38 * [in] pPredBufCol pointer to the coefficient column buffer 39 * [in] curQP quantization parameter of the current block. curQP 40 * may equal to predQP especially when the current 41 * block and the predictor block are in the same 42 * macroblock. 43 * [in] predQP quantization parameter of the predictor block 44 * [in] predDir indicates the prediction direction which takes one 45 * of the following values: 46 * OMX_VC_HORIZONTAL predict horizontally 47 * OMX_VC_VERTICAL predict vertically 48 * [in] ACPredFlag a flag indicating if AC prediction should be 49 * performed. It is equal to ac_pred_flag in the bit 50 * stream syntax of MPEG-4 51 * [in] videoComp video component type (luminance, chrominance or 52 * alpha) of the current block 53 * [in] flag This flag defines the if one wants to use this functions to 54 * calculate PQF (set 1, prediction) or QF (set 0, reconstruction) 55 * [out] pPreACPredict pointer to the predicted coefficients buffer. 56 * Filled ONLY if it is not NULL 57 * [out] pSrcDst pointer to the coefficient buffer which contains 58 * the quantized coefficients (QF) of the current 59 * block 60 * [out] pPredBufRow pointer to the updated coefficient row buffer 61 * [out] pPredBufCol pointer to the updated coefficient column buffer 62 * [out] pSumErr pointer to the updated sum of the difference 63 * between predicted and unpredicted coefficients 64 * If this is NULL, do not update 65 * 66 * Return Value: 67 * Standard OMXResult result. See enumeration for possible result codes. 68 * 69 */ 70 71 OMXResult armVCM4P2_ACDCPredict( 72 OMX_S16 * pSrcDst, 73 OMX_S16 * pPreACPredict, 74 OMX_S16 * pPredBufRow, 75 OMX_S16 * pPredBufCol, 76 OMX_INT curQP, 77 OMX_INT predQP, 78 OMX_INT predDir, 79 OMX_INT ACPredFlag, 80 OMXVCM4P2VideoComponent videoComp, 81 OMX_U8 flag, 82 OMX_INT *pSumErr 83 ) 84 { 85 OMX_INT dcScaler, i; 86 OMX_S16 tempPred; 87 88 /* Argument error checks */ 89 armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); 90 armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr); 91 armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr); 92 armRetArgErrIf(curQP <= 0, OMX_Sts_BadArgErr); 93 armRetArgErrIf(predQP <= 0, OMX_Sts_BadArgErr); 94 armRetArgErrIf((predDir != 1) && (predDir != 2), OMX_Sts_BadArgErr); 95 armRetArgErrIf(!armIs4ByteAligned(pSrcDst), OMX_Sts_BadArgErr); 96 armRetArgErrIf(!armIs4ByteAligned(pPredBufRow), OMX_Sts_BadArgErr); 97 armRetArgErrIf(!armIs4ByteAligned(pPredBufCol), OMX_Sts_BadArgErr); 98 99 100 /* Set DC scaler value to avoid some compilers giving a warning. */ 101 dcScaler=0; 102 103 /* Calculate the DC scaler value */ 104 if (videoComp == OMX_VC_LUMINANCE) 105 { 106 if (curQP >= 1 && curQP <= 4) 107 { 108 dcScaler = 8; 109 } 110 else if (curQP >= 5 && curQP <= 8) 111 { 112 dcScaler = 2 * curQP; 113 } 114 else if (curQP >= 9 && curQP <= 24) 115 { 116 dcScaler = curQP + 8; 117 } 118 else 119 { 120 dcScaler = (2 * curQP) - 16; 121 } 122 } 123 else if (videoComp == OMX_VC_CHROMINANCE) 124 { 125 if (curQP >= 1 && curQP <= 4) 126 { 127 dcScaler = 8; 128 } 129 else if (curQP >= 5 && curQP <= 24) 130 { 131 dcScaler = (curQP + 13)/2; 132 } 133 else 134 { 135 dcScaler = curQP - 6; 136 } 137 } 138 139 if (pPreACPredict != NULL) 140 { 141 pPreACPredict[0] = predDir; 142 } 143 144 if (predDir == OMX_VC_VERTICAL) 145 { 146 /* F[0][0]//dc_scaler */ 147 tempPred = armIntDivAwayFromZero(pPredBufRow[0], dcScaler); 148 } 149 else 150 { 151 /* F[0][0]//dc_scaler */ 152 tempPred = armIntDivAwayFromZero(pPredBufCol[0], dcScaler); 153 } 154 155 /* Updating the DC value to the row and col buffer */ 156 *(pPredBufRow - 8) = *pPredBufCol; 157 158 if (flag) 159 { 160 /* Cal and store F[0][0] into the col buffer */ 161 *pPredBufCol = pSrcDst[0] * dcScaler; 162 163 /* PQF = QF - F[0][0]//dc_scaler */ 164 pSrcDst[0] -= tempPred; 165 } 166 else 167 { 168 /* QF = PQF + F[0][0]//dc_scaler */ 169 pSrcDst[0] += tempPred; 170 171 /* Saturate */ 172 pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]); 173 174 /* Cal and store F[0][0] into the col buffer */ 175 *pPredBufCol = pSrcDst[0] * dcScaler; 176 } 177 178 179 if (ACPredFlag == 1) 180 { 181 if (predDir == OMX_VC_VERTICAL) 182 { 183 for (i = 1; i < 8; i++) 184 { 185 tempPred = armIntDivAwayFromZero \ 186 (pPredBufRow[i] * predQP, curQP); 187 if (flag) 188 { 189 /* Updating QF to the row buff */ 190 pPredBufRow[i] = pSrcDst[i]; 191 /*PQFX[v][0] = QFX[v][0] - (QFA[v][0] * QPA) // QPX */ 192 pSrcDst[i] -= tempPred; 193 /* Sum of absolute values of AC prediction error, this can 194 be used as a reference to choose whether to use 195 AC prediction */ 196 *pSumErr += armAbs(pSrcDst[i]); 197 /* pPreACPredict[1~7] store the error signal 198 after AC prediction */ 199 pPreACPredict[i] = pSrcDst[i]; 200 } 201 else 202 { 203 /*QFX[v][0] = PQFX[v][0] + (QFA[v][0] * QPA) // QPX */ 204 pSrcDst[i] += tempPred; 205 206 /* Saturate */ 207 pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]); 208 209 /* Updating QF to the row buff */ 210 pPredBufRow[i] = pSrcDst[i]; 211 } 212 } 213 } 214 else 215 { 216 for (i = 8; i < 64; i += 8) 217 { 218 tempPred = armIntDivAwayFromZero \ 219 (pPredBufCol[i>>3] * predQP, curQP); 220 if (flag) 221 { 222 /* Updating QF to col buff */ 223 pPredBufCol[i>>3] = pSrcDst[i]; 224 /*PQFX[0][u] = QFX[0][u] - (QFA[0][u] * QPA) // QPX */ 225 pSrcDst[i] -= tempPred; 226 /* Sum of absolute values of AC prediction error, this can 227 be used as a reference to choose whether to use AC 228 prediction */ 229 *pSumErr += armAbs(pSrcDst[i]); 230 /* pPreACPredict[1~7] store the error signal 231 after AC prediction */ 232 pPreACPredict[i>>3] = pSrcDst[i]; 233 } 234 else 235 { 236 /*QFX[0][u] = PQFX[0][u] + (QFA[0][u] * QPA) // QPX */ 237 pSrcDst[i] += tempPred; 238 239 /* Saturate */ 240 pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]); 241 242 /* Updating QF to col buff */ 243 pPredBufCol[i>>3] = pSrcDst[i]; 244 } 245 } 246 } 247 } 248 249 return OMX_Sts_NoErr; 250 } 251 252 /*End of File*/ 253 254