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