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