1/** 2 * 3 * File Name: omxVCM4P10_SubAndTransformQDQResidual.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 * Description: 12 * This function will calculate SAD for 4x4 blocks 13 * 14 */ 15 16#include "omxtypes.h" 17#include "armOMX.h" 18#include "omxVC.h" 19 20#include "armCOMM.h" 21#include "armVC.h" 22 23/** 24 * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1) 25 * 26 * Description: 27 * This function subtracts the prediction signal from the original signal to 28 * produce the difference signal and then performs a 4x4 integer transform and 29 * quantization. The quantized transformed coefficients are stored as 30 * pDstQuantCoeff. This function can also output dequantized coefficients or 31 * unquantized DC coefficients optionally by setting the pointers 32 * pDstDeQuantCoeff, pDCCoeff. 33 * 34 * Input Arguments: 35 * 36 * pSrcOrg - Pointer to original signal. 4-byte alignment required. 37 * pSrcPred - Pointer to prediction signal. 4-byte alignment required. 38 * iSrcOrgStep - Step of the original signal buffer; must be a multiple of 39 * 4. 40 * iSrcPredStep - Step of the prediction signal buffer; must be a multiple 41 * of 4. 42 * pNumCoeff -Number of non-zero coefficients after quantization. If this 43 * parameter is not required, it is set to NULL. 44 * nThreshSAD - Zero-block early detection threshold. If this parameter is 45 * not required, it is set to 0. 46 * iQP - Quantization parameter; must be in the range [0,51]. 47 * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or 48 * 0-INTER 49 * 50 * Output Arguments: 51 * 52 * pDstQuantCoeff - Pointer to the quantized transformed coefficients. 53 * 8-byte alignment required. 54 * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients 55 * if this parameter is not equal to NULL. 8-byte alignment 56 * required. 57 * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter 58 * is not equal to NULL. 59 * 60 * Return Value: 61 * 62 * OMX_Sts_NoErr - no error 63 * OMX_Sts_BadArgErr - bad arguments; returned if any of the following 64 * conditions are true: 65 * - at least one of the following pointers is NULL: 66 * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff, 67 * pDstDeQuantCoeff, pDCCoeff 68 * - pSrcOrg is not aligned on a 4-byte boundary 69 * - pSrcPred is not aligned on a 4-byte boundary 70 * - iSrcOrgStep is not a multiple of 4 71 * - iSrcPredStep is not a multiple of 4 72 * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary 73 * 74 */ 75 OMXResult omxVCM4P10_SubAndTransformQDQResidual ( 76 const OMX_U8* pSrcOrg, 77 const OMX_U8* pSrcPred, 78 OMX_U32 iSrcOrgStep, 79 OMX_U32 iSrcPredStep, 80 OMX_S16* pDstQuantCoeff, 81 OMX_S16* pDstDeQuantCoeff, 82 OMX_S16* pDCCoeff, 83 OMX_S8* pNumCoeff, 84 OMX_U32 nThreshSAD, 85 OMX_U32 iQP, 86 OMX_U8 bIntra 87) 88{ 89 OMX_INT i, j; 90 OMX_S8 NumCoeff = 0; 91 OMX_S16 Buf[16], m[16]; 92 OMX_U32 QBits, QPper, QPmod, f; 93 OMX_S32 Value, MF, ThreshDC; 94 95 /* check for argument error */ 96 armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr) 97 armRetArgErrIf(pDstDeQuantCoeff == NULL, OMX_Sts_BadArgErr) 98 armRetArgErrIf(pNumCoeff == NULL, OMX_Sts_BadArgErr) 99 armRetArgErrIf(pDCCoeff == NULL, OMX_Sts_BadArgErr) 100 armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr) 101 armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr) 102 armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr) 103 armRetArgErrIf(pDstQuantCoeff == NULL, OMX_Sts_BadArgErr) 104 armRetArgErrIf(armNot8ByteAligned(pDstQuantCoeff), OMX_Sts_BadArgErr) 105 armRetArgErrIf((pDstDeQuantCoeff != NULL) && 106 armNot8ByteAligned(pDstDeQuantCoeff), OMX_Sts_BadArgErr) 107 armRetArgErrIf((bIntra != 0) && (bIntra != 1), OMX_Sts_BadArgErr) 108 armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr) 109 armRetArgErrIf(iSrcOrgStep == 0, OMX_Sts_BadArgErr) 110 armRetArgErrIf(iSrcPredStep == 0, OMX_Sts_BadArgErr) 111 armRetArgErrIf(iSrcOrgStep & 3, OMX_Sts_BadArgErr) 112 armRetArgErrIf(iSrcPredStep & 3, OMX_Sts_BadArgErr) 113 114 /* 115 * Zero-Block Early detection using nThreshSAD param 116 */ 117 118 QPper = iQP / 6; 119 QPmod = iQP % 6; 120 QBits = 15 + QPper; 121 122 f = (1 << QBits) / (bIntra ? 3 : 6); 123 124 /* Do Zero-Block Early detection if enabled */ 125 if (nThreshSAD) 126 { 127 ThreshDC = ((1 << QBits) - f) / armVCM4P10_MFMatrix[QPmod][0]; 128 if (nThreshSAD < ThreshDC) 129 { 130 /* Set block to zero */ 131 if (pDCCoeff != NULL) 132 { 133 *pDCCoeff = 0; 134 } 135 136 for (j = 0; j < 4; j++) 137 { 138 for (i = 0; i < 4; i++) 139 { 140 pDstQuantCoeff [4 * j + i] = 0; 141 if (pDstDeQuantCoeff != NULL) 142 { 143 pDstDeQuantCoeff [4 * j + i] = 0; 144 } 145 } 146 } 147 148 if (pNumCoeff != NULL) 149 { 150 *pNumCoeff = 0; 151 } 152 return OMX_Sts_NoErr; 153 } 154 } 155 156 157 /* Calculate difference */ 158 for (j = 0; j < 4; j++) 159 { 160 for (i = 0; i < 4; i++) 161 { 162 Buf [j * 4 + i] = 163 pSrcOrg [j * iSrcOrgStep + i] - pSrcPred [j * iSrcPredStep + i]; 164 } 165 } 166 167 /* Residual Transform */ 168 armVCM4P10_FwdTransformResidual4x4 (m, Buf); 169 170 if (pDCCoeff != NULL) 171 { 172 /* Copy unquantized DC value into pointer */ 173 *pDCCoeff = m[0]; 174 } 175 176 /* Quantization */ 177 for (j = 0; j < 4; j++) 178 { 179 for (i = 0; i < 4; i++) 180 { 181 MF = armVCM4P10_MFMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]]; 182 Value = armAbs(m[j * 4 + i]) * MF + f; 183 Value >>= QBits; 184 Value = m[j * 4 + i] < 0 ? -Value : Value; 185 Buf[4 * j + i] = pDstQuantCoeff [4 * j + i] = (OMX_S16)Value; 186 if ((pNumCoeff != NULL) && Value) 187 { 188 NumCoeff++; 189 } 190 } 191 } 192 193 /* Output number of non-zero Coeffs */ 194 if (pNumCoeff != NULL) 195 { 196 *pNumCoeff = NumCoeff; 197 } 198 199 /* Residual Inv Transform */ 200 if (pDstDeQuantCoeff != NULL) 201 { 202 /* Re Scale */ 203 for (j = 0; j < 4; j++) 204 { 205 for (i = 0; i < 4; i++) 206 { 207 m [j * 4 + i] = Buf [j * 4 + i] * (1 << QPper) * 208 armVCM4P10_VMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]]; 209 } 210 } 211 armVCM4P10_TransformResidual4x4 (pDstDeQuantCoeff, m); 212 } 213 214 return OMX_Sts_NoErr; 215} 216 217/***************************************************************************** 218 * END OF FILE 219 *****************************************************************************/ 220 221