1 ; ********** 2 ; * 3 ; * File Name: omxVCM4P2_PredictReconCoefIntra_s.s 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 ; * Function: omxVCM4P2_PredictReconCoefIntra 17 ; * 18 ; * Description: 19 ; * Performs adaptive DC/AC coefficient prediction for an intra block. Prior 20 ; * to the function call, prediction direction (predDir) should be selected 21 ; * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2. 22 ; * 23 ; * Remarks: 24 ; * 25 ; * Parameters: 26 ; * [in] pSrcDst pointer to the coefficient buffer which contains the 27 ; * quantized coefficient residuals (PQF) of the current 28 ; * block; must be aligned on a 4-byte boundary. The 29 ; * output coefficients are saturated to the range 30 ; * [-2048, 2047]. 31 ; * [in] pPredBufRow pointer to the coefficient row buffer; must be aligned 32 ; * on a 4-byte boundary. 33 ; * [in] pPredBufCol pointer to the coefficient column buffer; must be 34 ; * aligned on a 4-byte boundary. 35 ; * [in] curQP quantization parameter of the current block. curQP may 36 ; * equal to predQP especially when the current block and 37 ; * the predictor block are in the same macroblock. 38 ; * [in] predQP quantization parameter of the predictor block 39 ; * [in] predDir indicates the prediction direction which takes one 40 ; * of the following values: 41 ; * OMX_VIDEO_HORIZONTAL predict horizontally 42 ; * OMX_VIDEO_VERTICAL predict vertically 43 ; * [in] ACPredFlag a flag indicating if AC prediction should be 44 ; * performed. It is equal to ac_pred_flag in the bit 45 ; * stream syntax of MPEG-4 46 ; * [in] videoComp video component type (luminance, chrominance or 47 ; * alpha) of the current block 48 ; * [out] pSrcDst pointer to the coefficient buffer which contains 49 ; * the quantized coefficients (QF) of the current 50 ; * block 51 ; * [out] pPredBufRow pointer to the updated coefficient row buffer 52 ; * [out] pPredBufCol pointer to the updated coefficient column buffer 53 ; * Return Value: 54 ; * OMX_Sts_NoErr - no error 55 ; * OMX_Sts_BadArgErr - Bad arguments 56 ; * - At least one of the pointers is NULL: pSrcDst, pPredBufRow, or pPredBufCol. 57 ; * - At least one the following cases: curQP <= 0, predQP <= 0, curQP >31, 58 ; * predQP > 31, preDir exceeds [1,2]. 59 ; * - At least one of the pointers pSrcDst, pPredBufRow, or pPredBufCol is not 60 ; * 4-byte aligned. 61 ; * 62 ; ********* 63 64 INCLUDE omxtypes_s.h 65 INCLUDE armCOMM_s.h 66 67 M_VARIANTS ARM1136JS 68 69 70 71 IMPORT armVCM4P2_Reciprocal_QP_S32 72 IMPORT armVCM4P2_Reciprocal_QP_S16 73 IMPORT armVCM4P2_DCScaler 74 75 76 77 IF ARM1136JS 78 79 80 ;// Input Arguments 81 82 pSrcDst RN 0 83 pPredBufRow RN 1 84 pPredBufCol RN 2 85 curQP RN 3 86 QP RN 3 87 predQP RN 4 88 predDir RN 5 89 ACPredFlag RN 6 90 videoComp RN 7 91 92 ;// Local Variables 93 94 temp2 RN 5 95 negCurQP RN 7 96 negdcScaler RN 7 97 tempPred RN 8 98 99 dcScaler RN 4 100 CoeffTable RN 9 101 absCoeffDC RN 9 102 temp3 RN 6 103 absCoeffAC RN 6 104 105 shortVideoHeader RN 9 106 predCoeffTable RN 10 107 Count RN 10 108 temp1 RN 12 109 index RN 12 110 Rem RN 14 111 temp RN 11 112 Return RN 0 113 114 115 116 M_START omxVCM4P2_PredictReconCoefIntra,r12 117 118 ;// Assigning pointers to Input arguments on Stack 119 120 M_ARG predQPonStack,4 121 M_ARG predDironStack,4 122 M_ARG ACPredFlagonStack,4 123 M_ARG videoComponStack,4 124 125 ;// DC Prediction 126 127 M_LDR videoComp,videoComponStack ;// Load videoComp From Stack 128 129 M_LDR predDir,predDironStack ;// Load Prediction direction 130 131 ;// dcScaler Calculation 132 133 LDR index, =armVCM4P2_DCScaler 134 ADD index,index,videoComp,LSL #5 135 LDRB dcScaler,[index,QP] 136 137 138 calDCVal 139 140 141 LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S16 ;// Loading the table with entries 32767/(1 to 63) 142 143 CMP predDir,#2 ;// Check if the Prediction direction is vertical 144 145 ;// Caulucate temp pred by performing Division 146 147 LDREQSH absCoeffDC,[pPredBufRow] ;// If vetical load the coeff from Row Prediction Buffer 148 LDRNESH absCoeffDC,[pPredBufCol] ;// If horizontal load the coeff from column Prediction Buffer 149 150 RSB negdcScaler,dcScaler,#0 ;// negdcScaler=-dcScaler 151 152 MOV temp1,absCoeffDC ;// temp1=prediction coeff 153 CMP temp1,#0 154 RSBLT absCoeffDC,temp1,#0 ;//absCoeffDC=abs(temp1) 155 156 ADD temp,dcScaler,dcScaler 157 LDRH temp,[predCoeffTable,temp] ;// Load value from coeff table for performing division using multiplication 158 159 SMULBB tempPred,temp,absCoeffDC ;// tempPred=pPredBufRow(Col)[0]*32767/dcScaler 160 ADD temp3,dcScaler,#1 161 LSR tempPred,tempPred,#15 ;// tempPred=pPredBufRow(Col)[0]/dcScaler 162 LSR temp3,temp3,#1 ;// temp3=round(dcScaler/2) 163 164 MLA Rem,negdcScaler,tempPred,absCoeffDC ;// Rem = pPredBufRow(Col)[0]-tempPred*dcScaler 165 166 167 LDRH temp,[pPredBufCol] 168 CMP Rem,temp3 169 ADDGE tempPred,#1 ;// If Rem>=round(dcScaler/2);tempPred=tempPred+1 170 CMP temp1,#0 171 RSBLT tempPred,tempPred,#0 ;/ if pPredBufRow(Col)[0]<0; tempPred=-tempPred 172 173 174 STRH temp,[pPredBufRow,#-16] 175 176 LDRH temp,[pSrcDst] ;// temp=pSrcDst[0] 177 M_LDR ACPredFlag,ACPredFlagonStack 178 ADD temp,temp,tempPred ;// temp=pSrcDst[0]+tempPred 179 SSAT16 temp,#12,temp ;// clip temp to [-2048,2047] 180 181 SMULBB temp1,temp,dcScaler ;// temp1=clipped(pSrcDst[0])*dcScaler 182 M_LDR predQP,predQPonStack 183 STRH temp,[pSrcDst] 184 CMP ACPredFlag,#1 ;// Check if the AC prediction flag is set or not 185 STRH temp1,[pPredBufCol] ;// store temp1 to pPredBufCol 186 187 ;// AC Prediction 188 189 190 BNE Exit ;// If not set Exit 191 192 LDR predCoeffTable, =armVCM4P2_Reciprocal_QP_S32 ;// Loading the table with entries 0x1ffff/(1 to 63) 193 MOV temp1,#4 194 MUL temp1,curQP,temp1 195 CMP predDir,#2 ;// Check the Prediction direction 196 RSB negCurQP,curQP,#0 197 LDR CoeffTable,[predCoeffTable,temp1] ;// CoeffTable=0x1ffff/curQP 198 ADD curQP,curQP,#1 ;// curQP=curQP+1 199 LSR curQP,curQP,#1 ;// curQP=round(curQP/2) 200 MOV Count,#2 ;// Initializing the Loop Count 201 BNE Horizontal ;// If the Prediction direction is horizontal branch to Horizontal 202 203 204 205 loop1 206 ;// Calculate tempPred 207 208 LDRSH absCoeffAC,[pPredBufRow,Count] ;// absCoeffAC=pPredBufRow[i], 1=<i<=7 209 MOV temp1,absCoeffAC 210 CMP temp1,#0 ;// compare pPredBufRow[i] with zero, 1=<i<=7 211 RSBLT absCoeffAC,temp1,#0 ;// absCoeffAC= abs(pPredBufRow[i]) 212 213 SMULBB absCoeffAC,absCoeffAC,predQP ;// temp1=pPredBufRow[i]*predQP 214 MUL tempPred,absCoeffAC,CoeffTable ;// tempPred=pPredBufRow[i]*predQP*0x1ffff/curQP 215 LSR tempPred,tempPred,#17 216 217 MLA Rem,negCurQP,tempPred,absCoeffAC ;// Rem=abs(pPredBufRow[i])-tempPred*curQP 218 LDRH temp,[pSrcDst,Count] ;// temp=pSrcDst[i],1<=i<8 219 220 CMP Rem,curQP 221 ADDGE tempPred,#1 ;// if Rem>=round(curQP/2); tempPred=tempPred+1 222 CMP temp1,#0 223 RSBLT tempPred,tempPred,#0 ;// if pPredBufRow[i]<0 ; tempPred=-tempPred 224 225 ;// Update source and Row Prediction buffers 226 227 ADD temp,temp,tempPred ;// temp=tempPred+pSrcDst[i] 228 SSAT16 temp,#12,temp ;// Clip temp to [-2048,2047] 229 STRH temp,[pSrcDst,Count] 230 STRH temp,[pPredBufRow,Count] ;// pPredBufRow[i]=temp 231 ADD Count,Count,#2 ;// i=i+1 232 CMP Count,#16 ;// compare if i=8 233 BLT loop1 234 B Exit ;// Branch to exit 235 236 Horizontal 237 238 MOV Count,#16 ;// Initializing i=8 239 240 loop2 241 242 LSR temp2,Count,#3 ;// temp2=i>>3 243 244 ;// Calculate tempPred 245 246 LDRH absCoeffAC,[pPredBufCol,temp2] ;// absCoefAC=pPredBufCol[i>>3] 247 MOV temp1,absCoeffAC 248 CMP temp1,#0 ;// compare pPredBufRow[i] with zero, 1=<i<=7 249 RSBLT absCoeffAC,temp1,#0 ;// absCoeffAC=abs(pPredBufCol[i>>3]) 250 251 SMULBB absCoeffAC,absCoeffAC,predQP ;// temp1=pPredBufCol[i>>3]*predQP 252 MUL tempPred,absCoeffAC,CoeffTable ;// tempPred=pPredBufCol[i>>3]*predQP*0x1ffff/curQP 253 LSR tempPred,tempPred,#17 ;// tempPred=pPredBufCol[i>>3]*predQP/curQP 254 255 MLA Rem,negCurQP,tempPred,absCoeffAC 256 LDRH temp,[pSrcDst,Count] ;// temp=pSrcDst[i] 257 258 CMP Rem,curQP ;// Compare Rem with round(curQP/2) 259 ADDGE tempPred,#1 ;// tempPred=tempPred+1 if Rem>=round(curQP/2) 260 CMP temp1,#0 261 RSBLT tempPred,tempPred,#0 ;// if pPredBufCol[i>>3 <0 tempPred=-tempPred 262 263 ;// Update source and Row Prediction buffers 264 265 ADD temp,temp,tempPred ;// temp=pSrcDst[i]+tempPred 266 SSAT16 temp,#12,temp ;// Clip temp to [-2048,2047] 267 STRH temp,[pSrcDst,Count] ;// pSrcDst[0]= clipped value 268 STRH temp,[pPredBufCol,temp2] ;// pPredBufCol[i>>3]=temp 269 ADD Count,Count,#16 ;// i=i+8 270 CMP Count,#128 ;// compare i with 64 271 BLT loop2 272 273 274 Exit 275 276 MOV Return,#OMX_Sts_NoErr 277 278 M_END 279 ENDIF 280 END 281 282 283 284