/src/libhevc/common/ihevc_itrans_recon_8x8.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ******************************************************************************/ |
18 | | /** |
19 | | ******************************************************************************* |
20 | | * @file |
21 | | * ihevc_itrans_recon_8x8.c |
22 | | * |
23 | | * @brief |
24 | | * Contains function definitions for inverse transform and reconstruction 8x8 |
25 | | * |
26 | | * |
27 | | * @author |
28 | | * 100470 |
29 | | * |
30 | | * @par List of Functions: |
31 | | * - ihevc_itrans_recon_8x8() |
32 | | * |
33 | | * @remarks |
34 | | * None |
35 | | * |
36 | | ******************************************************************************* |
37 | | */ |
38 | | #include <stdio.h> |
39 | | #include <string.h> |
40 | | #include "ihevc_typedefs.h" |
41 | | #include "ihevc_macros.h" |
42 | | #include "ihevc_platform_macros.h" |
43 | | #include "ihevc_defs.h" |
44 | | #include "ihevc_trans_tables.h" |
45 | | #include "ihevc_itrans_recon.h" |
46 | | #include "ihevc_trans_macros.h" |
47 | | |
48 | | /** |
49 | | ******************************************************************************* |
50 | | * |
51 | | * @brief |
52 | | * This function performs Inverse transform and reconstruction for 8x8 |
53 | | * input block |
54 | | * |
55 | | * @par Description: |
56 | | * Performs inverse transform and adds the prediction data and clips output |
57 | | * to 8 bit |
58 | | * |
59 | | * @param[in] pi2_src |
60 | | * Input 8x8 coefficients |
61 | | * |
62 | | * @param[in] pi2_tmp |
63 | | * Temporary 8x8 buffer for storing inverse |
64 | | * |
65 | | * transform |
66 | | * 1st stage output |
67 | | * |
68 | | * @param[in] pu1_pred |
69 | | * Prediction 8x8 block |
70 | | * |
71 | | * @param[out] pu1_dst |
72 | | * Output 8x8 block |
73 | | * |
74 | | * @param[in] src_strd |
75 | | * Input stride |
76 | | * |
77 | | * @param[in] pred_strd |
78 | | * Prediction stride |
79 | | * |
80 | | * @param[in] dst_strd |
81 | | * Output Stride |
82 | | * |
83 | | * @param[in] shift |
84 | | * Output shift |
85 | | * |
86 | | * @param[in] zero_cols |
87 | | * Zero columns in pi2_src |
88 | | * |
89 | | * @returns Void |
90 | | * |
91 | | * @remarks |
92 | | * None |
93 | | * |
94 | | ******************************************************************************* |
95 | | */ |
96 | | |
97 | | void ihevc_itrans_recon_8x8(WORD16 *pi2_src, |
98 | | WORD16 *pi2_tmp, |
99 | | UWORD8 *pu1_pred, |
100 | | UWORD8 *pu1_dst, |
101 | | WORD32 src_strd, |
102 | | WORD32 pred_strd, |
103 | | WORD32 dst_strd, |
104 | | WORD32 zero_cols, |
105 | | WORD32 zero_rows) |
106 | 202k | { |
107 | 202k | WORD32 j, k; |
108 | 202k | WORD32 e[4], o[4]; |
109 | 202k | WORD32 ee[2], eo[2]; |
110 | 202k | WORD32 add; |
111 | 202k | WORD32 shift; |
112 | 202k | WORD16 *pi2_tmp_orig; |
113 | 202k | WORD32 trans_size; |
114 | 202k | WORD32 zero_rows_2nd_stage = zero_cols; |
115 | 202k | WORD32 row_limit_2nd_stage; |
116 | | |
117 | 202k | trans_size = TRANS_SIZE_8; |
118 | | |
119 | 202k | pi2_tmp_orig = pi2_tmp; |
120 | | |
121 | 202k | if((zero_cols & 0xF0) == 0xF0) |
122 | 33.2k | row_limit_2nd_stage = 4; |
123 | 168k | else |
124 | 168k | row_limit_2nd_stage = TRANS_SIZE_8; |
125 | | |
126 | | |
127 | 202k | if((zero_rows & 0xF0) == 0xF0) /* First 4 rows of input are non-zero */ |
128 | 19.0k | { |
129 | | /************************************************************************************************/ |
130 | | /**********************************START - IT_RECON_8x8******************************************/ |
131 | | /************************************************************************************************/ |
132 | | |
133 | | /* Inverse Transform 1st stage */ |
134 | 19.0k | shift = IT_SHIFT_STAGE_1; |
135 | 19.0k | add = 1 << (shift - 1); |
136 | | |
137 | 130k | for(j = 0; j < row_limit_2nd_stage; j++) |
138 | 111k | { |
139 | | /* Checking for Zero Cols */ |
140 | 111k | if((zero_cols & 1) == 1) |
141 | 788 | { |
142 | 788 | memset(pi2_tmp, 0, trans_size * sizeof(WORD16)); |
143 | 788 | } |
144 | 111k | else |
145 | 111k | { |
146 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
147 | 555k | for(k = 0; k < 4; k++) |
148 | 444k | { |
149 | 444k | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_src[src_strd] |
150 | 444k | + g_ai2_ihevc_trans_8[3][k] |
151 | 444k | * pi2_src[3 * src_strd]; |
152 | 444k | } |
153 | 111k | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_src[2 * src_strd]; |
154 | 111k | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_src[2 * src_strd]; |
155 | 111k | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_src[0]; |
156 | 111k | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_src[0]; |
157 | | |
158 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
159 | 111k | e[0] = ee[0] + eo[0]; |
160 | 111k | e[3] = ee[0] - eo[0]; |
161 | 111k | e[1] = ee[1] + eo[1]; |
162 | 111k | e[2] = ee[1] - eo[1]; |
163 | 555k | for(k = 0; k < 4; k++) |
164 | 444k | { |
165 | 444k | pi2_tmp[k] = |
166 | 444k | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
167 | 444k | pi2_tmp[k + 4] = |
168 | 444k | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
169 | 444k | } |
170 | 111k | } |
171 | 111k | pi2_src++; |
172 | 111k | pi2_tmp += trans_size; |
173 | 111k | zero_cols = zero_cols >> 1; |
174 | 111k | } |
175 | | |
176 | 19.0k | pi2_tmp = pi2_tmp_orig; |
177 | | |
178 | | /* Inverse Transform 2nd stage */ |
179 | 19.0k | shift = IT_SHIFT_STAGE_2; |
180 | 19.0k | add = 1 << (shift - 1); |
181 | 19.0k | if((zero_rows_2nd_stage & 0xF0) == 0xF0) /* First 4 rows of output of 1st stage are non-zero */ |
182 | 10.1k | { |
183 | 91.6k | for(j = 0; j < trans_size; j++) |
184 | 81.5k | { |
185 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
186 | 407k | for(k = 0; k < 4; k++) |
187 | 326k | { |
188 | 326k | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size] |
189 | 326k | + g_ai2_ihevc_trans_8[3][k] * pi2_tmp[3 * trans_size]; |
190 | 326k | } |
191 | 81.5k | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size]; |
192 | 81.5k | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size]; |
193 | 81.5k | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0]; |
194 | 81.5k | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0]; |
195 | | |
196 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
197 | 81.5k | e[0] = ee[0] + eo[0]; |
198 | 81.5k | e[3] = ee[0] - eo[0]; |
199 | 81.5k | e[1] = ee[1] + eo[1]; |
200 | 81.5k | e[2] = ee[1] - eo[1]; |
201 | 407k | for(k = 0; k < 4; k++) |
202 | 326k | { |
203 | 326k | WORD32 itrans_out; |
204 | 326k | itrans_out = |
205 | 326k | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
206 | 326k | pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k])); |
207 | 326k | itrans_out = |
208 | 326k | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
209 | 326k | pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4])); |
210 | 326k | } |
211 | 81.5k | pi2_tmp++; |
212 | 81.5k | pu1_pred += pred_strd; |
213 | 81.5k | pu1_dst += dst_strd; |
214 | 81.5k | } |
215 | 10.1k | } |
216 | 8.88k | else /* All rows of output of 1st stage are non-zero */ |
217 | 8.88k | { |
218 | 79.9k | for(j = 0; j < trans_size; j++) |
219 | 71.0k | { |
220 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
221 | 355k | for(k = 0; k < 4; k++) |
222 | 284k | { |
223 | 284k | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size] |
224 | 284k | + g_ai2_ihevc_trans_8[3][k] |
225 | 284k | * pi2_tmp[3 * trans_size] |
226 | 284k | + g_ai2_ihevc_trans_8[5][k] |
227 | 284k | * pi2_tmp[5 * trans_size] |
228 | 284k | + g_ai2_ihevc_trans_8[7][k] |
229 | 284k | * pi2_tmp[7 * trans_size]; |
230 | 284k | } |
231 | | |
232 | 71.0k | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size] |
233 | 71.0k | + g_ai2_ihevc_trans_8[6][0] * pi2_tmp[6 * trans_size]; |
234 | 71.0k | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size] |
235 | 71.0k | + g_ai2_ihevc_trans_8[6][1] * pi2_tmp[6 * trans_size]; |
236 | 71.0k | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0] |
237 | 71.0k | + g_ai2_ihevc_trans_8[4][0] * pi2_tmp[4 * trans_size]; |
238 | 71.0k | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0] |
239 | 71.0k | + g_ai2_ihevc_trans_8[4][1] * pi2_tmp[4 * trans_size]; |
240 | | |
241 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
242 | 71.0k | e[0] = ee[0] + eo[0]; |
243 | 71.0k | e[3] = ee[0] - eo[0]; |
244 | 71.0k | e[1] = ee[1] + eo[1]; |
245 | 71.0k | e[2] = ee[1] - eo[1]; |
246 | 355k | for(k = 0; k < 4; k++) |
247 | 284k | { |
248 | 284k | WORD32 itrans_out; |
249 | 284k | itrans_out = |
250 | 284k | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
251 | 284k | pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k])); |
252 | 284k | itrans_out = |
253 | 284k | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
254 | 284k | pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4])); |
255 | 284k | } |
256 | 71.0k | pi2_tmp++; |
257 | 71.0k | pu1_pred += pred_strd; |
258 | 71.0k | pu1_dst += dst_strd; |
259 | 71.0k | } |
260 | 8.88k | } |
261 | | /************************************************************************************************/ |
262 | | /************************************END - IT_RECON_8x8******************************************/ |
263 | | /************************************************************************************************/ |
264 | 19.0k | } |
265 | 183k | else /* All rows of input are non-zero */ |
266 | 183k | { |
267 | | /************************************************************************************************/ |
268 | | /**********************************START - IT_RECON_8x8******************************************/ |
269 | | /************************************************************************************************/ |
270 | | |
271 | | /* Inverse Transform 1st stage */ |
272 | 183k | shift = IT_SHIFT_STAGE_1; |
273 | 183k | add = 1 << (shift - 1); |
274 | | |
275 | 1.55M | for(j = 0; j < row_limit_2nd_stage; j++) |
276 | 1.37M | { |
277 | | /* Checking for Zero Cols */ |
278 | 1.37M | if((zero_cols & 1) == 1) |
279 | 920 | { |
280 | 920 | memset(pi2_tmp, 0, trans_size * sizeof(WORD16)); |
281 | 920 | } |
282 | 1.37M | else |
283 | 1.37M | { |
284 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
285 | 6.86M | for(k = 0; k < 4; k++) |
286 | 5.48M | { |
287 | 5.48M | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_src[src_strd] |
288 | 5.48M | + g_ai2_ihevc_trans_8[3][k] |
289 | 5.48M | * pi2_src[3 * src_strd] |
290 | 5.48M | + g_ai2_ihevc_trans_8[5][k] |
291 | 5.48M | * pi2_src[5 * src_strd] |
292 | 5.48M | + g_ai2_ihevc_trans_8[7][k] |
293 | 5.48M | * pi2_src[7 * src_strd]; |
294 | 5.48M | } |
295 | | |
296 | 1.37M | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_src[2 * src_strd] |
297 | 1.37M | + g_ai2_ihevc_trans_8[6][0] * pi2_src[6 * src_strd]; |
298 | 1.37M | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_src[2 * src_strd] |
299 | 1.37M | + g_ai2_ihevc_trans_8[6][1] * pi2_src[6 * src_strd]; |
300 | 1.37M | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_src[0] |
301 | 1.37M | + g_ai2_ihevc_trans_8[4][0] * pi2_src[4 * src_strd]; |
302 | 1.37M | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_src[0] |
303 | 1.37M | + g_ai2_ihevc_trans_8[4][1] * pi2_src[4 * src_strd]; |
304 | | |
305 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
306 | 1.37M | e[0] = ee[0] + eo[0]; |
307 | 1.37M | e[3] = ee[0] - eo[0]; |
308 | 1.37M | e[1] = ee[1] + eo[1]; |
309 | 1.37M | e[2] = ee[1] - eo[1]; |
310 | 6.86M | for(k = 0; k < 4; k++) |
311 | 5.48M | { |
312 | 5.48M | pi2_tmp[k] = |
313 | 5.48M | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
314 | 5.48M | pi2_tmp[k + 4] = |
315 | 5.48M | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
316 | 5.48M | } |
317 | 1.37M | } |
318 | 1.37M | pi2_src++; |
319 | 1.37M | pi2_tmp += trans_size; |
320 | 1.37M | zero_cols = zero_cols >> 1; |
321 | 1.37M | } |
322 | | |
323 | 183k | pi2_tmp = pi2_tmp_orig; |
324 | | |
325 | | /* Inverse Transform 2nd stage */ |
326 | 183k | shift = IT_SHIFT_STAGE_2; |
327 | 183k | add = 1 << (shift - 1); |
328 | 183k | if((zero_rows_2nd_stage & 0xF0) == 0xF0) /* First 4 rows of output of 1st stage are non-zero */ |
329 | 23.0k | { |
330 | 207k | for(j = 0; j < trans_size; j++) |
331 | 184k | { |
332 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
333 | 923k | for(k = 0; k < 4; k++) |
334 | 738k | { |
335 | 738k | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size] |
336 | 738k | + g_ai2_ihevc_trans_8[3][k] * pi2_tmp[3 * trans_size]; |
337 | 738k | } |
338 | 184k | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size]; |
339 | 184k | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size]; |
340 | 184k | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0]; |
341 | 184k | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0]; |
342 | | |
343 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
344 | 184k | e[0] = ee[0] + eo[0]; |
345 | 184k | e[3] = ee[0] - eo[0]; |
346 | 184k | e[1] = ee[1] + eo[1]; |
347 | 184k | e[2] = ee[1] - eo[1]; |
348 | 923k | for(k = 0; k < 4; k++) |
349 | 738k | { |
350 | 738k | WORD32 itrans_out; |
351 | 738k | itrans_out = |
352 | 738k | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
353 | 738k | pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k])); |
354 | 738k | itrans_out = |
355 | 738k | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
356 | 738k | pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4])); |
357 | 738k | } |
358 | 184k | pi2_tmp++; |
359 | 184k | pu1_pred += pred_strd; |
360 | 184k | pu1_dst += dst_strd; |
361 | 184k | } |
362 | 23.0k | } |
363 | 160k | else /* All rows of output of 1st stage are non-zero */ |
364 | 160k | { |
365 | 1.44M | for(j = 0; j < trans_size; j++) |
366 | 1.28M | { |
367 | | /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */ |
368 | 6.40M | for(k = 0; k < 4; k++) |
369 | 5.12M | { |
370 | 5.12M | o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size] |
371 | 5.12M | + g_ai2_ihevc_trans_8[3][k] |
372 | 5.12M | * pi2_tmp[3 * trans_size] |
373 | 5.12M | + g_ai2_ihevc_trans_8[5][k] |
374 | 5.12M | * pi2_tmp[5 * trans_size] |
375 | 5.12M | + g_ai2_ihevc_trans_8[7][k] |
376 | 5.12M | * pi2_tmp[7 * trans_size]; |
377 | 5.12M | } |
378 | | |
379 | 1.28M | eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size] |
380 | 1.28M | + g_ai2_ihevc_trans_8[6][0] * pi2_tmp[6 * trans_size]; |
381 | 1.28M | eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size] |
382 | 1.28M | + g_ai2_ihevc_trans_8[6][1] * pi2_tmp[6 * trans_size]; |
383 | 1.28M | ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0] |
384 | 1.28M | + g_ai2_ihevc_trans_8[4][0] * pi2_tmp[4 * trans_size]; |
385 | 1.28M | ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0] |
386 | 1.28M | + g_ai2_ihevc_trans_8[4][1] * pi2_tmp[4 * trans_size]; |
387 | | |
388 | | /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */ |
389 | 1.28M | e[0] = ee[0] + eo[0]; |
390 | 1.28M | e[3] = ee[0] - eo[0]; |
391 | 1.28M | e[1] = ee[1] + eo[1]; |
392 | 1.28M | e[2] = ee[1] - eo[1]; |
393 | 6.40M | for(k = 0; k < 4; k++) |
394 | 5.12M | { |
395 | 5.12M | WORD32 itrans_out; |
396 | 5.12M | itrans_out = |
397 | 5.12M | CLIP_S16(((e[k] + o[k] + add) >> shift)); |
398 | 5.12M | pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k])); |
399 | 5.12M | itrans_out = |
400 | 5.12M | CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift)); |
401 | 5.12M | pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4])); |
402 | 5.12M | } |
403 | 1.28M | pi2_tmp++; |
404 | 1.28M | pu1_pred += pred_strd; |
405 | 1.28M | pu1_dst += dst_strd; |
406 | 1.28M | } |
407 | 160k | } |
408 | | /************************************************************************************************/ |
409 | | /************************************END - IT_RECON_8x8******************************************/ |
410 | | /************************************************************************************************/ |
411 | 183k | } |
412 | 202k | } |
413 | | |