omxVCM4P2_PredictReconCoefIntra_s.s 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; * 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
96pSrcDst          RN 0
97pPredBufRow      RN 1
98pPredBufCol      RN 2
99curQP            RN 3
100QP               RN 3
101predQP           RN 4
102predDir          RN 5
103ACPredFlag       RN 6
104videoComp        RN 7
105
106;// Local Variables
107
108temp2            RN 5
109negCurQP         RN 7
110negdcScaler      RN 7
111tempPred         RN 8
112
113dcScaler         RN 4
114CoeffTable       RN 9
115absCoeffDC       RN 9
116temp3            RN 6
117absCoeffAC       RN 6
118
119shortVideoHeader RN 9
120predCoeffTable   RN 10
121Count            RN 10
122temp1            RN 12
123index            RN 12
124Rem              RN 14
125temp             RN 11
126Return           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
152calDCVal
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
219loop1
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
250Horizontal
251
252       MOV             Count,#16                                      ;// Initializing i=8
253
254loop2
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
288Exit
289
290       MOV             Return,#OMX_Sts_NoErr
291
292       M_END
293       ENDIF
294       END
295
296
297
298