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_chroma_iquant_itrans_recon.c
22 *
23 * @brief
24 * Contains function definitions for inverse quantization, inverse
25 * transform and reconstruction of chroma interleaved data.
26 *
27 * @author
28 * 100470
29 *
30 * @par List of Functions:
31 * - ihevc_chroma_iquant_itrans_recon_4x4()
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_chroma_iquant_itrans_recon.h"
46 #include "ihevc_func_selector.h"
47 #include "ihevc_trans_macros.h"
48
49 /* All the functions work one component(U or V) of interleaved data depending upon pointers passed to it */
50 /* Data visualization */
51 /* U V U V U V U V */
52 /* U V U V U V U V */
53 /* U V U V U V U V */
54 /* U V U V U V U V */
55 /* If the pointer points to first byte of above stream (U) , functions will operate on U component */
56 /* If the pointer points to second byte of above stream (V) , functions will operate on V component */
57
58
59 /**
60 *******************************************************************************
61 *
62 * @brief
63 * This function performs inverse quantization, inverse transform and
64 * reconstruction for 4x4 input block
65 *
66 * @par Description:
67 * Performs inverse quantization , inverse transform and adds the
68 * prediction data and clips output to 8 bit
69 *
70 * @param[in] pi2_src
71 * Input 4x4 coefficients
72 *
73 * @param[in] pi2_tmp
74 * Temporary 4x4 buffer for storing inverse transform
75 * 1st stage output
76 *
77 * @param[in] pu1_pred
78 * Prediction 4x4 block
79 *
80 * @param[in] pi2_dequant_coeff
81 * Dequant Coeffs
82 *
83 * @param[out] pu1_dst
84 * Output 4x4 block
85 *
86 * @param[in] qp_div
87 * Quantization parameter / 6
88 *
89 * @param[in] qp_rem
90 * Quantization parameter % 6
91 *
92 * @param[in] src_strd
93 * Input stride
94 *
95 * @param[in] pred_strd
96 * Prediction stride
97 *
98 * @param[in] dst_strd
99 * Output Stride
100 *
101 * @param[in] zero_cols
102 * Zero columns in pi2_src
103 *
104 * @param[in] zero_rows
105 * Zero Rows in pi2_src
106 *
107 * @returns Void
108 *
109 * @remarks
110 * None
111 *
112 *******************************************************************************
113 */
114
115
ihevc_chroma_iquant_itrans_recon_4x4(WORD16 * pi2_src,WORD16 * pi2_tmp,UWORD8 * pu1_pred,WORD16 * pi2_dequant_coeff,UWORD8 * pu1_dst,WORD32 qp_div,WORD32 qp_rem,WORD32 src_strd,WORD32 pred_strd,WORD32 dst_strd,WORD32 zero_cols,WORD32 zero_rows)116 void ihevc_chroma_iquant_itrans_recon_4x4(WORD16 *pi2_src,
117 WORD16 *pi2_tmp,
118 UWORD8 *pu1_pred,
119 WORD16 *pi2_dequant_coeff,
120 UWORD8 *pu1_dst,
121 WORD32 qp_div, /* qpscaled / 6 */
122 WORD32 qp_rem, /* qpscaled % 6 */
123 WORD32 src_strd,
124 WORD32 pred_strd,
125 WORD32 dst_strd,
126 WORD32 zero_cols,
127 WORD32 zero_rows)
128 {
129 UNUSED(zero_rows);
130
131 /* Inverse Transform */
132 {
133 WORD32 j;
134 WORD32 e[2], o[2];
135 WORD32 add;
136 WORD32 shift;
137 WORD16 *pi2_tmp_orig;
138 WORD32 shift_iq;
139 WORD32 trans_size;
140 /* Inverse Quantization constants */
141 {
142 WORD32 log2_trans_size, bit_depth;
143
144 log2_trans_size = 2;
145 bit_depth = 8 + 0;
146 shift_iq = bit_depth + log2_trans_size - 5;
147 }
148
149 trans_size = TRANS_SIZE_4;
150 pi2_tmp_orig = pi2_tmp;
151
152 /* Inverse Transform 1st stage */
153 shift = IT_SHIFT_STAGE_1;
154 add = 1 << (shift - 1);
155
156 for(j = 0; j < trans_size; j++)
157 {
158 /* Checking for Zero Cols */
159 if((zero_cols & 1) == 1)
160 {
161 memset(pi2_tmp, 0, trans_size * sizeof(WORD16));
162 }
163 else
164 {
165 WORD32 iq_tmp_1, iq_tmp_2;
166 /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
167 IQUANT_4x4(iq_tmp_1,
168 pi2_src[1 * src_strd],
169 pi2_dequant_coeff[1 * trans_size] * g_ihevc_iquant_scales[qp_rem],
170 shift_iq, qp_div);
171 IQUANT_4x4(iq_tmp_2,
172 pi2_src[3 * src_strd],
173 pi2_dequant_coeff[3 * trans_size] * g_ihevc_iquant_scales[qp_rem],
174 shift_iq, qp_div);
175
176 o[0] = g_ai2_ihevc_trans_4[1][0] * iq_tmp_1
177 + g_ai2_ihevc_trans_4[3][0] * iq_tmp_2;
178 o[1] = g_ai2_ihevc_trans_4[1][1] * iq_tmp_1
179 + g_ai2_ihevc_trans_4[3][1] * iq_tmp_2;
180
181 IQUANT_4x4(iq_tmp_1,
182 pi2_src[0 * src_strd],
183 pi2_dequant_coeff[0 * trans_size] * g_ihevc_iquant_scales[qp_rem],
184 shift_iq, qp_div);
185 IQUANT_4x4(iq_tmp_2,
186 pi2_src[2 * src_strd],
187 pi2_dequant_coeff[2 * trans_size] * g_ihevc_iquant_scales[qp_rem],
188 shift_iq, qp_div);
189
190 e[0] = g_ai2_ihevc_trans_4[0][0] * iq_tmp_1
191 + g_ai2_ihevc_trans_4[2][0] * iq_tmp_2;
192 e[1] = g_ai2_ihevc_trans_4[0][1] * iq_tmp_1
193 + g_ai2_ihevc_trans_4[2][1] * iq_tmp_2;
194
195 pi2_tmp[0] =
196 CLIP_S16(((e[0] + o[0] + add) >> shift));
197 pi2_tmp[1] =
198 CLIP_S16(((e[1] + o[1] + add) >> shift));
199 pi2_tmp[2] =
200 CLIP_S16(((e[1] - o[1] + add) >> shift));
201 pi2_tmp[3] =
202 CLIP_S16(((e[0] - o[0] + add) >> shift));
203 }
204 pi2_src++;
205 pi2_dequant_coeff++;
206 pi2_tmp += trans_size;
207 zero_cols = zero_cols >> 1;
208 }
209
210 pi2_tmp = pi2_tmp_orig;
211
212 /* Inverse Transform 2nd stage */
213 shift = IT_SHIFT_STAGE_2;
214 add = 1 << (shift - 1);
215
216 for(j = 0; j < trans_size; j++)
217 {
218 WORD32 itrans_out;
219
220 /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
221 o[0] = g_ai2_ihevc_trans_4[1][0] * pi2_tmp[trans_size]
222 + g_ai2_ihevc_trans_4[3][0]
223 * pi2_tmp[3 * trans_size];
224 o[1] = g_ai2_ihevc_trans_4[1][1] * pi2_tmp[trans_size]
225 + g_ai2_ihevc_trans_4[3][1]
226 * pi2_tmp[3 * trans_size];
227 e[0] = g_ai2_ihevc_trans_4[0][0] * pi2_tmp[0]
228 + g_ai2_ihevc_trans_4[2][0]
229 * pi2_tmp[2 * trans_size];
230 e[1] = g_ai2_ihevc_trans_4[0][1] * pi2_tmp[0]
231 + g_ai2_ihevc_trans_4[2][1]
232 * pi2_tmp[2 * trans_size];
233
234 itrans_out =
235 CLIP_S16(((e[0] + o[0] + add) >> shift));
236 pu1_dst[0 * 2] = CLIP_U8((itrans_out + pu1_pred[0 * 2]));
237
238 itrans_out =
239 CLIP_S16(((e[1] + o[1] + add) >> shift));
240 pu1_dst[1 * 2] = CLIP_U8((itrans_out + pu1_pred[1 * 2]));
241
242 itrans_out =
243 CLIP_S16(((e[1] - o[1] + add) >> shift));
244 pu1_dst[2 * 2] = CLIP_U8((itrans_out + pu1_pred[2 * 2]));
245
246 itrans_out =
247 CLIP_S16(((e[0] - o[0] + add) >> shift));
248 pu1_dst[3 * 2] = CLIP_U8((itrans_out + pu1_pred[3 * 2]));
249
250 pi2_tmp++;
251 pu1_pred += pred_strd;
252 pu1_dst += dst_strd;
253
254 }
255 }
256 }
257