1 /*
2 * Copyright (C) 2009 The Android Open Source Project
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
19 Table of contents
20
21 1. Include headers
22 2. External compiler flags
23 3. Module defines
24 4. Local function prototypes
25 5. Functions
26 h264bsdProcessBlock
27 h264bsdProcessLumaDc
28 h264bsdProcessChromaDc
29
30 ------------------------------------------------------------------------------*/
31
32 /*------------------------------------------------------------------------------
33 1. Include headers
34 ------------------------------------------------------------------------------*/
35
36 #include "basetype.h"
37 #include "h264bsd_transform.h"
38 #include "h264bsd_util.h"
39
40 /*------------------------------------------------------------------------------
41 2. External compiler flags
42 --------------------------------------------------------------------------------
43
44 --------------------------------------------------------------------------------
45 3. Module defines
46 ------------------------------------------------------------------------------*/
47
48 /* Switch off the following Lint messages for this file:
49 * Info 701: Shift left of signed quantity (int)
50 * Info 702: Shift right of signed quantity (int)
51 */
52 /*lint -e701 -e702 */
53
54 /* LevelScale function */
55 static const i32 levelScale[6][3] = {
56 {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}};
57
58 /* qp % 6 as a function of qp */
59 static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,
60 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3};
61
62 /* qp / 6 as a function of qp */
63 static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,
64 4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8};
65
66 /*------------------------------------------------------------------------------
67 4. Local function prototypes
68 ------------------------------------------------------------------------------*/
69
70 /*------------------------------------------------------------------------------
71
72 Function: h264bsdProcessBlock
73
74 Functional description:
75 Function performs inverse zig-zag scan, inverse scaling and
76 inverse transform for a luma or a chroma residual block
77
78 Inputs:
79 data pointer to data to be processed
80 qp quantization parameter
81 skip skip processing of data[0], set to non-zero value
82 if dc coeff hanled separately
83 coeffMap 16 lsb's indicate which coeffs are non-zero,
84 bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc.
85
86 Outputs:
87 data processed data
88
89 Returns:
90 HANTRO_OK success
91 HANTRO_NOK processed data not in valid range [-512, 511]
92
93 ------------------------------------------------------------------------------*/
h264bsdProcessBlock(i32 * data,u32 qp,u32 skip,u32 coeffMap)94 u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap)
95 {
96
97 /* Variables */
98
99 i32 tmp0, tmp1, tmp2, tmp3;
100 i32 d1, d2, d3;
101 u32 row,col;
102 u32 qpDiv;
103 i32 *ptr;
104
105 /* Code */
106
107 qpDiv = qpDiv6[qp];
108 tmp1 = levelScale[qpMod6[qp]][0] << qpDiv;
109 tmp2 = levelScale[qpMod6[qp]][1] << qpDiv;
110 tmp3 = levelScale[qpMod6[qp]][2] << qpDiv;
111
112 if (!skip)
113 data[0] = (data[0] * tmp1);
114
115 /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes
116 * the scanning order into account */
117 if (coeffMap & 0xFF9C)
118 {
119 /* do the zig-zag scan and inverse quantization */
120 d1 = data[1];
121 d2 = data[14];
122 d3 = data[15];
123 data[1] = (d1 * tmp2);
124 data[14] = (d2 * tmp2);
125 data[15] = (d3 * tmp3);
126
127 d1 = data[2];
128 d2 = data[5];
129 d3 = data[4];
130 data[4] = (d1 * tmp2);
131 data[2] = (d2 * tmp1);
132 data[5] = (d3 * tmp3);
133
134 d1 = data[8];
135 d2 = data[3];
136 d3 = data[6];
137 tmp0 = (d1 * tmp2);
138 data[8] = (d2 * tmp1);
139 data[3] = (d3 * tmp2);
140 d1 = data[7];
141 d2 = data[12];
142 d3 = data[9];
143 data[6] = (d1 * tmp2);
144 data[7] = (d2 * tmp3);
145 data[12] = (d3 * tmp2);
146 data[9] = tmp0;
147
148 d1 = data[10];
149 d2 = data[11];
150 d3 = data[13];
151 data[13] = (d1 * tmp3);
152 data[10] = (d2 * tmp1);
153 data[11] = (d3 * tmp2);
154
155 /* horizontal transform */
156 for (row = 4, ptr = data; row--; ptr += 4)
157 {
158 tmp0 = ptr[0] + ptr[2];
159 tmp1 = ptr[0] - ptr[2];
160 tmp2 = (ptr[1] >> 1) - ptr[3];
161 tmp3 = ptr[1] + (ptr[3] >> 1);
162 ptr[0] = tmp0 + tmp3;
163 ptr[1] = tmp1 + tmp2;
164 ptr[2] = tmp1 - tmp2;
165 ptr[3] = tmp0 - tmp3;
166 }
167
168 /*lint +e661 +e662*/
169 /* then vertical transform */
170 for (col = 4; col--; data++)
171 {
172 tmp0 = data[0] + data[8];
173 tmp1 = data[0] - data[8];
174 tmp2 = (data[4] >> 1) - data[12];
175 tmp3 = data[4] + (data[12] >> 1);
176 data[0 ] = (tmp0 + tmp3 + 32)>>6;
177 data[4 ] = (tmp1 + tmp2 + 32)>>6;
178 data[8 ] = (tmp1 - tmp2 + 32)>>6;
179 data[12] = (tmp0 - tmp3 + 32)>>6;
180 /* check that each value is in the range [-512,511] */
181 if (((u32)(data[0] + 512) > 1023) ||
182 ((u32)(data[4] + 512) > 1023) ||
183 ((u32)(data[8] + 512) > 1023) ||
184 ((u32)(data[12] + 512) > 1023) )
185 return(HANTRO_NOK);
186 }
187 }
188 else /* rows 1, 2 and 3 are zero */
189 {
190 /* only dc-coeff is non-zero, i.e. coeffs at original positions
191 * 1, 5 and 6 are zero */
192 if ((coeffMap & 0x62) == 0)
193 {
194 tmp0 = (data[0] + 32) >> 6;
195 /* check that value is in the range [-512,511] */
196 if ((u32)(tmp0 + 512) > 1023)
197 return(HANTRO_NOK);
198 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
199 data[6] = data[7] = data[8] = data[9] = data[10] =
200 data[11] = data[12] = data[13] = data[14] = data[15] =
201 tmp0;
202 }
203 else /* at least one of the coeffs 1, 5 or 6 is non-zero */
204 {
205 data[1] = (data[1] * tmp2);
206 data[2] = (data[5] * tmp1);
207 data[3] = (data[6] * tmp2);
208 tmp0 = data[0] + data[2];
209 tmp1 = data[0] - data[2];
210 tmp2 = (data[1] >> 1) - data[3];
211 tmp3 = data[1] + (data[3] >> 1);
212 data[0] = (tmp0 + tmp3 + 32)>>6;
213 data[1] = (tmp1 + tmp2 + 32)>>6;
214 data[2] = (tmp1 - tmp2 + 32)>>6;
215 data[3] = (tmp0 - tmp3 + 32)>>6;
216 data[4] = data[8] = data[12] = data[0];
217 data[5] = data[9] = data[13] = data[1];
218 data[6] = data[10] = data[14] = data[2];
219 data[7] = data[11] = data[15] = data[3];
220 /* check that each value is in the range [-512,511] */
221 if (((u32)(data[0] + 512) > 1023) ||
222 ((u32)(data[1] + 512) > 1023) ||
223 ((u32)(data[2] + 512) > 1023) ||
224 ((u32)(data[3] + 512) > 1023) )
225 return(HANTRO_NOK);
226 }
227 }
228
229 return(HANTRO_OK);
230
231 }
232
233 /*------------------------------------------------------------------------------
234
235 Function: h264bsdProcessLumaDc
236
237 Functional description:
238 Function performs inverse zig-zag scan, inverse transform and
239 inverse scaling for a luma DC coefficients block
240
241 Inputs:
242 data pointer to data to be processed
243 qp quantization parameter
244
245 Outputs:
246 data processed data
247
248 Returns:
249 none
250
251 ------------------------------------------------------------------------------*/
h264bsdProcessLumaDc(i32 * data,u32 qp)252 void h264bsdProcessLumaDc(i32 *data, u32 qp)
253 {
254
255 /* Variables */
256
257 i32 tmp0, tmp1, tmp2, tmp3;
258 u32 row,col;
259 u32 qpMod, qpDiv;
260 i32 levScale;
261 i32 *ptr;
262
263 /* Code */
264
265 qpMod = qpMod6[qp];
266 qpDiv = qpDiv6[qp];
267
268 /* zig-zag scan */
269 tmp0 = data[2];
270 data[2] = data[5];
271 data[5] = data[4];
272 data[4] = tmp0;
273
274 tmp0 = data[8];
275 data[8] = data[3];
276 data[3] = data[6];
277 data[6] = data[7];
278 data[7] = data[12];
279 data[12] = data[9];
280 data[9] = tmp0;
281
282 tmp0 = data[10];
283 data[10] = data[11];
284 data[11] = data[13];
285 data[13] = tmp0;
286
287 /* horizontal transform */
288 for (row = 4, ptr = data; row--; ptr += 4)
289 {
290 tmp0 = ptr[0] + ptr[2];
291 tmp1 = ptr[0] - ptr[2];
292 tmp2 = ptr[1] - ptr[3];
293 tmp3 = ptr[1] + ptr[3];
294 ptr[0] = tmp0 + tmp3;
295 ptr[1] = tmp1 + tmp2;
296 ptr[2] = tmp1 - tmp2;
297 ptr[3] = tmp0 - tmp3;
298 }
299
300 /*lint +e661 +e662*/
301 /* then vertical transform and inverse scaling */
302 levScale = levelScale[ qpMod ][0];
303 if (qp >= 12)
304 {
305 levScale <<= (qpDiv-2);
306 for (col = 4; col--; data++)
307 {
308 tmp0 = data[0] + data[8 ];
309 tmp1 = data[0] - data[8 ];
310 tmp2 = data[4] - data[12];
311 tmp3 = data[4] + data[12];
312 data[0 ] = ((tmp0 + tmp3)*levScale);
313 data[4 ] = ((tmp1 + tmp2)*levScale);
314 data[8 ] = ((tmp1 - tmp2)*levScale);
315 data[12] = ((tmp0 - tmp3)*levScale);
316 }
317 }
318 else
319 {
320 i32 tmp;
321 tmp = ((1 - qpDiv) == 0) ? 1 : 2;
322 for (col = 4; col--; data++)
323 {
324 tmp0 = data[0] + data[8 ];
325 tmp1 = data[0] - data[8 ];
326 tmp2 = data[4] - data[12];
327 tmp3 = data[4] + data[12];
328 data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv);
329 data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv);
330 data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv);
331 data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv);
332 }
333 }
334
335 }
336
337 /*------------------------------------------------------------------------------
338
339 Function: h264bsdProcessChromaDc
340
341 Functional description:
342 Function performs inverse transform and inverse scaling for a
343 chroma DC coefficients block
344
345 Inputs:
346 data pointer to data to be processed
347 qp quantization parameter
348
349 Outputs:
350 data processed data
351
352 Returns:
353 none
354
355 ------------------------------------------------------------------------------*/
h264bsdProcessChromaDc(i32 * data,u32 qp)356 void h264bsdProcessChromaDc(i32 *data, u32 qp)
357 {
358
359 /* Variables */
360
361 i32 tmp0, tmp1, tmp2, tmp3;
362 u32 qpDiv;
363 i32 levScale;
364 u32 levShift;
365
366 /* Code */
367
368 qpDiv = qpDiv6[qp];
369 levScale = levelScale[ qpMod6[qp] ][0];
370
371 if (qp >= 6)
372 {
373 levScale <<= (qpDiv-1);
374 levShift = 0;
375 }
376 else
377 {
378 levShift = 1;
379 }
380
381 tmp0 = data[0] + data[2];
382 tmp1 = data[0] - data[2];
383 tmp2 = data[1] - data[3];
384 tmp3 = data[1] + data[3];
385 data[0] = ((tmp0 + tmp3) * levScale) >> levShift;
386 data[1] = ((tmp0 - tmp3) * levScale) >> levShift;
387 data[2] = ((tmp1 + tmp2) * levScale) >> levShift;
388 data[3] = ((tmp1 - tmp2) * levScale) >> levShift;
389 tmp0 = data[4] + data[6];
390 tmp1 = data[4] - data[6];
391 tmp2 = data[5] - data[7];
392 tmp3 = data[5] + data[7];
393 data[4] = ((tmp0 + tmp3) * levScale) >> levShift;
394 data[5] = ((tmp0 - tmp3) * levScale) >> levShift;
395 data[6] = ((tmp1 + tmp2) * levScale) >> levShift;
396 data[7] = ((tmp1 - tmp2) * levScale) >> levShift;
397
398 }
399
400 /*lint +e701 +e702 */
401
402
403