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