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