xref: /aosp_15_r20/external/libavc/common/ih264_ihadamard_scaling.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2015 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 *******************************************************************************
23 * @file
24 *  ih264_ihadamard_scaling.c
25 *
26 * @brief
27 *  Contains definition of functions for h264 inverse hadamard 4x4 transform and
28 *  scaling
29 *
30 * @author
31 *  ittiam
32 *
33 * @par List of Functions:
34 *  - ih264_ihadamard_scaling_4x4
35 *  - ih264_ihadamard_scaling_2x2_uv
36 *
37 * @remarks
38 *  none
39 *
40 *******************************************************************************
41 */
42 
43 /*****************************************************************************/
44 /* File Includes                                                             */
45 /*****************************************************************************/
46 
47 /* User Include Files */
48 #include "ih264_typedefs.h"
49 #include "ih264_macros.h"
50 #include "ih264_defs.h"
51 #include "ih264_trans_macros.h"
52 #include "ih264_trans_data.h"
53 #include "ih264_size_defs.h"
54 #include "ih264_structs.h"
55 #include "ih264_trans_quant_itrans_iquant.h"
56 
57 
58 /*****************************************************************************/
59 /* Function Definitions                                                      */
60 /*****************************************************************************/
61 
62 /**
63 ********************************************************************************
64 *
65 * @brief This function performs a 4x4 inverse hadamard transform on the luma
66 * DC coefficients and then performs scaling.
67 *
68 * @par Description:
69 *  The DC coefficients pass through a 2-stage inverse hadamard transform.
70 *  This inverse transformed content is scaled to based on Qp value.
71 *
72 * @param[in] pi2_src
73 *  input 4x4 block of DC coefficients
74 *
75 * @param[out] pi2_out
76 *  output 4x4 block
77 *
78 * @param[in] pu2_iscal_mat
79 *  pointer to scaling list
80 *
81 * @param[in] pu2_weigh_mat
82 *  pointer to weight matrix
83 *
84 * @param[in] u4_qp_div_6
85 *  Floor (qp/6)
86 *
87 * @param[in] pi4_tmp
88 *  temporary buffer of size 1*16
89 *
90 * @returns none
91 *
92 * @remarks none
93 *
94 *******************************************************************************
95 */
ih264_ihadamard_scaling_4x4(WORD16 * pi2_src,WORD16 * pi2_out,const UWORD16 * pu2_iscal_mat,const UWORD16 * pu2_weigh_mat,UWORD32 u4_qp_div_6,WORD32 * pi4_tmp)96 void ih264_ihadamard_scaling_4x4(WORD16* pi2_src,
97                                  WORD16* pi2_out,
98                                  const UWORD16 *pu2_iscal_mat,
99                                  const UWORD16 *pu2_weigh_mat,
100                                  UWORD32 u4_qp_div_6,
101                                  WORD32* pi4_tmp)
102 {
103     WORD32 i;
104     WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
105     WORD16 *pi2_src_ptr, *pi2_out_ptr;
106     WORD32 *pi4_tmp_ptr;
107     WORD32 rnd_fact = (u4_qp_div_6 < 6) ? (1 << (5 - u4_qp_div_6)) : 0;
108 
109     pi4_tmp_ptr = pi4_tmp;
110     pi2_src_ptr = pi2_src;
111     pi2_out_ptr = pi2_out;
112 
113     /* horizontal transform */
114     for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
115     {
116         x4 = pi2_src_ptr[0];
117         x5 = pi2_src_ptr[1];
118         x6 = pi2_src_ptr[2];
119         x7 = pi2_src_ptr[3];
120 
121         x0 = x4 + x7;
122         x1 = x5 + x6;
123         x2 = x5 - x6;
124         x3 = x4 - x7;
125 
126         pi4_tmp_ptr[0] = x0 + x1;
127         pi4_tmp_ptr[1] = x2 + x3;
128         pi4_tmp_ptr[2] = x0 - x1;
129         pi4_tmp_ptr[3] = x3 - x2;
130 
131         pi4_tmp_ptr += SUB_BLK_WIDTH_4x4;
132         pi2_src_ptr += SUB_BLK_WIDTH_4x4;
133     }
134 
135     /* vertical transform */
136     pi4_tmp_ptr = pi4_tmp;
137     for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
138     {
139         x4 = pi4_tmp_ptr[0];
140         x5 = pi4_tmp_ptr[4];
141         x6 = pi4_tmp_ptr[8];
142         x7 = pi4_tmp_ptr[12];
143 
144         x0 = x4 + x7;
145         x1 = x5 + x6;
146         x2 = x5 - x6;
147         x3 = x4 - x7;
148 
149         pi4_tmp_ptr[0] = x0 + x1;
150         pi4_tmp_ptr[4] = x2 + x3;
151         pi4_tmp_ptr[8] = x0 - x1;
152         pi4_tmp_ptr[12] = x3 - x2;
153 
154         pi4_tmp_ptr++;
155     }
156     pi4_tmp_ptr = pi4_tmp;
157 
158     /* scaling */
159     for(i = 0; i < (SUB_BLK_WIDTH_4x4 * SUB_BLK_WIDTH_4x4); i++)
160     {
161         INV_QUANT(pi4_tmp_ptr[i], pu2_iscal_mat[0], pu2_weigh_mat[0],
162                   u4_qp_div_6, rnd_fact, 6);
163         pi2_out_ptr[i] = pi4_tmp_ptr[i];
164     }
165 }
166 
167 /**
168 ********************************************************************************
169 *
170 * @brief This function performs a 2x2 inverse hadamard transform on the chroma
171 * DC coefficients and then performs scaling.
172 *
173 * @par Description:
174 *  The DC coefficients pass through a 2-stage inverse hadamard transform.
175 *  This inverse transformed content is scaled to based on Qp value.
176 *
177 * @param[in] pi2_src
178 *  input 2x2 block of DC coefficients
179 *
180 * @param[out] pi2_out
181 *  output 2x2 block
182 *
183 * @param[in] pu2_iscal_mat
184 *  pointer to scaling list
185 *
186 * @param[in] pu2_weigh_mat
187 *  pointer to weight matrix
188 *
189 * @param[in] u4_qp_div_6
190 *  Floor (qp/6)
191 *
192 * @param[in] pi4_tmp
193 *  temporary buffer of size 1*16
194 *
195 * @returns none
196 *
197 * @remarks none
198 *
199 *******************************************************************************
200 */
ih264_ihadamard_scaling_2x2_uv(WORD16 * pi2_src,WORD16 * pi2_out,const UWORD16 * pu2_iscal_mat,const UWORD16 * pu2_weigh_mat,UWORD32 u4_qp_div_6,WORD32 * pi4_tmp)201 void ih264_ihadamard_scaling_2x2_uv(WORD16* pi2_src,
202                                     WORD16* pi2_out,
203                                     const UWORD16 *pu2_iscal_mat,
204                                     const UWORD16 *pu2_weigh_mat,
205                                     UWORD32 u4_qp_div_6,
206                                     WORD32* pi4_tmp)
207 {
208     WORD32 i4_x0, i4_x1, i4_x2, i4_x3, i4_x4, i4_x5, i4_x6, i4_x7;
209     WORD32 i4_y0, i4_y1, i4_y2, i4_y3, i4_y4, i4_y5, i4_y6, i4_y7;
210 
211     UNUSED(pi4_tmp);
212 
213     /* U Plane */
214     i4_x4 = pi2_src[0];
215     i4_x5 = pi2_src[1];
216     i4_x6 = pi2_src[2];
217     i4_x7 = pi2_src[3];
218 
219     i4_x0 = i4_x4 + i4_x5;
220     i4_x1 = i4_x4 - i4_x5;
221     i4_x2 = i4_x6 + i4_x7;
222     i4_x3 = i4_x6 - i4_x7;
223 
224     i4_x4 = i4_x0 + i4_x2;
225     i4_x5 = i4_x1 + i4_x3;
226     i4_x6 = i4_x0 - i4_x2;
227     i4_x7 = i4_x1 - i4_x3;
228 
229     INV_QUANT(i4_x4, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
230     INV_QUANT(i4_x5, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
231     INV_QUANT(i4_x6, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
232     INV_QUANT(i4_x7, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
233 
234     pi2_out[0] = i4_x4;
235     pi2_out[1] = i4_x5;
236     pi2_out[2] = i4_x6;
237     pi2_out[3] = i4_x7;
238 
239     /* V Plane */
240     i4_y4 = pi2_src[4];
241     i4_y5 = pi2_src[5];
242     i4_y6 = pi2_src[6];
243     i4_y7 = pi2_src[7];
244 
245     i4_y0 = i4_y4 + i4_y5;
246     i4_y1 = i4_y4 - i4_y5;
247     i4_y2 = i4_y6 + i4_y7;
248     i4_y3 = i4_y6 - i4_y7;
249 
250     i4_y4 = i4_y0 + i4_y2;
251     i4_y5 = i4_y1 + i4_y3;
252     i4_y6 = i4_y0 - i4_y2;
253     i4_y7 = i4_y1 - i4_y3;
254 
255     INV_QUANT(i4_y4, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
256     INV_QUANT(i4_y5, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
257     INV_QUANT(i4_y6, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
258     INV_QUANT(i4_y7, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5);
259 
260     pi2_out[4] = i4_y4;
261     pi2_out[5] = i4_y5;
262     pi2_out[6] = i4_y6;
263     pi2_out[7] = i4_y7;
264 }
265