1 /******************************************************************************
2 *
3 * Copyright (C) 2022 The Android Open Source Project
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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /**
21 *******************************************************************************
22 * @file
23 * ih264_iquant_itrans_recon.c
24 *
25 * @brief
26 * Contains definition of functions for h264 inverse quantization inverse
27 *transformation and recon
28 *
29 * @author
30 * Ittiam
31 *
32 * @par List of Functions:
33 * - ih264_iquant_itrans_recon_4x4()
34 * - ih264_iquant_itrans_recon_8x8()
35 * - ih264_iquant_itrans_recon_4x4_dc()
36 * - ih264_iquant_itrans_recon_8x8_dc()
37 * - ih264_iquant_itrans_recon_chroma_4x4()
38 * -ih264_iquant_itrans_recon_chroma_4x4_dc()
39 *
40 * @remarks
41 *
42 *******************************************************************************
43 */
44
45 /*****************************************************************************/
46 /* File Includes */
47 /*****************************************************************************/
48 #include <stdint.h>
49
50 #include "ih264_typedefs.h"
51 #include "ih264_debug.h"
52 #include "ih264_defs.h"
53 #include "ih264_trans_macros.h"
54 #include "ih264_macros.h"
55 #include "ih264_platform_macros.h"
56 #include "ih264_trans_data.h"
57 #include "ih264_size_defs.h"
58 #include "ih264_structs.h"
59 #include "isvc_trans_quant_itrans_iquant.h"
60
61 /*
62 ********************************************************************************
63 *
64 * @brief This function reconstructs a 4x4 sub block from quantized resiude and
65 * prediction buffer
66 *
67 * @par Description:
68 * The quantized residue is first inverse quantized, then inverse transformed.
69 * This inverse transformed content is added to the prediction buffer to recon-
70 * struct the end output
71 *
72 * @param[in] pi2_src
73 * quantized 4x4 block
74 *
75 * @param[in] pu1_pred
76 * prediction 4x4 block
77 *
78 * @param[in] pi2_res
79 * residue 4x4 block
80 *
81 * @param[out] pu1_out
82 * reconstructed 4x4 block
83 *
84 * @param[in] src_strd
85 * quantization buffer stride
86 *
87 * @param[in] i4_pred_stride,
88 * Prediction buffer stride
89 *
90 * @param[in] i4_out_stride
91 * recon buffer Stride
92 *
93 * @param[in] i4_res_stride
94 * residue buffer Stride
95 *
96 * @param[in] pu2_scaling_list
97 * pointer to scaling list
98 *
99 * @param[in] pu2_norm_adjust
100 * pointer to inverse scale matrix
101 *
102 * @param[in] u4_qp_div_6
103 * Floor (qp/6)
104 *
105 * @param[in] pi2_tmp
106 * temporary buffer of size 1*16
107 *
108 * @returns none
109 *
110 * @remarks none
111 *
112 *******************************************************************************
113 */
isvc_iquant_itrans_recon_4x4(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)114 void isvc_iquant_itrans_recon_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
115 buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
116 buffer_container_t *ps_rec,
117 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
118 WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
119 UWORD8 u1_res_accumulate)
120 {
121 WORD16 x0, x1, x2, x3, i;
122 WORD32 q0, q1, q2, q3;
123 WORD16 i_macro;
124
125 WORD16 *pi2_src = ps_src->pv_data;
126 WORD16 *pi2_res = ps_res->pv_data;
127 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
128 UWORD8 *pu1_pred = ps_pred->pv_data;
129 UWORD8 *pu1_out = ps_rec->pv_data;
130 WORD32 i4_src_stride = ps_src->i4_data_stride;
131 WORD32 i4_res_stride = ps_res->i4_data_stride;
132 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
133 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
134 WORD32 i4_out_stride = ps_rec->i4_data_stride;
135 const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
136 const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
137 UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
138 WORD16 *pi2_src_ptr = pi2_src;
139 WORD16 *pi2_tmp_ptr = pi2_tmp;
140 UWORD8 *pu1_pred_ptr = pu1_pred;
141 WORD16 *pi2_res_ptr = pi2_res;
142 WORD16 *pi2_res_pred_ptr = pi2_res_pred;
143 UWORD8 *pu1_out_ptr = pu1_out;
144 WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
145
146 /* inverse quant */
147 /*horizontal inverse transform */
148 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
149 {
150 q0 = pi2_src_ptr[0];
151 INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
152 if(i == 0 && i4_iq_start_idx == 1) q0 = pi2_dc_src[0]; // Restoring dc value for intra case
153
154 q2 = pi2_src_ptr[2];
155 INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
156
157 x0 = q0 + q2;
158 x1 = q0 - q2;
159
160 q1 = pi2_src_ptr[1];
161 INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
162
163 q3 = pi2_src_ptr[3];
164 INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
165
166 x2 = (q1 >> 1) - q3;
167 x3 = q1 + (q3 >> 1);
168
169 pi2_tmp_ptr[0] = x0 + x3;
170 pi2_tmp_ptr[1] = x1 + x2;
171 pi2_tmp_ptr[2] = x1 - x2;
172 pi2_tmp_ptr[3] = x0 - x3;
173
174 pi2_src_ptr += i4_src_stride;
175 pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
176 pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
177 pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
178 }
179
180 /* vertical inverse transform */
181 pi2_tmp_ptr = pi2_tmp;
182 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
183 {
184 pu1_pred_ptr = pu1_pred;
185 pi2_res_ptr = pi2_res;
186 pi2_res_pred_ptr = pi2_res_pred;
187 pu1_out = pu1_out_ptr;
188
189 x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
190 x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
191 x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
192 x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
193
194 /* inverse prediction */
195 i_macro = x0 + x3;
196 i_macro = ((i_macro + 32) >> 6);
197 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
198 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
199 pu1_pred_ptr += i4_pred_stride;
200 pu1_out += i4_out_stride;
201 pi2_res_ptr += i4_res_stride;
202 pi2_res_pred_ptr += i4_res_pred_stride;
203
204 i_macro = x1 + x2;
205 i_macro = ((i_macro + 32) >> 6);
206 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
207 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
208 pu1_pred_ptr += i4_pred_stride;
209 pu1_out += i4_out_stride;
210 pi2_res_ptr += i4_res_stride;
211 pi2_res_pred_ptr += i4_res_pred_stride;
212
213 i_macro = x1 - x2;
214 i_macro = ((i_macro + 32) >> 6);
215 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
216 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
217 pu1_pred_ptr += i4_pred_stride;
218 pu1_out += i4_out_stride;
219 pi2_res_ptr += i4_res_stride;
220 pi2_res_pred_ptr += i4_res_pred_stride;
221
222 i_macro = x0 - x3;
223 i_macro = ((i_macro + 32) >> 6);
224 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
225 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
226
227 pi2_tmp_ptr++;
228 pu1_out_ptr++;
229 pu1_pred++;
230 pi2_res++;
231 pi2_res_pred++;
232 }
233 }
234
isvc_iquant_itrans_recon_4x4_dc(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)235 void isvc_iquant_itrans_recon_4x4_dc(buffer_container_t *ps_src, buffer_container_t *ps_pred,
236 buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
237 buffer_container_t *ps_rec,
238 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
239 WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
240 UWORD8 u1_res_accumulate)
241 {
242 WORD16 *pi2_src = ps_src->pv_data;
243 WORD16 *pi2_res = ps_res->pv_data;
244 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
245 UWORD8 *pu1_pred = ps_pred->pv_data;
246 UWORD8 *pu1_out = ps_rec->pv_data;
247 WORD32 i4_res_stride = ps_res->i4_data_stride;
248 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
249 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
250 WORD32 i4_out_stride = ps_rec->i4_data_stride;
251 const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
252 const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
253 UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
254 UWORD8 *pu1_pred_ptr = pu1_pred;
255 WORD16 *pi2_res_ptr = pi2_res;
256 WORD16 *pi2_res_pred_ptr = pi2_res_pred;
257 UWORD8 *pu1_out_ptr = pu1_out;
258 WORD32 q0;
259 WORD16 i_macro, i;
260 WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
261 UNUSED(pi2_tmp);
262
263 if(i4_iq_start_idx == 0)
264 {
265 q0 = pi2_src[0];
266 INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
267 }
268 else
269 {
270 q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
271 }
272 i_macro = ((q0 + 32) >> 6);
273 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
274 {
275 pu1_pred_ptr = pu1_pred;
276 pi2_res_ptr = pi2_res;
277 pi2_res_pred_ptr = pi2_res_pred;
278 pu1_out = pu1_out_ptr;
279
280 /* inverse prediction */
281 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
282 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
283 pu1_pred_ptr += i4_pred_stride;
284 pu1_out += i4_out_stride;
285 pi2_res_ptr += i4_res_stride;
286 pi2_res_pred_ptr += i4_res_pred_stride;
287
288 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
289 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
290 pu1_pred_ptr += i4_pred_stride;
291 pu1_out += i4_out_stride;
292 pi2_res_ptr += i4_res_stride;
293 pi2_res_pred_ptr += i4_res_pred_stride;
294
295 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
296 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
297 pu1_pred_ptr += i4_pred_stride;
298 pu1_out += i4_out_stride;
299 pi2_res_ptr += i4_res_stride;
300 pi2_res_pred_ptr += i4_res_pred_stride;
301
302 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
303 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
304
305 pu1_out_ptr++;
306 pu1_pred++;
307 pi2_res++;
308 pi2_res_pred++;
309 }
310 }
311
312 /**
313 *******************************************************************************
314 *
315 * @brief
316 * This function performs inverse quant and Inverse transform type Ci4 for 8x8
317 *block
318 *
319 * @par Description:
320 * Performs inverse transform Ci8 and adds the residue to get the
321 * reconstructed block
322 *
323 * @param[in] pi2_src
324 * Input 8x8coefficients
325 *
326 * @param[in] pu1_pred
327 * Prediction 8x8 block
328 *
329 * @param[out] pu1_recon
330 * Output 8x8 block
331 *
332 * @param[in] q_div
333 * QP/6
334 *
335 * @param[in] q_rem
336 * QP%6
337 *
338 * @param[in] q_lev
339 * Quantizer level
340 *
341 * @param[in] src_strd
342 * Input stride
343 *
344 * @param[in] i4_pred_stride,
345 * Prediction stride
346 *
347 * @param[in] i4_out_stride
348 * Output Stride
349 *
350 * @param[in] pi4_tmp
351 * temporary buffer of size 1*16 we dont need a bigger blcok since we reuse
352 * the tmp for each block
353 *
354 * @param[in] pu4_iquant_mat
355 * Pointer to the inverse quantization matrix
356 *
357 * @returns Void
358 *
359 * @remarks
360 * None
361 *
362 *******************************************************************************
363 */
isvc_iquant_itrans_recon_8x8(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)364 void isvc_iquant_itrans_recon_8x8(buffer_container_t *ps_src, buffer_container_t *ps_pred,
365 buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
366 buffer_container_t *ps_rec,
367 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
368 WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
369 UWORD8 u1_res_accumulate)
370 {
371 WORD32 i;
372 WORD16 i_z0, i_z1, i_z2, i_z3, i_z4, i_z5, i_z6, i_z7;
373 WORD16 i_y0, i_y1, i_y2, i_y3, i_y4, i_y5, i_y6, i_y7;
374 WORD16 i_macro;
375 WORD32 q;
376
377 WORD16 *pi2_src = ps_src->pv_data;
378 WORD16 *pi2_res = ps_res->pv_data;
379 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
380 UWORD8 *pu1_pred = ps_pred->pv_data;
381 UWORD8 *pu1_out = ps_rec->pv_data;
382 WORD32 i4_res_stride = ps_res->i4_data_stride;
383 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
384 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
385 WORD32 i4_out_stride = ps_rec->i4_data_stride;
386 const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
387 const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
388 UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
389 WORD16 *pi2_tmp_ptr = pi2_tmp;
390 UWORD8 *pu1_pred_ptr = pu1_pred;
391 WORD16 *pi2_res_ptr = pi2_res;
392 WORD16 *pi2_res_pred_ptr = pi2_res_pred;
393 UWORD8 *pu1_out_ptr = pu1_out;
394 WORD32 rnd_fact = (u4_qp_div_6 < 6) ? (1 << (5 - u4_qp_div_6)) : 0;
395 UNUSED(i4_iq_start_idx);
396 UNUSED(pi2_dc_src);
397
398 ASSERT(ps_src->i4_data_stride == SUB_BLK_WIDTH_8x8);
399
400 /*************************************************************/
401 /* De quantization of coefficients. Will be replaced by SIMD */
402 /* operations on platform. Note : DC coeff is not scaled */
403 /*************************************************************/
404 for(i = 0; i < (SUB_BLK_WIDTH_8x8 * SUB_BLK_WIDTH_8x8); i++)
405 {
406 q = pi2_src[i];
407 INV_QUANT(q, pu2_iscal_mat[i], pu2_weigh_mat[i], u4_qp_div_6, rnd_fact, 6);
408 pi2_tmp_ptr[i] = q;
409 }
410
411 /* Perform Inverse transform */
412 /*--------------------------------------------------------------------*/
413 /* IDCT [ Horizontal transformation ] */
414 /*--------------------------------------------------------------------*/
415 for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
416 {
417 /*------------------------------------------------------------------*/
418 /* y0 = w0 + w4 */
419 /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
420 /* y2 = w0 - w4 */
421 /* y3 = w1 + w7 - w3 - (w3 >> 1) */
422 /* y4 = (w2 >> 1) - w6 */
423 /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
424 /* y6 = w2 + (w6 >> 1) */
425 /* y7 = w3 + w5 + w1 + (w1 >> 1) */
426 /*------------------------------------------------------------------*/
427 i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4]);
428
429 i_y1 =
430 ((WORD32) (-pi2_tmp_ptr[3]) + pi2_tmp_ptr[5] - pi2_tmp_ptr[7] - (pi2_tmp_ptr[7] >> 1));
431
432 i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4]);
433
434 i_y3 = ((WORD32) pi2_tmp_ptr[1] + pi2_tmp_ptr[7] - pi2_tmp_ptr[3] - (pi2_tmp_ptr[3] >> 1));
435
436 i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6]);
437
438 i_y5 =
439 ((WORD32) (-pi2_tmp_ptr[1]) + pi2_tmp_ptr[7] + pi2_tmp_ptr[5] + (pi2_tmp_ptr[5] >> 1));
440
441 i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
442
443 i_y7 = ((WORD32) pi2_tmp_ptr[3] + pi2_tmp_ptr[5] + pi2_tmp_ptr[1] + (pi2_tmp_ptr[1] >> 1));
444
445 /*------------------------------------------------------------------*/
446 /* z0 = y0 + y6 */
447 /* z1 = y1 + (y7 >> 2) */
448 /* z2 = y2 + y4 */
449 /* z3 = y3 + (y5 >> 2) */
450 /* z4 = y2 - y4 */
451 /* z5 = (y3 >> 2) - y5 */
452 /* z6 = y0 - y6 */
453 /* z7 = y7 - (y1 >> 2) */
454 /*------------------------------------------------------------------*/
455 i_z0 = i_y0 + i_y6;
456 i_z1 = i_y1 + (i_y7 >> 2);
457 i_z2 = i_y2 + i_y4;
458 i_z3 = i_y3 + (i_y5 >> 2);
459 i_z4 = i_y2 - i_y4;
460 i_z5 = (i_y3 >> 2) - i_y5;
461 i_z6 = i_y0 - i_y6;
462 i_z7 = i_y7 - (i_y1 >> 2);
463
464 /*------------------------------------------------------------------*/
465 /* x0 = z0 + z7 */
466 /* x1 = z2 + z5 */
467 /* x2 = z4 + z3 */
468 /* x3 = z6 + z1 */
469 /* x4 = z6 - z1 */
470 /* x5 = z4 - z3 */
471 /* x6 = z2 - z5 */
472 /* x7 = z0 - z7 */
473 /*------------------------------------------------------------------*/
474 pi2_tmp_ptr[0] = i_z0 + i_z7;
475 pi2_tmp_ptr[1] = i_z2 + i_z5;
476 pi2_tmp_ptr[2] = i_z4 + i_z3;
477 pi2_tmp_ptr[3] = i_z6 + i_z1;
478 pi2_tmp_ptr[4] = i_z6 - i_z1;
479 pi2_tmp_ptr[5] = i_z4 - i_z3;
480 pi2_tmp_ptr[6] = i_z2 - i_z5;
481 pi2_tmp_ptr[7] = i_z0 - i_z7;
482
483 /* move to the next row */
484 // pi2_src_ptr += SUB_BLK_WIDTH_8x8;
485 pi2_tmp_ptr += SUB_BLK_WIDTH_8x8;
486 }
487 /*--------------------------------------------------------------------*/
488 /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
489 /* */
490 /* Add the prediction and store it back to reconstructed frame buffer */
491 /* [Prediction buffer itself in this case] */
492 /*--------------------------------------------------------------------*/
493
494 pi2_tmp_ptr = pi2_tmp;
495 for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
496 {
497 pu1_pred_ptr = pu1_pred;
498 pi2_res_ptr = pi2_res;
499 pi2_res_pred_ptr = pi2_res_pred;
500 pu1_out = pu1_out_ptr;
501 /*------------------------------------------------------------------*/
502 /* y0j = w0j + w4j */
503 /* y1j = -w3j + w5j -w7j -(w7j >> 1) */
504 /* y2j = w0j -w4j */
505 /* y3j = w1j + w7j -w3j -(w3j >> 1) */
506 /* y4j = ( w2j >> 1 ) -w6j */
507 /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
508 /* y6j = w2j + ( w6j >> 1 ) */
509 /* y7j = w3j + w5j + w1j + (w1j >> 1) */
510 /*------------------------------------------------------------------*/
511 i_y0 = pi2_tmp_ptr[0] + pi2_tmp_ptr[32];
512
513 i_y1 = (WORD32) (-pi2_tmp_ptr[24]) + pi2_tmp_ptr[40] - pi2_tmp_ptr[56] -
514 (pi2_tmp_ptr[56] >> 1);
515
516 i_y2 = pi2_tmp_ptr[0] - pi2_tmp_ptr[32];
517
518 i_y3 = (WORD32) pi2_tmp_ptr[8] + pi2_tmp_ptr[56] - pi2_tmp_ptr[24] - (pi2_tmp_ptr[24] >> 1);
519
520 i_y4 = (pi2_tmp_ptr[16] >> 1) - pi2_tmp_ptr[48];
521
522 i_y5 =
523 (WORD32) (-pi2_tmp_ptr[8]) + pi2_tmp_ptr[56] + pi2_tmp_ptr[40] + (pi2_tmp_ptr[40] >> 1);
524
525 i_y6 = pi2_tmp_ptr[16] + (pi2_tmp_ptr[48] >> 1);
526
527 i_y7 = (WORD32) pi2_tmp_ptr[24] + pi2_tmp_ptr[40] + pi2_tmp_ptr[8] + (pi2_tmp_ptr[8] >> 1);
528
529 /*------------------------------------------------------------------*/
530 /* z0j = y0j + y6j */
531 /* z1j = y1j + (y7j >> 2) */
532 /* z2j = y2j + y4j */
533 /* z3j = y3j + (y5j >> 2) */
534 /* z4j = y2j -y4j */
535 /* z5j = (y3j >> 2) -y5j */
536 /* z6j = y0j -y6j */
537 /* z7j = y7j -(y1j >> 2) */
538 /*------------------------------------------------------------------*/
539 i_z0 = i_y0 + i_y6;
540 i_z1 = i_y1 + (i_y7 >> 2);
541 i_z2 = i_y2 + i_y4;
542 i_z3 = i_y3 + (i_y5 >> 2);
543 i_z4 = i_y2 - i_y4;
544 i_z5 = (i_y3 >> 2) - i_y5;
545 i_z6 = i_y0 - i_y6;
546 i_z7 = i_y7 - (i_y1 >> 2);
547
548 /*------------------------------------------------------------------*/
549 /* x0j = z0j + z7j */
550 /* x1j = z2j + z5j */
551 /* x2j = z4j + z3j */
552 /* x3j = z6j + z1j */
553 /* x4j = z6j -z1j */
554 /* x5j = z4j -z3j */
555 /* x6j = z2j -z5j */
556 /* x7j = z0j -z7j */
557 /*------------------------------------------------------------------*/
558 i_macro = ((i_z0 + i_z7 + 32) >> 6);
559 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
560 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
561 /* Change uc_recBuffer to Point to next element in the same column*/
562 pu1_pred_ptr += i4_pred_stride;
563 pu1_out += i4_out_stride;
564 pi2_res_ptr += i4_res_stride;
565 pi2_res_pred_ptr += i4_res_pred_stride;
566
567 i_macro = ((i_z2 + i_z5 + 32) >> 6);
568 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
569 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
570 pu1_pred_ptr += i4_pred_stride;
571 pu1_out += i4_out_stride;
572 pi2_res_ptr += i4_res_stride;
573 pi2_res_pred_ptr += i4_res_pred_stride;
574
575 i_macro = ((i_z4 + i_z3 + 32) >> 6);
576 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
577 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
578 pu1_pred_ptr += i4_pred_stride;
579 pu1_out += i4_out_stride;
580 pi2_res_ptr += i4_res_stride;
581 pi2_res_pred_ptr += i4_res_pred_stride;
582
583 i_macro = ((i_z6 + i_z1 + 32) >> 6);
584 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
585 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
586 pu1_pred_ptr += i4_pred_stride;
587 pu1_out += i4_out_stride;
588 pi2_res_ptr += i4_res_stride;
589 pi2_res_pred_ptr += i4_res_pred_stride;
590
591 i_macro = ((i_z6 - i_z1 + 32) >> 6);
592 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
593 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
594 pu1_pred_ptr += i4_pred_stride;
595 pu1_out += i4_out_stride;
596 pi2_res_ptr += i4_res_stride;
597 pi2_res_pred_ptr += i4_res_pred_stride;
598
599 i_macro = ((i_z4 - i_z3 + 32) >> 6);
600 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
601 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
602 pu1_pred_ptr += i4_pred_stride;
603 pu1_out += i4_out_stride;
604 pi2_res_ptr += i4_res_stride;
605 pi2_res_pred_ptr += i4_res_pred_stride;
606
607 i_macro = ((i_z2 - i_z5 + 32) >> 6);
608 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
609 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
610 pu1_pred_ptr += i4_pred_stride;
611 pu1_out += i4_out_stride;
612 pi2_res_ptr += i4_res_stride;
613 pi2_res_pred_ptr += i4_res_pred_stride;
614
615 i_macro = ((i_z0 - i_z7 + 32) >> 6);
616 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
617 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
618
619 pi2_tmp_ptr++;
620 pu1_out_ptr++;
621 pu1_pred++;
622 pi2_res++;
623 pi2_res_pred++;
624 }
625 }
626
627 /*
628 ********************************************************************************
629 *
630 * @brief This function reconstructs a 4x4 sub block from quantized resiude and
631 * prediction buffer
632 *
633 * @par Description:
634 * The quantized residue is first inverse quantized, then inverse transformed.
635 * This inverse transformed content is added to the prediction buffer to recon-
636 * struct the end output
637 *
638 * @param[in] pi2_src
639 * quantized 4x4 block
640 *
641 * @param[in] pu1_pred
642 * prediction 4x4 block
643 *
644 * @param[out] pu1_out
645 * reconstructed 4x4 block
646 *
647 * @param[in] src_strd
648 * quantization buffer stride
649 *
650 * @param[in] i4_pred_stride,
651 * Prediction buffer stride
652 *
653 * @param[in] i4_out_stride
654 * recon buffer Stride
655 *
656 * @param[in] pu2_scaling_list
657 * pointer to scaling list
658 *
659 * @param[in] pu2_norm_adjust
660 * pointer to inverse scale matrix
661 *
662 * @param[in] u4_qp_div_6
663 * Floor (qp/6)
664 *
665 * @param[in] pi4_tmp
666 * temporary buffer of size 1*16
667 *
668 * @returns none
669 *
670 * @remarks none
671 *
672 *******************************************************************************
673 */
isvc_iquant_itrans_recon_chroma_4x4(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)674 void isvc_iquant_itrans_recon_chroma_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
675 buffer_container_t *ps_res_pred,
676 buffer_container_t *ps_res, buffer_container_t *ps_rec,
677 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
678 WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
679 WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
680 {
681 WORD16 x0, x1, x2, x3, i;
682 WORD32 q0, q1, q2, q3;
683 WORD16 i_macro;
684
685 WORD16 *pi2_src = ps_src->pv_data;
686 WORD16 *pi2_res = ps_res->pv_data;
687 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
688 UWORD8 *pu1_pred = ps_pred->pv_data;
689 UWORD8 *pu1_out = ps_rec->pv_data;
690 WORD32 i4_src_stride = ps_src->i4_data_stride;
691 WORD32 i4_res_stride = ps_res->i4_data_stride;
692 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
693 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
694 WORD32 i4_out_stride = ps_rec->i4_data_stride;
695 const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
696 const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
697 UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
698 WORD16 *pi2_src_ptr = pi2_src;
699 WORD16 *pi2_tmp_ptr = pi2_tmp;
700 UWORD8 *pu1_pred_ptr = pu1_pred;
701 WORD16 *pi2_res_ptr = pi2_res;
702 WORD16 *pi2_res_pred_ptr = pi2_res_pred;
703 UWORD8 *pu1_out_ptr = pu1_out;
704 WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
705
706 UNUSED(i4_iq_start_idx);
707
708 /* inverse quant */
709 /*horizontal inverse transform */
710 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
711 {
712 if(i == 0)
713 {
714 q0 = pi2_dc_src[0];
715 }
716 else
717 {
718 q0 = pi2_src_ptr[0];
719 INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
720 }
721
722 q2 = pi2_src_ptr[2];
723 INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
724
725 x0 = q0 + q2;
726 x1 = q0 - q2;
727
728 q1 = pi2_src_ptr[1];
729 INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
730
731 q3 = pi2_src_ptr[3];
732 INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
733
734 x2 = (q1 >> 1) - q3;
735 x3 = q1 + (q3 >> 1);
736
737 pi2_tmp_ptr[0] = x0 + x3;
738 pi2_tmp_ptr[1] = x1 + x2;
739 pi2_tmp_ptr[2] = x1 - x2;
740 pi2_tmp_ptr[3] = x0 - x3;
741
742 pi2_src_ptr += i4_src_stride;
743 pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
744 pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
745 pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
746 }
747
748 /* vertical inverse transform */
749 pi2_tmp_ptr = pi2_tmp;
750 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
751 {
752 pu1_pred_ptr = pu1_pred;
753 pi2_res_ptr = pi2_res;
754 pi2_res_pred_ptr = pi2_res_pred;
755 pu1_out = pu1_out_ptr;
756
757 x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
758 x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
759 x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
760 x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
761
762 /* inverse prediction */
763 i_macro = x0 + x3;
764 i_macro = ((i_macro + 32) >> 6);
765 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
766 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
767 pu1_pred_ptr += i4_pred_stride;
768 pu1_out += i4_out_stride;
769 pi2_res_ptr += i4_res_stride;
770 pi2_res_pred_ptr += i4_res_pred_stride;
771
772 i_macro = x1 + x2;
773 i_macro = ((i_macro + 32) >> 6);
774 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
775 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
776 pu1_pred_ptr += i4_pred_stride;
777 pu1_out += i4_out_stride;
778 pi2_res_ptr += i4_res_stride;
779 pi2_res_pred_ptr += i4_res_pred_stride;
780
781 i_macro = x1 - x2;
782 i_macro = ((i_macro + 32) >> 6);
783 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
784 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
785 pu1_pred_ptr += i4_pred_stride;
786 pu1_out += i4_out_stride;
787 pi2_res_ptr += i4_res_stride;
788 pi2_res_pred_ptr += i4_res_pred_stride;
789
790 i_macro = x0 - x3;
791 i_macro = ((i_macro + 32) >> 6);
792 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
793 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
794
795 pi2_tmp_ptr++;
796 pu1_out_ptr += 2; // Interleaved store for output
797 pu1_pred += 2; // Interleaved load for pred buffer
798 pi2_res += 2;
799 pi2_res_pred += 2;
800 }
801 }
802
803 /*
804 ********************************************************************************
805 *
806 * @brief This function reconstructs a 4x4 sub block from quantized resiude and
807 * prediction buffer if only dc value is present for residue
808 *
809 * @par Description:
810 * The quantized residue is first inverse quantized,
811 * This inverse quantized content is added to the prediction buffer to recon-
812 * struct the end output
813 *
814 * @param[in] pi2_src
815 * quantized dc coefficient
816 *
817 * @param[in] pu1_pred
818 * prediction 4x4 block in interleaved format
819 *
820 * @param[in] i4_pred_stride,
821 * Prediction buffer stride in interleaved format
822 *
823 * @param[in] i4_out_stride
824 * recon buffer Stride
825 *
826 * @returns none
827 *
828 * @remarks none
829 *
830 *******************************************************************************
831 */
832
isvc_iquant_itrans_recon_chroma_4x4_dc(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)833 void isvc_iquant_itrans_recon_chroma_4x4_dc(buffer_container_t *ps_src, buffer_container_t *ps_pred,
834 buffer_container_t *ps_res_pred,
835 buffer_container_t *ps_res, buffer_container_t *ps_rec,
836 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
837 WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
838 WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
839 {
840 WORD32 q0;
841 WORD16 i_macro, i;
842
843 WORD16 *pi2_src = ps_src->pv_data;
844 WORD16 *pi2_res = ps_res->pv_data;
845 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
846 UWORD8 *pu1_pred = ps_pred->pv_data;
847 UWORD8 *pu1_out = ps_rec->pv_data;
848 WORD32 i4_res_stride = ps_res->i4_data_stride;
849 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
850 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
851 WORD32 i4_out_stride = ps_rec->i4_data_stride;
852 const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
853 const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
854 UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
855 UWORD8 *pu1_pred_ptr = pu1_pred;
856 WORD16 *pi2_res_ptr = pi2_res;
857 WORD16 *pi2_res_pred_ptr = pi2_res_pred;
858 UWORD8 *pu1_out_ptr = pu1_out;
859
860 UNUSED(pi2_src);
861 UNUSED(pu2_iscal_mat);
862 UNUSED(pu2_weigh_mat);
863 UNUSED(u4_qp_div_6);
864 UNUSED(pi2_tmp);
865 UNUSED(i4_iq_start_idx);
866
867 q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
868 i_macro = ((q0 + 32) >> 6);
869
870 for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
871 {
872 pu1_pred_ptr = pu1_pred;
873 pi2_res_ptr = pi2_res;
874 pi2_res_pred_ptr = pi2_res_pred;
875 pu1_out = pu1_out_ptr;
876
877 /* inverse prediction */
878 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
879 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
880 pu1_pred_ptr += i4_pred_stride;
881 pu1_out += i4_out_stride;
882 pi2_res_ptr += i4_res_stride;
883 pi2_res_pred_ptr += i4_res_pred_stride;
884
885 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
886 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
887 pu1_pred_ptr += i4_pred_stride;
888 pu1_out += i4_out_stride;
889 pi2_res_ptr += i4_res_stride;
890 pi2_res_pred_ptr += i4_res_pred_stride;
891
892 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
893 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
894 pu1_pred_ptr += i4_pred_stride;
895 pu1_out += i4_out_stride;
896 pi2_res_ptr += i4_res_stride;
897 pi2_res_pred_ptr += i4_res_pred_stride;
898
899 pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
900 *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
901
902 pu1_out_ptr += 2;
903 pu1_pred += 2;
904 pi2_res += 2;
905 pi2_res_pred += 2;
906 }
907 }
908
909 /*
910 ********************************************************************************
911 *
912 * @brief This function reconstructs a 4x4 sub block from quantized residue and
913 * prediction buffer assuming cbf=0
914 *
915 * @param[in] ps_src
916 * quantized 4x4 block
917 *
918 * @param[in] ps_pred
919 * prediction 4x4 block
920 *
921 * @param[in] ps_res
922 * residue 4x4 block
923 *
924 * @param[in] ps_res_pred
925 * residual pred 4x4 block
926 *
927 * @param[out] ps_out
928 * reconstructed 4x4 block
929 *
930 * @param[out] ps_iq_it_res_rec_constants
931 * reconstructed 4x4 block
932 *
933 * @param[out] pi2_tmp
934 * scratch buf
935 *
936 * @param[out] pi2_dc_src
937 * Pointer to dc coeff location
938 *
939 * @param[out] i4_iq_start_idx
940 * Idx of first coeff
941 *
942 * @param[in] pi2_tmp
943 * temporary buffer of size 1*16
944 *
945 * @param[in] u1_res_accumulate
946 * Flag to control residual accumulation
947 *
948 * @returns none
949 *
950 *******************************************************************************
951 */
isvc_zcbf_iquant_itrans_recon_4x4(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)952 void isvc_zcbf_iquant_itrans_recon_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
953 buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
954 buffer_container_t *ps_rec,
955 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
956 WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
957 UWORD8 u1_res_accumulate)
958 {
959 WORD32 i, j;
960
961 UWORD8 *pu1_out = ps_rec->pv_data;
962 WORD16 *pi2_res = ps_res->pv_data;
963 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
964 UWORD8 *pu1_pred = ps_pred->pv_data;
965 WORD32 i4_out_stride = ps_rec->i4_data_stride;
966 WORD32 i4_res_stride = ps_res->i4_data_stride;
967 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
968 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
969
970 UNUSED(ps_src);
971 UNUSED(ps_iq_it_res_rec_constants);
972 UNUSED(pi2_tmp);
973 UNUSED(pi2_dc_src);
974 UNUSED(i4_iq_start_idx);
975
976 if(u1_res_accumulate)
977 {
978 for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
979 {
980 for(j = 0; j < SUB_BLK_WIDTH_4x4; j++)
981 {
982 pi2_res[j + i * i4_res_stride] = isvc_get_residue(
983 0, pi2_res_pred[j + i * i4_res_pred_stride], u1_res_accumulate);
984 pu1_out[j + i * i4_out_stride] =
985 CLIP3(0, UINT8_MAX,
986 pu1_pred[j + i * i4_pred_stride] + pi2_res[j + i * i4_res_stride]);
987 }
988 }
989 }
990 else
991 {
992 for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
993 {
994 for(j = 0; j < SUB_BLK_WIDTH_4x4; j++)
995 {
996 pi2_res[j + i * i4_res_stride] = 0;
997 pu1_out[j + i * i4_out_stride] = pu1_pred[j + i * i4_pred_stride];
998 }
999 }
1000 }
1001 }
1002
1003 /*
1004 ********************************************************************************
1005 *
1006 * @brief This function reconstructs a 4x4 sub block from quantized residue and
1007 * prediction buffer assuming cbf=0
1008 *
1009 * @param[in] ps_src
1010 * quantized 4x4 block
1011 *
1012 * @param[in] ps_pred
1013 * prediction 4x4 block
1014 *
1015 * @param[in] ps_res
1016 * residue 4x4 block
1017 *
1018 * @param[in] ps_res_pred
1019 * residual pred 4x4 block
1020 *
1021 * @param[out] ps_out
1022 * reconstructed 4x4 block
1023 *
1024 * @param[out] ps_iq_it_res_rec_constants
1025 * reconstructed 4x4 block
1026 *
1027 * @param[out] pi2_tmp
1028 * scratch buf
1029 *
1030 * @param[out] pi2_dc_src
1031 * Pointer to dc coeff location
1032 *
1033 * @param[out] i4_iq_start_idx
1034 * Idx of first coeff
1035 *
1036 * @param[in] pi2_tmp
1037 * temporary buffer of size 1*16
1038 *
1039 * @param[in] u1_res_accumulate
1040 * Flag to control residual accumulation
1041 *
1042 * @returns none
1043 *
1044 *******************************************************************************
1045 */
isvc_chroma_zcbf_iquant_itrans_recon_4x4(buffer_container_t * ps_src,buffer_container_t * ps_pred,buffer_container_t * ps_res_pred,buffer_container_t * ps_res,buffer_container_t * ps_rec,iq_it_res_rec_constants_t * ps_iq_it_res_rec_constants,WORD16 * pi2_tmp,WORD16 * pi2_dc_src,WORD32 i4_iq_start_idx,UWORD8 u1_res_accumulate)1046 void isvc_chroma_zcbf_iquant_itrans_recon_4x4(
1047 buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
1048 buffer_container_t *ps_res, buffer_container_t *ps_rec,
1049 iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
1050 WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
1051 {
1052 WORD32 i, j;
1053
1054 UWORD8 *pu1_out = ps_rec->pv_data;
1055 WORD32 i4_out_stride = ps_rec->i4_data_stride;
1056 WORD16 *pi2_res = ps_res->pv_data;
1057 WORD16 *pi2_res_pred = ps_res_pred->pv_data;
1058 UWORD8 *pu1_pred = ps_pred->pv_data;
1059 WORD32 i4_res_stride = ps_res->i4_data_stride;
1060 WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
1061 WORD32 i4_pred_stride = ps_pred->i4_data_stride;
1062
1063 UNUSED(ps_src);
1064 UNUSED(ps_iq_it_res_rec_constants);
1065 UNUSED(pi2_tmp);
1066 UNUSED(pi2_dc_src);
1067 UNUSED(i4_iq_start_idx);
1068
1069 if(u1_res_accumulate)
1070 {
1071 for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
1072 {
1073 for(j = 0; j < SUB_BLK_WIDTH_4x4 * 2; j += 2)
1074 {
1075 pi2_res[j + i * i4_res_stride] = isvc_get_residue(
1076 0, pi2_res_pred[j + i * i4_res_pred_stride], u1_res_accumulate);
1077 pu1_out[j + i * i4_out_stride] = CLIP3(
1078 0, UINT8_MAX,
1079 ((WORD16) pu1_pred[j + i * i4_pred_stride]) + pi2_res[j + i * i4_res_stride]);
1080 }
1081 }
1082 }
1083 else
1084 {
1085 for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
1086 {
1087 for(j = 0; j < SUB_BLK_WIDTH_4x4 * 2; j += 2)
1088 {
1089 pi2_res[j + i * i4_res_stride] = 0;
1090 pu1_out[j + i * i4_out_stride] = pu1_pred[j + i * i4_pred_stride];
1091 }
1092 }
1093 }
1094 }
1095