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