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
82pSrcDst          RN 0
83pPredBufRow      RN 1
84pPredBufCol      RN 2
85curQP            RN 3
86QP               RN 3
87predQP           RN 4
88predDir          RN 5
89ACPredFlag       RN 6
90videoComp        RN 7
91
92;// Local Variables
93
94temp2            RN 5
95negCurQP         RN 7
96negdcScaler      RN 7
97tempPred         RN 8
98
99dcScaler         RN 4
100CoeffTable       RN 9
101absCoeffDC       RN 9
102temp3            RN 6
103absCoeffAC       RN 6
104
105shortVideoHeader RN 9
106predCoeffTable   RN 10
107Count            RN 10
108temp1            RN 12
109index            RN 12
110Rem              RN 14
111temp             RN 11
112Return           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
138calDCVal
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
205loop1
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
236Horizontal
237
238       MOV             Count,#16                                      ;// Initializing i=8
239
240loop2
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
274Exit
275
276       MOV             Return,#OMX_Sts_NoErr
277
278       M_END
279       ENDIF
280       END
281
282
283
284