/src/libhevc/decoder/ihevcd_iquant_itrans_recon_ctb.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 | | * ihevcd_iquant_itrans_recon_ctb.c |
22 | | * |
23 | | * @brief |
24 | | * Contains functions for inverse quantization, inverse transform and recon |
25 | | * |
26 | | * @author |
27 | | * Ittiam |
28 | | * |
29 | | * @par List of Functions: |
30 | | * - ihevcd_iquant_itrans_recon_ctb() |
31 | | * |
32 | | * @remarks |
33 | | * None |
34 | | * |
35 | | ******************************************************************************* |
36 | | */ |
37 | | /*****************************************************************************/ |
38 | | /* File Includes */ |
39 | | /*****************************************************************************/ |
40 | | #include <stdio.h> |
41 | | #include <stddef.h> |
42 | | #include <stdlib.h> |
43 | | #include <string.h> |
44 | | |
45 | | #include "ihevc_typedefs.h" |
46 | | #include "iv.h" |
47 | | #include "ivd.h" |
48 | | #include "ihevcd_cxa.h" |
49 | | |
50 | | #include "ihevc_defs.h" |
51 | | #include "ihevc_debug.h" |
52 | | #include "ihevc_structs.h" |
53 | | #include "ihevc_cabac_tables.h" |
54 | | #include "ihevc_macros.h" |
55 | | #include "ihevc_platform_macros.h" |
56 | | |
57 | | #include "ihevcd_defs.h" |
58 | | #include "ihevcd_function_selector.h" |
59 | | #include "ihevcd_structs.h" |
60 | | #include "ihevcd_error.h" |
61 | | #include "ihevcd_bitstream.h" |
62 | | #include "ihevc_common_tables.h" |
63 | | |
64 | | /* Intra pred includes */ |
65 | | #include "ihevc_intra_pred.h" |
66 | | |
67 | | /* Inverse transform common module includes */ |
68 | | #include "ihevc_trans_tables.h" |
69 | | #include "ihevc_trans_macros.h" |
70 | | #include "ihevc_itrans_recon.h" |
71 | | #include "ihevc_recon.h" |
72 | | #include "ihevc_chroma_itrans_recon.h" |
73 | | #include "ihevc_chroma_recon.h" |
74 | | |
75 | | /* Decoder includes */ |
76 | | #include "ihevcd_common_tables.h" |
77 | | #include "ihevcd_iquant_itrans_recon_ctb.h" |
78 | | #include "ihevcd_debug.h" |
79 | | #include "ihevcd_profile.h" |
80 | | #include "ihevcd_statistics.h" |
81 | | #include "ihevcd_itrans_recon_dc.h" |
82 | | |
83 | | |
84 | | /* Globals */ |
85 | | static const WORD32 g_i4_ip_funcs[MAX_NUM_IP_MODES] = |
86 | | { IP_FUNC_MODE_0, /* Mode 0 */ |
87 | | IP_FUNC_MODE_1, /* Mode 1 */ |
88 | | IP_FUNC_MODE_2, /* Mode 2 */ |
89 | | IP_FUNC_MODE_3TO9, /* Mode 3 */ |
90 | | IP_FUNC_MODE_3TO9, /* Mode 4 */ |
91 | | IP_FUNC_MODE_3TO9, /* Mode 5 */ |
92 | | IP_FUNC_MODE_3TO9, /* Mode 6 */ |
93 | | IP_FUNC_MODE_3TO9, /* Mode 7 */ |
94 | | IP_FUNC_MODE_3TO9, /* Mode 8 */ |
95 | | IP_FUNC_MODE_3TO9, /* Mode 9 */ |
96 | | IP_FUNC_MODE_10, /* Mode 10 */ |
97 | | IP_FUNC_MODE_11TO17, /* Mode 11 */ |
98 | | IP_FUNC_MODE_11TO17, /* Mode 12 */ |
99 | | IP_FUNC_MODE_11TO17, /* Mode 13 */ |
100 | | IP_FUNC_MODE_11TO17, /* Mode 14 */ |
101 | | IP_FUNC_MODE_11TO17, /* Mode 15 */ |
102 | | IP_FUNC_MODE_11TO17, /* Mode 16 */ |
103 | | IP_FUNC_MODE_11TO17, /* Mode 17 */ |
104 | | IP_FUNC_MODE_18_34, /* Mode 18 */ |
105 | | IP_FUNC_MODE_19TO25, /* Mode 19 */ |
106 | | IP_FUNC_MODE_19TO25, /* Mode 20 */ |
107 | | IP_FUNC_MODE_19TO25, /* Mode 21 */ |
108 | | IP_FUNC_MODE_19TO25, /* Mode 22 */ |
109 | | IP_FUNC_MODE_19TO25, /* Mode 23 */ |
110 | | IP_FUNC_MODE_19TO25, /* Mode 24 */ |
111 | | IP_FUNC_MODE_19TO25, /* Mode 25 */ |
112 | | IP_FUNC_MODE_26, /* Mode 26 */ |
113 | | IP_FUNC_MODE_27TO33, /* Mode 27 */ |
114 | | IP_FUNC_MODE_27TO33, /* Mode 26 */ |
115 | | IP_FUNC_MODE_27TO33, /* Mode 29 */ |
116 | | IP_FUNC_MODE_27TO33, /* Mode 30 */ |
117 | | IP_FUNC_MODE_27TO33, /* Mode 31 */ |
118 | | IP_FUNC_MODE_27TO33, /* Mode 32 */ |
119 | | IP_FUNC_MODE_27TO33, /* Mode 33 */ |
120 | | IP_FUNC_MODE_18_34, /* Mode 34 */ |
121 | | }; |
122 | | |
123 | | |
124 | | const WORD16 *g_ai2_ihevc_trans_tables[] = |
125 | | { &g_ai2_ihevc_trans_dst_4[0][0], |
126 | | &g_ai2_ihevc_trans_4[0][0], |
127 | | &g_ai2_ihevc_trans_8[0][0], |
128 | | &g_ai2_ihevc_trans_16[0][0], |
129 | | &g_ai2_ihevc_trans_32[0][0] |
130 | | }; |
131 | | |
132 | | |
133 | | /*****************************************************************************/ |
134 | | /* Structures */ |
135 | | /*****************************************************************************/ |
136 | | /** |
137 | | * Structure to hold fields required for iq it recon construction process |
138 | | */ |
139 | | typedef struct |
140 | | { |
141 | | /* |
142 | | * parsed transform coeffs |
143 | | */ |
144 | | WORD16 *pi2_tu_coeff; |
145 | | |
146 | | /** |
147 | | * pred buffer |
148 | | */ |
149 | | UWORD8 *pu1_pred; |
150 | | |
151 | | /** |
152 | | * recon buffer |
153 | | */ |
154 | | UWORD8 *pu1_dst; |
155 | | |
156 | | /** |
157 | | * transform coeffs buffer stride |
158 | | */ |
159 | | WORD32 tu_coeff_stride; |
160 | | |
161 | | /** |
162 | | * pred buffer stride |
163 | | */ |
164 | | WORD32 pred_strd; |
165 | | |
166 | | /** |
167 | | * recon buffer stride |
168 | | */ |
169 | | WORD32 dst_strd; |
170 | | |
171 | | /** |
172 | | * zero cols, zero rows for optimizing itrans process |
173 | | */ |
174 | | UWORD32 zero_cols; |
175 | | UWORD32 zero_rows; |
176 | | |
177 | | /** |
178 | | * dc only? for optimizing itrans process |
179 | | */ |
180 | | UWORD32 coeff_type; |
181 | | WORD16 coeff_value; |
182 | | |
183 | | /** |
184 | | * cbf |
185 | | */ |
186 | | UWORD8 cbf; |
187 | | |
188 | | /** |
189 | | * is transform skip |
190 | | */ |
191 | | UWORD8 transform_skip_flag; |
192 | | |
193 | | #ifdef ENABLE_MAIN_REXT_PROFILE |
194 | | /** |
195 | | * is explicit rdpcm enabled |
196 | | */ |
197 | | UWORD8 explicit_rdpcm_flag; |
198 | | |
199 | | /** |
200 | | * explicit rdpcm dir |
201 | | */ |
202 | | UWORD8 explicit_rdpcm_dir; |
203 | | #endif |
204 | | |
205 | | } tu_plane_iq_it_recon_ctxt_t; |
206 | | |
207 | | |
208 | | /*****************************************************************************/ |
209 | | /* Function Prototypes */ |
210 | | /*****************************************************************************/ |
211 | | typedef void (*PF_IQITRECON_PLANE)(process_ctxt_t *ps_proc, |
212 | | tu_t *ps_tu, |
213 | | tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt, |
214 | | WORD32 func_idx, |
215 | | WORD32 log2_trans_size, |
216 | | CHROMA_PLANE_ID_T chroma_plane, |
217 | | WORD8 intra_flag, |
218 | | WORD8 intra_pred_mode); |
219 | | |
220 | | /* Returns number of ai2_level read from ps_sblk_coeff */ |
221 | | UWORD8* ihevcd_unpack_coeffs(WORD16 *pi2_tu_coeff, |
222 | | WORD32 log2_trans_size, |
223 | | UWORD8 *pu1_tu_coeff_data, |
224 | | WORD16 *pi2_dequant_matrix, |
225 | | WORD32 qp_rem, |
226 | | WORD32 qp_div, |
227 | | TRANSFORM_TYPE e_trans_type, |
228 | | WORD32 trans_quant_bypass, |
229 | | UWORD32 *pu4_zero_cols, |
230 | | UWORD32 *pu4_zero_rows, |
231 | | UWORD32 *pu4_coeff_type, |
232 | | WORD16 *pi2_coeff_value) |
233 | 0 | { |
234 | | /* Generating coeffs from coeff-map */ |
235 | 0 | WORD32 i; |
236 | 0 | WORD16 *pi2_sblk_ptr; |
237 | 0 | WORD32 subblk_pos_x, subblk_pos_y; |
238 | 0 | WORD32 sblk_scan_idx, coeff_raster_idx; |
239 | 0 | WORD32 sblk_non_zero_coeff_idx; |
240 | 0 | tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data; |
241 | 0 | UWORD8 u1_num_coded_sblks, u1_scan_type; |
242 | 0 | UWORD8 *pu1_new_tu_coeff_data; |
243 | 0 | WORD32 trans_size; |
244 | 0 | WORD32 xs, ys; |
245 | 0 | WORD32 trans_skip; |
246 | 0 | WORD16 iquant_out; |
247 | 0 | WORD32 shift_iq; |
248 | 0 | WORD32 bit_depth; |
249 | |
|
250 | 0 | bit_depth = 8 + 0; |
251 | 0 | shift_iq = bit_depth + log2_trans_size - 5; |
252 | 0 | trans_size = (1 << log2_trans_size); |
253 | | |
254 | | /* First byte points to number of coded blocks */ |
255 | 0 | u1_num_coded_sblks = *pu1_tu_coeff_data++; |
256 | | |
257 | | /* Next byte points to scan type */ |
258 | 0 | u1_scan_type = *pu1_tu_coeff_data++; |
259 | | /* 0th bit has trans_skip */ |
260 | 0 | trans_skip = u1_scan_type & 1; |
261 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
262 | 0 | u1_scan_type = (u1_scan_type & 0xF) >> 1; |
263 | | #else |
264 | | u1_scan_type >>= 1; |
265 | | #endif |
266 | |
|
267 | 0 | pi2_sblk_ptr = pi2_tu_coeff; |
268 | | |
269 | | /* Initially all columns are assumed to be zero */ |
270 | 0 | *pu4_zero_cols = 0xFFFFFFFF; |
271 | | /* Initially all rows are assumed to be zero */ |
272 | 0 | *pu4_zero_rows = 0xFFFFFFFF; |
273 | |
|
274 | 0 | ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)(pu1_tu_coeff_data); |
275 | |
|
276 | 0 | if(trans_skip) |
277 | 0 | memset(pi2_tu_coeff, 0, trans_size * trans_size * sizeof(WORD16)); |
278 | |
|
279 | 0 | STATS_INIT_SBLK_AND_COEFF_POS(); |
280 | | |
281 | | /* DC only case */ |
282 | 0 | if((e_trans_type != DST_4x4) && (1 == u1_num_coded_sblks) |
283 | 0 | && (0 == ps_tu_sblk_coeff_data->u2_subblk_pos) |
284 | 0 | && (1 == ps_tu_sblk_coeff_data->u2_sig_coeff_map)) |
285 | 0 | { |
286 | 0 | *pu4_coeff_type = 1; |
287 | |
|
288 | 0 | if(!trans_quant_bypass) |
289 | 0 | { |
290 | 0 | WORD32 dequant_coeff = (trans_skip && (trans_size > 4)) ? 16 : pi2_dequant_matrix[0]; |
291 | 0 | if(4 == trans_size) |
292 | 0 | { |
293 | 0 | IQUANT_4x4(iquant_out, |
294 | 0 | ps_tu_sblk_coeff_data->ai2_level[0], |
295 | 0 | dequant_coeff |
296 | 0 | * g_ihevc_iquant_scales[qp_rem], |
297 | 0 | shift_iq, qp_div); |
298 | 0 | } |
299 | 0 | else |
300 | 0 | { |
301 | 0 | IQUANT(iquant_out, ps_tu_sblk_coeff_data->ai2_level[0], |
302 | 0 | dequant_coeff * g_ihevc_iquant_scales[qp_rem], |
303 | 0 | shift_iq, qp_div); |
304 | 0 | } |
305 | 0 | if(trans_skip) |
306 | 0 | { |
307 | 0 | WORD32 shift_ts = MAX_TR_DYNAMIC_RANGE - bit_depth - log2_trans_size; |
308 | 0 | if(shift_ts > 0) |
309 | 0 | { |
310 | 0 | iquant_out = (iquant_out + (1 << (shift_ts - 1))) >> shift_ts; |
311 | 0 | } |
312 | 0 | else if(shift_ts < 0) |
313 | 0 | { |
314 | 0 | iquant_out = iquant_out << (-shift_ts); |
315 | 0 | } |
316 | 0 | } |
317 | 0 | } |
318 | 0 | else |
319 | 0 | { |
320 | | /* setting the column to zero */ |
321 | 0 | for(i = 0; i < trans_size; i++) |
322 | 0 | *(pi2_tu_coeff + i * trans_size) = 0; |
323 | |
|
324 | 0 | iquant_out = ps_tu_sblk_coeff_data->ai2_level[0]; |
325 | 0 | } |
326 | 0 | *pi2_coeff_value = iquant_out; |
327 | 0 | *pi2_tu_coeff = iquant_out; |
328 | 0 | *pu4_zero_cols &= ~0x1; |
329 | 0 | *pu4_zero_rows &= ~0x1; |
330 | 0 | ps_tu_sblk_coeff_data = |
331 | 0 | (void *)&ps_tu_sblk_coeff_data->ai2_level[1]; |
332 | |
|
333 | 0 | STATS_UPDATE_COEFF_COUNT(); |
334 | 0 | STATS_LAST_SBLK_POS_UPDATE(e_trans_type, (trans_skip || trans_quant_bypass), 0, 0); |
335 | 0 | STATS_UPDATE_SBLK_AND_COEFF_HISTOGRAM(e_trans_type, (trans_quant_bypass || trans_skip)); |
336 | 0 | return ((UWORD8 *)ps_tu_sblk_coeff_data); |
337 | 0 | } |
338 | 0 | else |
339 | 0 | { |
340 | 0 | *pu4_coeff_type = 0; |
341 | | /* In case of trans skip, memset has already happened */ |
342 | 0 | if(!trans_skip) |
343 | 0 | memset(pi2_tu_coeff, 0, trans_size * trans_size * sizeof(WORD16)); |
344 | 0 | } |
345 | | |
346 | 0 | for(i = 0; i < u1_num_coded_sblks; i++) |
347 | 0 | { |
348 | 0 | UWORD32 u4_sig_coeff_map; |
349 | 0 | subblk_pos_x = ps_tu_sblk_coeff_data->u2_subblk_pos & 0x00FF; |
350 | 0 | subblk_pos_y = (ps_tu_sblk_coeff_data->u2_subblk_pos & 0xFF00) >> 8; |
351 | |
|
352 | 0 | STATS_LAST_SBLK_POS_UPDATE(e_trans_type, (trans_skip || trans_quant_bypass), subblk_pos_x, subblk_pos_y); |
353 | |
|
354 | 0 | subblk_pos_x = subblk_pos_x * MIN_TU_SIZE; |
355 | 0 | subblk_pos_y = subblk_pos_y * MIN_TU_SIZE; |
356 | |
|
357 | 0 | pi2_sblk_ptr = pi2_tu_coeff + subblk_pos_y * trans_size |
358 | 0 | + subblk_pos_x; |
359 | | |
360 | | //*pu4_zero_cols &= ~(0xF << subblk_pos_x); |
361 | |
|
362 | 0 | sblk_non_zero_coeff_idx = 0; |
363 | 0 | u4_sig_coeff_map = ps_tu_sblk_coeff_data->u2_sig_coeff_map; |
364 | | //for(sblk_scan_idx = (31 - CLZ(u4_sig_coeff_map)); sblk_scan_idx >= 0; sblk_scan_idx--) |
365 | 0 | sblk_scan_idx = 31; |
366 | 0 | do |
367 | 0 | { |
368 | 0 | WORD32 clz = CLZ(u4_sig_coeff_map); |
369 | |
|
370 | 0 | sblk_scan_idx -= clz; |
371 | | /* when clz is 31, u4_sig_coeff_map << (clz+1) might result in unknown behaviour in some cases */ |
372 | | /* Hence either use SHL which takes care of handling these issues based on platform or shift in two stages */ |
373 | 0 | u4_sig_coeff_map = u4_sig_coeff_map << clz; |
374 | | /* Copying coeffs and storing in reverse order */ |
375 | 0 | { |
376 | 0 | STATS_UPDATE_COEFF_COUNT(); |
377 | 0 | coeff_raster_idx = |
378 | 0 | gau1_ihevc_invscan4x4[u1_scan_type][sblk_scan_idx]; |
379 | |
|
380 | 0 | xs = coeff_raster_idx & 0x3; |
381 | 0 | ys = coeff_raster_idx >> 2; |
382 | |
|
383 | 0 | if(!trans_quant_bypass) |
384 | 0 | { |
385 | 0 | WORD32 dequant_coeff = (trans_skip && (trans_size > 4)) ? 16 : pi2_dequant_matrix[(subblk_pos_x + xs) + (subblk_pos_y + ys) * trans_size]; |
386 | 0 | if(4 == trans_size) |
387 | 0 | { |
388 | 0 | IQUANT_4x4(iquant_out, |
389 | 0 | ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx], |
390 | 0 | dequant_coeff |
391 | 0 | * g_ihevc_iquant_scales[qp_rem], |
392 | 0 | shift_iq, qp_div); |
393 | 0 | sblk_non_zero_coeff_idx++; |
394 | 0 | } |
395 | 0 | else |
396 | 0 | { |
397 | 0 | IQUANT(iquant_out, |
398 | 0 | ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx], |
399 | 0 | dequant_coeff * g_ihevc_iquant_scales[qp_rem], |
400 | 0 | shift_iq, qp_div); |
401 | 0 | sblk_non_zero_coeff_idx++; |
402 | 0 | } |
403 | |
|
404 | 0 | if(trans_skip) |
405 | 0 | { |
406 | 0 | WORD32 shift_ts = MAX_TR_DYNAMIC_RANGE - bit_depth - log2_trans_size; |
407 | 0 | if(shift_ts > 0) |
408 | 0 | { |
409 | 0 | iquant_out = (iquant_out + (1 << (shift_ts - 1))) >> shift_ts; |
410 | 0 | } |
411 | 0 | else if(shift_ts < 0) |
412 | 0 | { |
413 | 0 | iquant_out = iquant_out << (-shift_ts); |
414 | 0 | } |
415 | 0 | } |
416 | 0 | } |
417 | 0 | else |
418 | 0 | { |
419 | 0 | iquant_out = ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx++]; |
420 | 0 | } |
421 | 0 | *pu4_zero_cols &= ~(0x1U << (subblk_pos_x + xs)); |
422 | 0 | *pu4_zero_rows &= ~(0x1U << (subblk_pos_y + ys)); |
423 | 0 | *(pi2_sblk_ptr + xs + ys * trans_size) = iquant_out; |
424 | 0 | } |
425 | 0 | sblk_scan_idx--; |
426 | 0 | u4_sig_coeff_map <<= 1; |
427 | |
|
428 | 0 | }while(u4_sig_coeff_map); |
429 | | /* Updating the sblk pointer */ |
430 | 0 | ps_tu_sblk_coeff_data = |
431 | 0 | (void *)&ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx]; |
432 | 0 | } |
433 | |
|
434 | 0 | STATS_UPDATE_SBLK_AND_COEFF_HISTOGRAM(e_trans_type, (trans_quant_bypass || trans_skip)); |
435 | |
|
436 | 0 | pu1_new_tu_coeff_data = (UWORD8 *)ps_tu_sblk_coeff_data; |
437 | |
|
438 | 0 | return pu1_new_tu_coeff_data; |
439 | 0 | } |
440 | | |
441 | | WORD32 ihevcd_get_intra_nbr_flag(process_ctxt_t *ps_proc, |
442 | | tu_t *ps_tu, |
443 | | UWORD32 *pu4_intra_nbr_avail, |
444 | | WORD16 i2_pic_width_in_luma_samples, |
445 | | UWORD8 i1_constrained_intra_pred_flag, |
446 | | WORD32 trans_size, |
447 | | WORD32 ctb_size) |
448 | 0 | { |
449 | 0 | sps_t *ps_sps; |
450 | 0 | UWORD8 u1_bot_lt_avail, u1_left_avail, u1_top_avail, u1_top_rt_avail, |
451 | 0 | u1_top_lt_avail; |
452 | 0 | WORD32 x_cur, y_cur, x_nbr, y_nbr; |
453 | 0 | UWORD8 *pu1_nbr_intra_flag; |
454 | 0 | UWORD8 *pu1_pic_intra_flag; |
455 | 0 | UWORD8 top_right, top, top_left, left, bot_left; |
456 | 0 | WORD32 intra_pos; |
457 | 0 | WORD32 num_8_blks, num_8_blks_in_bits; |
458 | 0 | WORD32 numbytes_row = (i2_pic_width_in_luma_samples + 63) / 64; |
459 | 0 | WORD32 cur_x, cur_y; |
460 | 0 | WORD32 i; |
461 | 0 | WORD32 nbr_flags; |
462 | |
|
463 | 0 | ps_sps = ps_proc->ps_sps; |
464 | 0 | cur_x = ps_tu->b4_pos_x; |
465 | 0 | cur_y = ps_tu->b4_pos_y; |
466 | |
|
467 | 0 | u1_bot_lt_avail = (pu4_intra_nbr_avail[1 + cur_y + trans_size / MIN_TU_SIZE] |
468 | 0 | >> (31 - (1 + cur_x - 1))) & 1; |
469 | 0 | u1_left_avail = (pu4_intra_nbr_avail[1 + cur_y] >> (31 - (1 + cur_x - 1))) |
470 | 0 | & 1; |
471 | 0 | u1_top_avail = (pu4_intra_nbr_avail[1 + cur_y - 1] >> (31 - (1 + cur_x))) |
472 | 0 | & 1; |
473 | 0 | u1_top_rt_avail = (pu4_intra_nbr_avail[1 + cur_y - 1] |
474 | 0 | >> (31 - (1 + cur_x + trans_size / MIN_TU_SIZE))) & 1; |
475 | 0 | u1_top_lt_avail = (pu4_intra_nbr_avail[1 + cur_y - 1] |
476 | 0 | >> (31 - (1 + cur_x - 1))) & 1; |
477 | |
|
478 | 0 | x_cur = ps_proc->i4_ctb_x * ctb_size + cur_x * MIN_TU_SIZE; |
479 | 0 | y_cur = ps_proc->i4_ctb_y * ctb_size + cur_y * MIN_TU_SIZE; |
480 | |
|
481 | 0 | pu1_pic_intra_flag = ps_proc->pu1_pic_intra_flag; |
482 | | |
483 | | /* WORD32 nbr_flags as below MSB --> LSB */ |
484 | | /* Top-Left | Top-Right | Top | Left | Bottom-Left |
485 | | * 1 4 4 4 4 |
486 | | */ |
487 | 0 | bot_left = 0; |
488 | 0 | left = 0; |
489 | 0 | top_right = 0; |
490 | 0 | top = 0; |
491 | 0 | top_left = 0; |
492 | |
|
493 | 0 | num_8_blks = trans_size > 4 ? trans_size / 8 : 1; |
494 | 0 | num_8_blks_in_bits = ((1 << num_8_blks) - 1); |
495 | |
|
496 | 0 | if(i1_constrained_intra_pred_flag) |
497 | 0 | { |
498 | | /* TODO: constrained intra pred not tested */ |
499 | 0 | if(u1_bot_lt_avail) |
500 | 0 | { |
501 | 0 | x_nbr = x_cur - 1; |
502 | 0 | y_nbr = y_cur + trans_size; |
503 | |
|
504 | 0 | pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row |
505 | 0 | + x_nbr / 64; |
506 | 0 | intra_pos = ((x_nbr / 8) % 8); |
507 | 0 | for(i = 0; i < num_8_blks; i++) |
508 | 0 | { |
509 | 0 | bot_left |= ((*(pu1_nbr_intra_flag + i * numbytes_row) |
510 | 0 | >> intra_pos) & 1) << i; |
511 | 0 | } |
512 | 0 | bot_left &= num_8_blks_in_bits; |
513 | 0 | } |
514 | 0 | if(u1_left_avail) |
515 | 0 | { |
516 | 0 | x_nbr = x_cur - 1; |
517 | 0 | y_nbr = y_cur; |
518 | |
|
519 | 0 | pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row |
520 | 0 | + x_nbr / 64; |
521 | 0 | intra_pos = ((x_nbr / 8) % 8); |
522 | |
|
523 | 0 | for(i = 0; i < num_8_blks; i++) |
524 | 0 | { |
525 | 0 | left |= ((*(pu1_nbr_intra_flag + i * numbytes_row) >> intra_pos) |
526 | 0 | & 1) << i; |
527 | 0 | } |
528 | 0 | left &= num_8_blks_in_bits; |
529 | 0 | } |
530 | 0 | if(u1_top_avail) |
531 | 0 | { |
532 | 0 | x_nbr = x_cur; |
533 | 0 | y_nbr = y_cur - 1; |
534 | |
|
535 | 0 | pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row |
536 | 0 | + x_nbr / 64; |
537 | 0 | intra_pos = ((x_nbr / 8) % 8); |
538 | |
|
539 | 0 | top = (*pu1_nbr_intra_flag >> intra_pos); |
540 | 0 | top &= num_8_blks_in_bits; |
541 | | /* |
542 | | for(i=0;i<num_8_blks;i++) |
543 | | { |
544 | | top |= ( (*pu1_nbr_intra_flag >> (intra_pos+i)) & 1) << i; |
545 | | } |
546 | | */ |
547 | 0 | } |
548 | 0 | if(u1_top_rt_avail) |
549 | 0 | { |
550 | 0 | x_nbr = x_cur + trans_size; |
551 | 0 | y_nbr = y_cur - 1; |
552 | |
|
553 | 0 | pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row |
554 | 0 | + x_nbr / 64; |
555 | 0 | intra_pos = ((x_nbr / 8) % 8); |
556 | |
|
557 | 0 | top_right = (*pu1_nbr_intra_flag >> intra_pos); |
558 | 0 | top_right &= num_8_blks_in_bits; |
559 | | /* |
560 | | for(i=0;i<num_8_blks;i++) |
561 | | { |
562 | | top_right |= ( (*pu1_nbr_intra_flag >> (intra_pos+i)) & 1) << i; |
563 | | } |
564 | | */ |
565 | 0 | } |
566 | 0 | if(u1_top_lt_avail) |
567 | 0 | { |
568 | 0 | x_nbr = x_cur - 1; |
569 | 0 | y_nbr = y_cur - 1; |
570 | |
|
571 | 0 | pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row |
572 | 0 | + x_nbr / 64; |
573 | 0 | intra_pos = ((x_nbr / 8) % 8); |
574 | |
|
575 | 0 | top_left = (*pu1_nbr_intra_flag >> intra_pos) & 1; |
576 | 0 | } |
577 | 0 | } |
578 | 0 | else |
579 | 0 | { |
580 | 0 | if(u1_top_avail) |
581 | 0 | top = 0xF; |
582 | 0 | if(u1_top_rt_avail) |
583 | 0 | top_right = 0xF; |
584 | 0 | if(u1_bot_lt_avail) |
585 | 0 | bot_left = 0xF; |
586 | 0 | if(u1_left_avail) |
587 | 0 | left = 0xF; |
588 | 0 | if(u1_top_lt_avail) |
589 | 0 | top_left = 0x1; |
590 | 0 | } |
591 | | |
592 | | /* Handling incomplete CTBs */ |
593 | 0 | { |
594 | 0 | WORD32 pu_size_limit = MIN(trans_size, 8); |
595 | 0 | WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples |
596 | 0 | - (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size) |
597 | 0 | - (ps_tu->b4_pos_x * MIN_TU_SIZE) |
598 | 0 | - (1 << (ps_tu->b3_size + 2)); |
599 | | /* ctb_size_top gives number of valid pixels remaining in the current row */ |
600 | 0 | WORD32 ctb_size_top = MIN(ctb_size, cols_remaining); |
601 | 0 | WORD32 ctb_size_top_bits = (1 << (ctb_size_top / pu_size_limit)) - 1; |
602 | |
|
603 | 0 | WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples |
604 | 0 | - (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size) |
605 | 0 | - (ps_tu->b4_pos_y * MIN_TU_SIZE) |
606 | 0 | - (1 << (ps_tu->b3_size + 2)); |
607 | | /* ctb_size_bot gives number of valid pixels remaining in the current column */ |
608 | 0 | WORD32 ctb_size_bot = MIN(ctb_size, rows_remaining); |
609 | 0 | WORD32 ctb_size_bot_bits = (1 << (ctb_size_bot / pu_size_limit)) - 1; |
610 | |
|
611 | 0 | top_right &= ctb_size_top_bits; |
612 | 0 | bot_left &= ctb_size_bot_bits; |
613 | 0 | } |
614 | | |
615 | | /* Top-Left | Top-Right | Top | Left | Bottom-Left |
616 | | * 1 4 4 4 4 |
617 | | */ |
618 | | |
619 | | /* |
620 | | nbr_flags = (top_left << 16) | (gau4_ihevcd_4_bit_reverse[top_right] << 12) | (gau4_ihevcd_4_bit_reverse[top] << 8) | (gau4_ihevcd_4_bit_reverse[left] << 4) |
621 | | | gau4_ihevcd_4_bit_reverse[bot_left]; |
622 | | */ |
623 | 0 | nbr_flags = (top_left << 16) | (top_right << 12) | (top << 8) | (gau4_ihevcd_4_bit_reverse[left] << 4) |
624 | 0 | | gau4_ihevcd_4_bit_reverse[bot_left]; |
625 | | |
626 | |
|
627 | 0 | return nbr_flags; |
628 | |
|
629 | 0 | } |
630 | | |
631 | | static void ihevcd_iquant_itrans_recon_tu_plane(process_ctxt_t *ps_proc, |
632 | | tu_t *ps_tu, |
633 | | tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt, |
634 | | WORD32 func_idx, |
635 | | WORD32 log2_trans_size, |
636 | | CHROMA_PLANE_ID_T chroma_plane, |
637 | | WORD8 intra_flag, |
638 | | WORD8 intra_pred_mode) |
639 | 0 | { |
640 | 0 | sps_t *ps_sps = ps_proc->ps_sps; |
641 | 0 | pps_t *ps_pps = ps_proc->ps_pps; |
642 | 0 | codec_t *ps_codec = ps_proc->ps_codec; |
643 | |
|
644 | 0 | if(1 == ps_pl_tu_ctxt->cbf) |
645 | 0 | { |
646 | 0 | if(ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag) |
647 | 0 | { |
648 | | /* Recon */ |
649 | 0 | ps_codec->apf_recon[func_idx](ps_pl_tu_ctxt->pi2_tu_coeff, ps_pl_tu_ctxt->pu1_pred, |
650 | 0 | ps_pl_tu_ctxt->pu1_dst, ps_pl_tu_ctxt->tu_coeff_stride, |
651 | 0 | ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd, |
652 | 0 | ps_pl_tu_ctxt->zero_cols); |
653 | 0 | } |
654 | 0 | else |
655 | 0 | { |
656 | | /* iQuant , iTrans and Recon */ |
657 | 0 | if((0 == ps_pl_tu_ctxt->coeff_type)) |
658 | 0 | { |
659 | 0 | ps_codec->apf_itrans_recon[func_idx](ps_pl_tu_ctxt->pi2_tu_coeff, |
660 | 0 | ps_proc->pi2_itrans_intrmd_buf, |
661 | 0 | ps_pl_tu_ctxt->pu1_pred, |
662 | 0 | ps_pl_tu_ctxt->pu1_dst, |
663 | 0 | ps_pl_tu_ctxt->tu_coeff_stride, |
664 | 0 | ps_pl_tu_ctxt->pred_strd, |
665 | 0 | ps_pl_tu_ctxt->dst_strd, |
666 | 0 | ps_pl_tu_ctxt->zero_cols, |
667 | 0 | ps_pl_tu_ctxt->zero_rows); |
668 | 0 | } |
669 | 0 | else /* DC only */ |
670 | 0 | { |
671 | 0 | ps_codec->apf_itrans_recon_dc[chroma_plane != NULL_PLANE]( |
672 | 0 | ps_pl_tu_ctxt->pu1_pred, ps_pl_tu_ctxt->pu1_dst, |
673 | 0 | ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd, log2_trans_size, |
674 | 0 | ps_pl_tu_ctxt->coeff_value); |
675 | 0 | } |
676 | 0 | } |
677 | 0 | } |
678 | 0 | } |
679 | | |
680 | | #ifdef ENABLE_MAIN_REXT_PROFILE |
681 | | static void ihevcd_iquant_itrans_resi_recon_tu_plane(process_ctxt_t *ps_proc, |
682 | | tu_t *ps_tu, |
683 | | tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt, |
684 | | WORD32 func_idx, |
685 | | WORD32 log2_trans_size, |
686 | | CHROMA_PLANE_ID_T chroma_plane, |
687 | | WORD8 intra_flag, |
688 | | WORD8 intra_pred_mode) |
689 | 0 | { |
690 | 0 | sps_t *ps_sps = ps_proc->ps_sps; |
691 | 0 | pps_t *ps_pps = ps_proc->ps_pps; |
692 | 0 | codec_t *ps_codec = ps_proc->ps_codec; |
693 | 0 | WORD8 trans_size = 1 << log2_trans_size; |
694 | 0 | WORD16 *pi2_res = ps_proc->pi2_res_luma_buf; |
695 | 0 | WORD16 *pi2_res_uv = ps_proc->pi2_res_chroma_buf; |
696 | 0 | WORD32 alpha = 0; |
697 | 0 | WORD16 *residue_out_base = chroma_plane == NULL_PLANE ? pi2_res : pi2_res_uv; |
698 | 0 | WORD16 *residue_out = residue_out_base; |
699 | | // if both rdpcm and rotate are to be applied, share the output residue buffer between the |
700 | | // two transforms |
701 | 0 | WORD16 *residue_out_intrmdt = residue_out_base + (TRANS_SIZE_4 * TRANS_SIZE_4); |
702 | |
|
703 | 0 | if(chroma_plane == U_PLANE && ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0) |
704 | 0 | { |
705 | 0 | alpha = (1 << (ps_tu->b3_cb_log2_res_scale_abs_plus1 - 1)) |
706 | 0 | * (1 - 2 * ps_tu->b1_cb_log2_res_sign); |
707 | 0 | } |
708 | 0 | else if(chroma_plane == V_PLANE && ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0) |
709 | 0 | { |
710 | 0 | alpha = (1 << (ps_tu->b3_cr_log2_res_scale_abs_plus1 - 1)) |
711 | 0 | * (1 - 2 * ps_tu->b1_cr_log2_res_sign); |
712 | 0 | } |
713 | 0 | if(1 == ps_pl_tu_ctxt->cbf) |
714 | 0 | { |
715 | 0 | if(ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag) |
716 | 0 | { |
717 | 0 | WORD8 rotate = ps_sps->i1_transform_skip_rotation_enabled_flag && trans_size == 4 |
718 | 0 | && intra_flag; |
719 | 0 | WORD8 rdpcm = (ps_sps->i1_implicit_rdpcm_enabled_flag && intra_flag |
720 | 0 | && (intra_pred_mode == 10 || intra_pred_mode == 26)) |
721 | 0 | || ps_pl_tu_ctxt->explicit_rdpcm_flag; |
722 | 0 | WORD16 *src_residue = ps_pl_tu_ctxt->pi2_tu_coeff; |
723 | 0 | WORD16 src_residue_strd = ps_pl_tu_ctxt->tu_coeff_stride; |
724 | |
|
725 | 0 | if(rotate) |
726 | 0 | { |
727 | 0 | ihevc_res_4x4_rotate(src_residue, rdpcm ? residue_out_intrmdt : residue_out, |
728 | 0 | src_residue_strd, trans_size, ps_pl_tu_ctxt->zero_cols); |
729 | 0 | ps_pl_tu_ctxt->zero_cols = |
730 | 0 | gau4_ihevcd_4_bit_reverse[ps_pl_tu_ctxt->zero_cols & 0xF]; |
731 | 0 | src_residue = residue_out_intrmdt; |
732 | 0 | src_residue_strd = trans_size; |
733 | 0 | } |
734 | |
|
735 | 0 | if(rdpcm) |
736 | 0 | { |
737 | 0 | WORD8 rdpcm_dir = |
738 | 0 | ps_pl_tu_ctxt->explicit_rdpcm_flag ? |
739 | 0 | ps_pl_tu_ctxt->explicit_rdpcm_dir : |
740 | 0 | intra_pred_mode != 10; |
741 | 0 | if(rdpcm_dir == 0) |
742 | 0 | { |
743 | 0 | ihevc_res_nxn_rdpcm_horz(src_residue, residue_out, src_residue_strd, trans_size, |
744 | 0 | trans_size, ps_pl_tu_ctxt->zero_cols); |
745 | 0 | ps_pl_tu_ctxt->zero_cols = (1 << CTZ(~ps_pl_tu_ctxt->zero_cols)) - 1; |
746 | 0 | } |
747 | 0 | else |
748 | 0 | { |
749 | 0 | ihevc_res_nxn_rdpcm_vert(src_residue, residue_out, src_residue_strd, trans_size, |
750 | 0 | trans_size, ps_pl_tu_ctxt->zero_cols); |
751 | 0 | } |
752 | 0 | } |
753 | |
|
754 | 0 | if(!rdpcm && !rotate) |
755 | 0 | { |
756 | 0 | ihevc_res_nxn_copy(src_residue, residue_out, src_residue_strd, trans_size, |
757 | 0 | trans_size, ps_pl_tu_ctxt->zero_cols); |
758 | 0 | } |
759 | 0 | } |
760 | 0 | else |
761 | 0 | { |
762 | | /* iQuant, iTrans */ |
763 | 0 | if(0 == ps_pl_tu_ctxt->coeff_type) |
764 | 0 | { |
765 | 0 | WORD32 func_tmp_idx = chroma_plane != NULL_PLANE ? func_idx - 4 : func_idx; |
766 | 0 | ps_codec->apf_itrans_res[func_tmp_idx](ps_pl_tu_ctxt->pi2_tu_coeff, |
767 | 0 | ps_proc->pi2_itrans_intrmd_buf, residue_out, |
768 | 0 | ps_pl_tu_ctxt->tu_coeff_stride, trans_size, |
769 | 0 | ps_pl_tu_ctxt->zero_cols, |
770 | 0 | ps_pl_tu_ctxt->zero_rows); |
771 | 0 | } |
772 | 0 | else /* DC only */ |
773 | 0 | { |
774 | 0 | ps_codec->apf_itrans_res_dc(residue_out, trans_size, log2_trans_size, |
775 | 0 | ps_pl_tu_ctxt->coeff_value); |
776 | 0 | } |
777 | 0 | ps_pl_tu_ctxt->zero_cols = 0; |
778 | 0 | } |
779 | 0 | if(!alpha) |
780 | 0 | { |
781 | 0 | ps_codec->apf_recon[func_idx](residue_out, ps_pl_tu_ctxt->pu1_pred, |
782 | 0 | ps_pl_tu_ctxt->pu1_dst, trans_size, |
783 | 0 | ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd, |
784 | 0 | ps_pl_tu_ctxt->zero_cols); |
785 | 0 | } |
786 | 0 | } |
787 | 0 | if(alpha) |
788 | 0 | { |
789 | 0 | if(0 == ps_pl_tu_ctxt->cbf) |
790 | 0 | { |
791 | 0 | memset(residue_out, 0, trans_size * trans_size * sizeof(WORD16)); |
792 | 0 | } |
793 | 0 | ihevc_chroma_recon_nxn_ccp(pi2_res, pi2_res_uv, ps_pl_tu_ctxt->pu1_pred, |
794 | 0 | ps_pl_tu_ctxt->pu1_dst, alpha, trans_size, trans_size, |
795 | 0 | trans_size, ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd); |
796 | 0 | } |
797 | 0 | } |
798 | | |
799 | | PF_IQITRECON_PLANE get_iqitrec_func(process_ctxt_t *ps_proc, |
800 | | tu_t *ps_tu, |
801 | | tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt, |
802 | | WORD32 log2_trans_size, |
803 | | CHROMA_PLANE_ID_T chroma_plane, |
804 | | WORD8 intra_flag, |
805 | | WORD8 intra_pred_mode) |
806 | 0 | { |
807 | 0 | sps_t *ps_sps = ps_proc->ps_sps; |
808 | 0 | pps_t *ps_pps = ps_proc->ps_pps; |
809 | 0 | WORD8 trans_size = 1 << log2_trans_size; |
810 | |
|
811 | 0 | if(1 == ps_pl_tu_ctxt->cbf |
812 | 0 | && (ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag)) |
813 | 0 | { |
814 | 0 | if(ps_sps->i1_transform_skip_rotation_enabled_flag && trans_size == 4 && intra_flag) |
815 | 0 | return ihevcd_iquant_itrans_resi_recon_tu_plane; |
816 | 0 | if(ps_sps->i1_implicit_rdpcm_enabled_flag && intra_flag |
817 | 0 | && (intra_pred_mode == 10 || intra_pred_mode == 26)) |
818 | 0 | return ihevcd_iquant_itrans_resi_recon_tu_plane; |
819 | 0 | if(ps_pl_tu_ctxt->explicit_rdpcm_flag) |
820 | 0 | return ihevcd_iquant_itrans_resi_recon_tu_plane; |
821 | 0 | } |
822 | 0 | if(ps_pps->i1_cross_component_prediction_enabled_flag) |
823 | 0 | { |
824 | 0 | if((chroma_plane == NULL_PLANE |
825 | 0 | && (ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0 |
826 | 0 | || ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0)) |
827 | 0 | || (chroma_plane == V_PLANE && ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0) |
828 | 0 | || (chroma_plane == U_PLANE && ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0)) |
829 | 0 | return ihevcd_iquant_itrans_resi_recon_tu_plane; |
830 | 0 | } |
831 | 0 | return ihevcd_iquant_itrans_recon_tu_plane; |
832 | 0 | } |
833 | | #endif |
834 | | |
835 | | WORD32 ihevcd_iquant_itrans_recon_ctb(process_ctxt_t *ps_proc) |
836 | 0 | { |
837 | 0 | WORD16 *pi2_scaling_mat; |
838 | 0 | UWORD8 *pu1_y_dst_ctb; |
839 | 0 | UWORD8 *pu1_uv_dst_ctb; |
840 | 0 | WORD32 ctb_size; |
841 | 0 | codec_t *ps_codec; |
842 | 0 | slice_header_t *ps_slice_hdr; |
843 | 0 | tu_t *ps_tu; |
844 | 0 | WORD16 *pi2_ctb_coeff; |
845 | 0 | WORD32 tu_cnt; |
846 | 0 | WORD16 *pi2_tu_coeff; |
847 | 0 | WORD32 pic_strd; |
848 | 0 | WORD32 luma_nbr_flags; |
849 | 0 | WORD32 luma_nbr_flags_4x4[4] = { 0 }; |
850 | 0 | WORD32 chroma_nbr_flags = 0; |
851 | 0 | WORD32 chroma_nbr_flags_subtu = 0; |
852 | 0 | WORD32 disable_boundary_filter = 0; |
853 | |
|
854 | 0 | UWORD8 u1_luma_pred_mode_first_tu = 0; |
855 | | /* Pointers for generating 2d coeffs from coeff-map */ |
856 | 0 | UWORD8 *pu1_tu_coeff_data; |
857 | | /* nbr avail map for CTB */ |
858 | | /* 1st bit points to neighbor (left/top_left/bot_left) */ |
859 | | /* 1Tb starts at 2nd bit from msb of 2nd value in array, followed by number of min_tu's in that ctb */ |
860 | 0 | UWORD32 au4_intra_nbr_avail[MAX_CTB_SIZE / MIN_TU_SIZE + 2 /* Top nbr + bot nbr */]; |
861 | 0 | UWORD32 top_avail_bits; |
862 | 0 | sps_t *ps_sps; |
863 | 0 | pps_t *ps_pps; |
864 | 0 | WORD32 intra_flag; |
865 | 0 | UWORD8 *pu1_pic_intra_flag; |
866 | 0 | WORD32 h_samp_factor, v_samp_factor; |
867 | 0 | WORD32 chroma_pixel_strd = 2; |
868 | 0 | PF_IQITRECON_PLANE iqitrecon_fptr = ihevcd_iquant_itrans_recon_tu_plane; |
869 | | |
870 | | /*************************************************************************/ |
871 | | /* Contanis scaling matrix offset in the following order in a 1D buffer */ |
872 | | /* Entries that are listed as UNUSED are invalid combinations where */ |
873 | | /* scaling matrix is not used. eg: 64x64 SKIP CU, 64x64 PCM CU */ |
874 | | /* Intra 4 x 4 Y, 4 x 4 U, 4 x 4 V */ |
875 | | /* Inter 4 x 4 Y, 4 x 4 U, 4 x 4 V */ |
876 | | /* Intra 8 x 8 Y, 8 x 8 U, 8 x 8 V */ |
877 | | /* Inter 8 x 8 Y, 8 x 8 U, 8 x 8 V */ |
878 | | /* Intra 16x16 Y, 16x16 U, 16x16 V */ |
879 | | /* Inter 16x16 Y, 16x16 U, 16x16 V */ |
880 | | /* Intra 32x32 Y, 32x32 U, 32x32 V */ |
881 | | /* Inter 32x32 Y, 32x32 U, 32x32 V */ |
882 | | /* UNUSED, UNUSED, UNUSED */ |
883 | | /* UNUSED, UNUSED, UNUSED */ |
884 | | /*************************************************************************/ |
885 | 0 | static const WORD32 scaling_mat_offset[] = |
886 | 0 | { 0, 16, 32, 48, 64, 80, 96, 160, 224, 288, 352, 416, 480, 736, 992, |
887 | 0 | 1248, 1504, 1760, 2016, 3040, 4064, 5088, 6112, 7136, 0, 0, 0, 0, 0, 0}; |
888 | |
|
889 | 0 | PROFILE_DISABLE_IQ_IT_RECON_INTRA_PRED(); |
890 | |
|
891 | 0 | ps_sps = ps_proc->ps_sps; |
892 | 0 | ps_pps = ps_proc->ps_pps; |
893 | 0 | ps_slice_hdr = ps_proc->ps_slice_hdr; |
894 | 0 | ps_codec = ps_proc->ps_codec; |
895 | |
|
896 | 0 | pu1_y_dst_ctb = ps_proc->pu1_cur_ctb_luma; |
897 | 0 | pu1_uv_dst_ctb = ps_proc->pu1_cur_ctb_chroma; |
898 | |
|
899 | 0 | pi2_ctb_coeff = ps_proc->pi2_invscan_out; |
900 | |
|
901 | 0 | ctb_size = (1 << ps_sps->i1_log2_ctb_size); |
902 | 0 | pu1_tu_coeff_data = (UWORD8 *)ps_proc->pv_tu_coeff_data; |
903 | |
|
904 | 0 | pic_strd = ps_codec->i4_strd; |
905 | |
|
906 | 0 | pi2_tu_coeff = pi2_ctb_coeff; |
907 | |
|
908 | 0 | ps_tu = ps_proc->ps_tu; |
909 | |
|
910 | 0 | if((1 == ps_sps->i1_scaling_list_enable_flag) && (1 == ps_pps->i1_pps_scaling_list_data_present_flag)) |
911 | 0 | { |
912 | 0 | pi2_scaling_mat = ps_pps->pi2_scaling_mat; |
913 | 0 | } |
914 | 0 | else |
915 | 0 | { |
916 | 0 | pi2_scaling_mat = ps_sps->pi2_scaling_mat; |
917 | 0 | } |
918 | |
|
919 | 0 | { |
920 | | /* Updating the initial availability map */ |
921 | 0 | WORD32 i; |
922 | 0 | UWORD8 u1_left_ctb_avail, u1_top_lt_ctb_avail, u1_top_rt_ctb_avail, |
923 | 0 | u1_top_ctb_avail; |
924 | |
|
925 | 0 | u1_left_ctb_avail = ps_proc->u1_left_ctb_avail; |
926 | 0 | u1_top_lt_ctb_avail = ps_proc->u1_top_lt_ctb_avail; |
927 | 0 | u1_top_ctb_avail = ps_proc->u1_top_ctb_avail; |
928 | 0 | u1_top_rt_ctb_avail = ps_proc->u1_top_rt_ctb_avail; |
929 | | |
930 | | /* Initializing the availability array */ |
931 | 0 | memset(au4_intra_nbr_avail, 0, |
932 | 0 | (MAX_CTB_SIZE / MIN_TU_SIZE + 2) * sizeof(UWORD32)); |
933 | | /* Initializing the availability array with CTB level availability flags */ |
934 | 0 | { |
935 | 0 | WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples - (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size); |
936 | 0 | WORD32 ctb_size_left = MIN(ctb_size, rows_remaining); |
937 | 0 | for(i = 0; i < ctb_size_left / MIN_TU_SIZE; i++) |
938 | 0 | { |
939 | 0 | au4_intra_nbr_avail[i + 1] = ((UWORD32)u1_left_ctb_avail << 31); |
940 | 0 | } |
941 | 0 | } |
942 | 0 | au4_intra_nbr_avail[0] |= (((UWORD32)u1_top_rt_ctb_avail << 31) |
943 | 0 | >> (1 + ctb_size / MIN_TU_SIZE)); /* 1+ctb_size/4 position bit pos from msb */ |
944 | |
|
945 | 0 | au4_intra_nbr_avail[0] |= ((UWORD32)u1_top_lt_ctb_avail << 31); |
946 | |
|
947 | 0 | { |
948 | 0 | WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples - (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size); |
949 | 0 | WORD32 ctb_size_top = MIN(ctb_size, cols_remaining); |
950 | 0 | WORD32 shift = (31 - (ctb_size / MIN_TU_SIZE)); |
951 | | |
952 | | /* ctb_size_top gives number of valid pixels remaining in the current row */ |
953 | | /* Since we need pattern of 1's starting from the MSB, an additional shift */ |
954 | | /* is needed */ |
955 | 0 | shift += ((ctb_size - ctb_size_top) / MIN_TU_SIZE); |
956 | |
|
957 | 0 | top_avail_bits = ((1 << (ctb_size_top / MIN_TU_SIZE)) - 1) |
958 | 0 | << shift; |
959 | 0 | } |
960 | 0 | au4_intra_nbr_avail[0] |= ( |
961 | 0 | (u1_top_ctb_avail == 1) ? top_avail_bits : 0x0); |
962 | | /* Starting from msb 2nd bit to (1+ctb_size/4) bit, set 1 if top avail,or 0 */ |
963 | |
|
964 | 0 | } |
965 | |
|
966 | 0 | h_samp_factor = (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 1 : 2; |
967 | 0 | v_samp_factor = (CHROMA_FMT_IDC_YUV420 == ps_sps->i1_chroma_format_idc) ? 2 : 1; |
968 | | |
969 | | /* Applying Inverse transform on all the TU's in CTB */ |
970 | 0 | for(tu_cnt = 0; tu_cnt < ps_proc->i4_ctb_tu_cnt; tu_cnt++, ps_tu++) |
971 | 0 | { |
972 | | /* Reset boundary filter flag for each transform unit (TU) iteration */ |
973 | 0 | disable_boundary_filter = 0; |
974 | 0 | tu_plane_iq_it_recon_ctxt_t y_cb_tu = { 0 }; |
975 | 0 | tu_plane_iq_it_recon_ctxt_t cr_tu = { 0 }; |
976 | 0 | tu_plane_iq_it_recon_ctxt_t *ps_cb_tu = &y_cb_tu; |
977 | 0 | tu_plane_iq_it_recon_ctxt_t *ps_cr_tu = &cr_tu; |
978 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
979 | 0 | tu_plane_iq_it_recon_ctxt_t cb_sub_tu = { 0 }; |
980 | 0 | tu_plane_iq_it_recon_ctxt_t cr_sub_tu = { 0 }; |
981 | 0 | #endif |
982 | |
|
983 | 0 | WORD32 num_comp, c_idx, func_idx; |
984 | |
|
985 | 0 | WORD32 qp_div = 0, qp_rem = 0; |
986 | 0 | WORD32 qp_div_v = 0, qp_rem_v = 0; |
987 | 0 | WORD32 chroma_qp_idx; |
988 | 0 | WORD8 i1_chroma_pic_qp_offset, i1_chroma_slice_qp_offset; |
989 | 0 | WORD16 *pi2_dequant_matrix = NULL, *pi2_dequant_matrix_v = NULL; |
990 | |
|
991 | 0 | WORD32 trans_size = 0; |
992 | 0 | TRANSFORM_TYPE e_trans_type; |
993 | 0 | WORD32 log2_y_trans_size_minus_2, log2_uv_trans_size_minus_2; |
994 | 0 | WORD32 log2_trans_size; |
995 | |
|
996 | 0 | WORD32 tu_x, tu_y; |
997 | 0 | WORD32 tu_y_offset, tu_uv_offset; |
998 | 0 | UWORD8 u1_luma_pred_mode, u1_chroma_pred_mode; |
999 | 0 | WORD32 offset; |
1000 | 0 | WORD32 pcm_flag; |
1001 | 0 | WORD32 chroma_yuv420sp_vu = (ps_codec->e_ref_chroma_fmt == IV_YUV_420SP_VU); |
1002 | | /* If 420SP_VU is chroma format, pred and dst pointer */ |
1003 | | /* will be added +1 to point to U */ |
1004 | 0 | WORD32 chroma_yuv420sp_vu_u_offset = 1 * chroma_yuv420sp_vu; |
1005 | | /* If 420SP_VU is chroma format, pred and dst pointer */ |
1006 | | /* will be added U offset of +1 and subtracted 2 */ |
1007 | | /* to point to V */ |
1008 | 0 | WORD32 chroma_yuv420sp_vu_v_offset = -2 * chroma_yuv420sp_vu; |
1009 | |
|
1010 | 0 | tu_x = ps_tu->b4_pos_x * 4; /* Converting minTU unit to pixel unit */ |
1011 | 0 | tu_y = ps_tu->b4_pos_y * 4; /* Converting minTU unit to pixel unit */ |
1012 | 0 | { |
1013 | 0 | WORD32 tu_abs_x = (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size) + (tu_x); |
1014 | 0 | WORD32 tu_abs_y = (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size) + (tu_y); |
1015 | |
|
1016 | 0 | WORD32 numbytes_row = (ps_sps->i2_pic_width_in_luma_samples + 63) / 64; |
1017 | |
|
1018 | 0 | pu1_pic_intra_flag = ps_proc->pu1_pic_intra_flag; |
1019 | 0 | pu1_pic_intra_flag += (tu_abs_y >> 3) * numbytes_row; |
1020 | 0 | pu1_pic_intra_flag += (tu_abs_x >> 6); |
1021 | |
|
1022 | 0 | intra_flag = *pu1_pic_intra_flag; |
1023 | 0 | intra_flag &= (1 << ((tu_abs_x >> 3) % 8)); |
1024 | 0 | } |
1025 | |
|
1026 | 0 | u1_luma_pred_mode = ps_tu->b6_luma_intra_mode; |
1027 | 0 | u1_chroma_pred_mode = ps_tu->b3_chroma_intra_mode_idx; |
1028 | |
|
1029 | 0 | if(CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc && u1_chroma_pred_mode != 7) |
1030 | 0 | num_comp = 2; /* Y and UV */ |
1031 | 0 | else |
1032 | 0 | num_comp = 1; /* Y */ |
1033 | |
|
1034 | 0 | pcm_flag = 0; |
1035 | |
|
1036 | 0 | if((intra_flag) && (u1_luma_pred_mode == INTRA_PRED_NONE)) |
1037 | 0 | { |
1038 | 0 | UWORD8 *pu1_buf; |
1039 | 0 | UWORD8 *pu1_y_dst = pu1_y_dst_ctb; |
1040 | 0 | UWORD8 *pu1_uv_dst = pu1_uv_dst_ctb; |
1041 | 0 | WORD32 i, j; |
1042 | 0 | tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data; |
1043 | 0 | WORD32 cb_size = 1 << (ps_tu->b3_size + 2); |
1044 | | |
1045 | | /* trans_size is used to update availability after reconstruction */ |
1046 | 0 | trans_size = cb_size; |
1047 | |
|
1048 | 0 | pcm_flag = 1; |
1049 | |
|
1050 | 0 | tu_y_offset = tu_x + tu_y * pic_strd; |
1051 | 0 | pu1_y_dst += tu_x + tu_y * pic_strd; |
1052 | | |
1053 | | /* First byte points to number of coded blocks */ |
1054 | 0 | pu1_tu_coeff_data++; |
1055 | | |
1056 | | /* Next byte points to scan type */ |
1057 | 0 | pu1_tu_coeff_data++; |
1058 | |
|
1059 | 0 | ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)pu1_tu_coeff_data; |
1060 | |
|
1061 | 0 | pu1_buf = (UWORD8 *)&ps_tu_sblk_coeff_data->ai2_level[0]; |
1062 | 0 | { |
1063 | |
|
1064 | 0 | for(i = 0; i < cb_size; i++) |
1065 | 0 | { |
1066 | | //pu1_y_dst[i * pic_strd + j] = *pu1_buf++; |
1067 | 0 | memcpy(&pu1_y_dst[i * pic_strd], pu1_buf, cb_size); |
1068 | 0 | pu1_buf += cb_size; |
1069 | 0 | } |
1070 | |
|
1071 | 0 | if(ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_MONOCHROME) |
1072 | 0 | { |
1073 | 0 | WORD32 chroma_strd = (pic_strd * chroma_pixel_strd) / h_samp_factor; |
1074 | |
|
1075 | 0 | pu1_uv_dst += (tu_x * chroma_pixel_strd / h_samp_factor) |
1076 | 0 | + (tu_y * chroma_pixel_strd * pic_strd / (h_samp_factor * v_samp_factor)); |
1077 | 0 | pu1_uv_dst = pu1_uv_dst + chroma_yuv420sp_vu_u_offset; |
1078 | | |
1079 | | /* U */ |
1080 | 0 | for(i = 0; i < cb_size / v_samp_factor; i++) |
1081 | 0 | { |
1082 | 0 | for(j = 0; j < cb_size / h_samp_factor; j++) |
1083 | 0 | { |
1084 | 0 | pu1_uv_dst[i * chroma_strd + chroma_pixel_strd * j] = *pu1_buf++; |
1085 | 0 | } |
1086 | 0 | } |
1087 | |
|
1088 | 0 | pu1_uv_dst = pu1_uv_dst + 1 + chroma_yuv420sp_vu_v_offset; |
1089 | | |
1090 | | /* V */ |
1091 | 0 | for(i = 0; i < cb_size / v_samp_factor; i++) |
1092 | 0 | { |
1093 | 0 | for(j = 0; j < cb_size / h_samp_factor; j++) |
1094 | 0 | { |
1095 | 0 | pu1_uv_dst[i * chroma_strd + chroma_pixel_strd * j] = *pu1_buf++; |
1096 | 0 | } |
1097 | 0 | } |
1098 | 0 | } |
1099 | 0 | } |
1100 | |
|
1101 | 0 | pu1_tu_coeff_data = pu1_buf; |
1102 | |
|
1103 | 0 | } |
1104 | | |
1105 | | |
1106 | | |
1107 | | |
1108 | |
|
1109 | 0 | for(c_idx = 0; c_idx < num_comp; c_idx++) |
1110 | 0 | { |
1111 | 0 | if(0 == pcm_flag) |
1112 | 0 | { |
1113 | |
|
1114 | 0 | if(c_idx == 0) /* Y */ |
1115 | 0 | { |
1116 | | /* Initializing variables */ |
1117 | |
|
1118 | 0 | log2_y_trans_size_minus_2 = ps_tu->b3_size; |
1119 | 0 | trans_size = 1 << (log2_y_trans_size_minus_2 + 2); |
1120 | 0 | log2_trans_size = log2_y_trans_size_minus_2 + 2; |
1121 | |
|
1122 | 0 | tu_y_offset = tu_x + tu_y * pic_strd; |
1123 | | |
1124 | | /* Calculating scaling matrix offset */ |
1125 | 0 | offset = log2_y_trans_size_minus_2 * 6 + (!intra_flag) * 3 + c_idx; |
1126 | 0 | pi2_dequant_matrix = pi2_scaling_mat + scaling_mat_offset[offset]; |
1127 | | |
1128 | | /* 4x4 transform Luma in INTRA mode is DST */ |
1129 | 0 | if(log2_y_trans_size_minus_2 == 0 && intra_flag) |
1130 | 0 | { |
1131 | 0 | func_idx = log2_y_trans_size_minus_2; |
1132 | 0 | e_trans_type = DST_4x4; |
1133 | 0 | } |
1134 | 0 | else |
1135 | 0 | { |
1136 | 0 | func_idx = log2_y_trans_size_minus_2 + 1; |
1137 | 0 | e_trans_type = (TRANSFORM_TYPE)(log2_y_trans_size_minus_2 + 1); |
1138 | 0 | } |
1139 | |
|
1140 | 0 | qp_div = ps_tu->b7_qp / 6; |
1141 | 0 | qp_rem = ps_tu->b7_qp % 6; |
1142 | |
|
1143 | 0 | y_cb_tu.pi2_tu_coeff = pi2_tu_coeff; |
1144 | 0 | y_cb_tu.pu1_pred = pu1_y_dst_ctb + tu_y_offset; |
1145 | 0 | y_cb_tu.pu1_dst = pu1_y_dst_ctb + tu_y_offset; |
1146 | 0 | y_cb_tu.tu_coeff_stride = trans_size; |
1147 | 0 | y_cb_tu.pred_strd = pic_strd; |
1148 | 0 | y_cb_tu.dst_strd = pic_strd; |
1149 | 0 | y_cb_tu.cbf = ps_tu->b1_y_cbf; |
1150 | 0 | y_cb_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1; |
1151 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1152 | 0 | y_cb_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1; |
1153 | 0 | y_cb_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1; |
1154 | 0 | #endif |
1155 | | /* Unpacking coeffs */ |
1156 | 0 | if(1 == y_cb_tu.cbf) |
1157 | 0 | { |
1158 | 0 | pu1_tu_coeff_data = ihevcd_unpack_coeffs( |
1159 | 0 | y_cb_tu.pi2_tu_coeff, log2_y_trans_size_minus_2 + 2, |
1160 | 0 | pu1_tu_coeff_data, pi2_dequant_matrix, |
1161 | 0 | qp_rem, qp_div, e_trans_type, |
1162 | 0 | ps_tu->b1_transquant_bypass, &y_cb_tu.zero_cols, |
1163 | 0 | &y_cb_tu.zero_rows, &y_cb_tu.coeff_type, |
1164 | 0 | &y_cb_tu.coeff_value); |
1165 | 0 | } |
1166 | 0 | } |
1167 | 0 | else /* UV interleaved */ |
1168 | 0 | { |
1169 | | /* Initializing variables */ |
1170 | 0 | const WORD16 *pi2_ihevcd_chroma_qp = |
1171 | 0 | CHROMA_FMT_IDC_YUV420 != ps_sps->i1_chroma_format_idc ? |
1172 | 0 | gai2_ihevcd_chroma_qp_clip : |
1173 | 0 | gai2_ihevcd_chroma_qp_420; |
1174 | | |
1175 | | /* Chroma :If Transform size is 4x4, keep 4x4 else do transform on (trans_size/2 x trans_size/2) */ |
1176 | 0 | if(ps_tu->b3_size == 0) |
1177 | 0 | { |
1178 | 0 | log2_uv_trans_size_minus_2 = ps_tu->b3_size; |
1179 | 0 | if(CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) |
1180 | 0 | { |
1181 | 0 | tu_uv_offset = (tu_x * chroma_pixel_strd) |
1182 | 0 | + (tu_y * chroma_pixel_strd * pic_strd); |
1183 | 0 | } |
1184 | 0 | else |
1185 | 0 | { |
1186 | | /* Chroma 4x4 is present with 4th luma 4x4 block. For this case chroma postion has to be (luma pos x - 4, luma pos y - 4) */ |
1187 | 0 | tu_uv_offset = (tu_x - 4) + ((tu_y - 4) / v_samp_factor) * pic_strd; |
1188 | 0 | } |
1189 | 0 | } |
1190 | 0 | else |
1191 | 0 | { |
1192 | 0 | if(CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) |
1193 | 0 | { |
1194 | 0 | log2_uv_trans_size_minus_2 = ps_tu->b3_size; |
1195 | 0 | } |
1196 | 0 | else |
1197 | 0 | { |
1198 | 0 | log2_uv_trans_size_minus_2 = ps_tu->b3_size - 1; |
1199 | 0 | } |
1200 | 0 | tu_uv_offset = (tu_x * chroma_pixel_strd / h_samp_factor) |
1201 | 0 | + (tu_y * chroma_pixel_strd * pic_strd / (h_samp_factor * v_samp_factor)); |
1202 | 0 | } |
1203 | 0 | trans_size = 1 << (log2_uv_trans_size_minus_2 + 2); |
1204 | 0 | log2_trans_size = log2_uv_trans_size_minus_2 + 2; |
1205 | | |
1206 | | /*TODO: Add support for choosing different tables for U and V, |
1207 | | * change this to a single array to handle flat/default/custom, intra/inter, luma/chroma and various sizes |
1208 | | */ |
1209 | | /* Calculating scaling matrix offset */ |
1210 | | /* ((log2_uv_trans_size_minus_2 == 3) ? 1:3) condition check is not needed, since |
1211 | | * max uv trans size is 16x16 |
1212 | | */ |
1213 | 0 | offset = log2_uv_trans_size_minus_2 * 6 + (!intra_flag) * 3 + c_idx; |
1214 | 0 | pi2_dequant_matrix = pi2_scaling_mat + scaling_mat_offset[offset]; |
1215 | 0 | pi2_dequant_matrix_v = pi2_scaling_mat + scaling_mat_offset[offset + 1]; |
1216 | |
|
1217 | 0 | func_idx = 1 + 4 + log2_uv_trans_size_minus_2; /* DST func + Y funcs + cur func index*/ |
1218 | | |
1219 | | /* Handle error cases where 64x64 TU is signalled which results in 32x32 chroma. |
1220 | | * Limit func_idx based on allowed max chroma tu size */ |
1221 | 0 | func_idx = MIN(func_idx, (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 8 : 7); |
1222 | |
|
1223 | 0 | e_trans_type = (TRANSFORM_TYPE)(log2_uv_trans_size_minus_2 + 1); |
1224 | | /* QP for U */ |
1225 | 0 | i1_chroma_pic_qp_offset = ps_pps->i1_pic_cb_qp_offset; |
1226 | 0 | i1_chroma_slice_qp_offset = ps_slice_hdr->i1_slice_cb_qp_offset; |
1227 | |
|
1228 | 0 | chroma_qp_idx = ps_tu->b7_qp + i1_chroma_pic_qp_offset + i1_chroma_slice_qp_offset; |
1229 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1230 | 0 | if(ps_tu->b1_cu_chroma_qp_offset_flag) |
1231 | 0 | { |
1232 | 0 | chroma_qp_idx += ps_pps->i4_cb_qp_offset_list[ps_tu->b3_cu_chroma_qp_offset_idx]; |
1233 | 0 | } |
1234 | 0 | #endif |
1235 | 0 | chroma_qp_idx = CLIP3(chroma_qp_idx, 0, 57); |
1236 | 0 | qp_div = pi2_ihevcd_chroma_qp[chroma_qp_idx] / 6; |
1237 | 0 | qp_rem = pi2_ihevcd_chroma_qp[chroma_qp_idx] % 6; |
1238 | | |
1239 | | /* QP for V */ |
1240 | 0 | i1_chroma_pic_qp_offset = ps_pps->i1_pic_cr_qp_offset; |
1241 | 0 | i1_chroma_slice_qp_offset = ps_slice_hdr->i1_slice_cr_qp_offset; |
1242 | |
|
1243 | 0 | chroma_qp_idx = ps_tu->b7_qp + i1_chroma_pic_qp_offset + i1_chroma_slice_qp_offset; |
1244 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1245 | 0 | if(ps_tu->b1_cu_chroma_qp_offset_flag) |
1246 | 0 | { |
1247 | 0 | chroma_qp_idx += ps_pps->i4_cr_qp_offset_list[ps_tu->b3_cu_chroma_qp_offset_idx]; |
1248 | 0 | } |
1249 | 0 | #endif |
1250 | 0 | chroma_qp_idx = CLIP3(chroma_qp_idx, 0, 57); |
1251 | 0 | qp_div_v = pi2_ihevcd_chroma_qp[chroma_qp_idx] / 6; |
1252 | 0 | qp_rem_v = pi2_ihevcd_chroma_qp[chroma_qp_idx] % 6; |
1253 | |
|
1254 | 0 | y_cb_tu.pi2_tu_coeff = pi2_tu_coeff; |
1255 | 0 | y_cb_tu.pu1_pred = pu1_uv_dst_ctb + tu_uv_offset + chroma_yuv420sp_vu_u_offset; /* Pointing to start byte of U*/ |
1256 | 0 | y_cb_tu.pu1_dst = pu1_uv_dst_ctb + tu_uv_offset + chroma_yuv420sp_vu_u_offset; /* Pointing to start byte of U*/ |
1257 | 0 | y_cb_tu.tu_coeff_stride = trans_size; |
1258 | 0 | y_cb_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1259 | 0 | y_cb_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1260 | 0 | y_cb_tu.cbf = ps_tu->b1_cb_cbf; |
1261 | |
|
1262 | 0 | cr_tu.pi2_tu_coeff = pi2_tu_coeff + trans_size * trans_size; |
1263 | 0 | cr_tu.pu1_pred = y_cb_tu.pu1_pred + 1 + chroma_yuv420sp_vu_v_offset; /* Pointing to start byte of V*/ |
1264 | 0 | cr_tu.pu1_dst = y_cb_tu.pu1_dst + 1 + chroma_yuv420sp_vu_v_offset; /* Pointing to start byte of V*/ |
1265 | 0 | cr_tu.tu_coeff_stride = trans_size; |
1266 | 0 | cr_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1267 | 0 | cr_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1268 | 0 | cr_tu.cbf = ps_tu->b1_cr_cbf; |
1269 | | |
1270 | | /* Unpacking coeffs */ |
1271 | 0 | y_cb_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1; |
1272 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1273 | 0 | y_cb_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1; |
1274 | 0 | y_cb_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1; |
1275 | 0 | #endif |
1276 | 0 | if(1 == y_cb_tu.cbf) |
1277 | 0 | { |
1278 | 0 | pu1_tu_coeff_data = ihevcd_unpack_coeffs( |
1279 | 0 | y_cb_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2, |
1280 | 0 | pu1_tu_coeff_data, pi2_dequant_matrix, |
1281 | 0 | qp_rem, qp_div, e_trans_type, |
1282 | 0 | ps_tu->b1_transquant_bypass, &y_cb_tu.zero_cols, |
1283 | 0 | &y_cb_tu.zero_rows, &y_cb_tu.coeff_type, |
1284 | 0 | &y_cb_tu.coeff_value); |
1285 | 0 | } |
1286 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1287 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422) |
1288 | 0 | { |
1289 | 0 | cb_sub_tu.pi2_tu_coeff = ps_proc->pi2_invscan_out_subtu; |
1290 | 0 | cb_sub_tu.pu1_pred = y_cb_tu.pu1_pred + trans_size * y_cb_tu.pred_strd; |
1291 | 0 | cb_sub_tu.pu1_dst = y_cb_tu.pu1_dst + trans_size * y_cb_tu.dst_strd; |
1292 | 0 | cb_sub_tu.tu_coeff_stride = trans_size; |
1293 | 0 | cb_sub_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1294 | 0 | cb_sub_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1295 | 0 | cb_sub_tu.cbf = ps_tu->b1_cb_cbf_subtu1; |
1296 | 0 | cb_sub_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1; |
1297 | 0 | cb_sub_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1; |
1298 | 0 | cb_sub_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1; |
1299 | 0 | if(1 == cb_sub_tu.cbf) |
1300 | 0 | { |
1301 | 0 | pu1_tu_coeff_data = ihevcd_unpack_coeffs( |
1302 | 0 | cb_sub_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2, |
1303 | 0 | pu1_tu_coeff_data, pi2_dequant_matrix, |
1304 | 0 | qp_rem, qp_div, e_trans_type, |
1305 | 0 | ps_tu->b1_transquant_bypass, &cb_sub_tu.zero_cols, |
1306 | 0 | &cb_sub_tu.zero_rows, &cb_sub_tu.coeff_type, |
1307 | 0 | &cb_sub_tu.coeff_value); |
1308 | 0 | } |
1309 | 0 | } |
1310 | 0 | #endif |
1311 | |
|
1312 | 0 | cr_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1; |
1313 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1314 | 0 | cr_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1; |
1315 | 0 | cr_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1; |
1316 | 0 | #endif |
1317 | 0 | if(1 == cr_tu.cbf) |
1318 | 0 | { |
1319 | 0 | pu1_tu_coeff_data = ihevcd_unpack_coeffs( |
1320 | 0 | cr_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2, |
1321 | 0 | pu1_tu_coeff_data, pi2_dequant_matrix_v, |
1322 | 0 | qp_rem_v, qp_div_v, e_trans_type, |
1323 | 0 | ps_tu->b1_transquant_bypass, &cr_tu.zero_cols, |
1324 | 0 | &cr_tu.zero_rows, &cr_tu.coeff_type, &cr_tu.coeff_value); |
1325 | 0 | } |
1326 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1327 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422) |
1328 | 0 | { |
1329 | 0 | cr_sub_tu.pi2_tu_coeff = ps_proc->pi2_invscan_out_subtu + trans_size * trans_size; |
1330 | 0 | cr_sub_tu.pu1_pred = cr_tu.pu1_pred + trans_size * cr_tu.pred_strd; |
1331 | 0 | cr_sub_tu.pu1_dst = cr_tu.pu1_dst + trans_size * cr_tu.dst_strd; |
1332 | 0 | cr_sub_tu.tu_coeff_stride = trans_size; |
1333 | 0 | cr_sub_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1334 | 0 | cr_sub_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor; |
1335 | 0 | cr_sub_tu.cbf = ps_tu->b1_cr_cbf_subtu1; |
1336 | 0 | cr_sub_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1; |
1337 | 0 | cr_sub_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1; |
1338 | 0 | cr_sub_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1; |
1339 | 0 | if(1 == cr_sub_tu.cbf) |
1340 | 0 | { |
1341 | 0 | pu1_tu_coeff_data = ihevcd_unpack_coeffs( |
1342 | 0 | cr_sub_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2, |
1343 | 0 | pu1_tu_coeff_data, pi2_dequant_matrix_v, |
1344 | 0 | qp_rem_v, qp_div_v, e_trans_type, |
1345 | 0 | ps_tu->b1_transquant_bypass, &cr_sub_tu.zero_cols, |
1346 | 0 | &cr_sub_tu.zero_rows, &cr_sub_tu.coeff_type, |
1347 | 0 | &cr_sub_tu.coeff_value); |
1348 | 0 | } |
1349 | 0 | } |
1350 | 0 | #endif |
1351 | 0 | } |
1352 | 0 | WORD8 subtu_idx = 0; |
1353 | 0 | do |
1354 | 0 | { |
1355 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1356 | 0 | if(subtu_idx != 0 && c_idx != 0) |
1357 | 0 | { |
1358 | 0 | ps_cb_tu = &cb_sub_tu; |
1359 | 0 | ps_cr_tu = &cr_sub_tu; |
1360 | 0 | chroma_nbr_flags = chroma_nbr_flags_subtu; |
1361 | 0 | } |
1362 | 0 | #endif |
1363 | | /***************************************************************/ |
1364 | | /****************** Intra Prediction **************************/ |
1365 | | /***************************************************************/ |
1366 | 0 | if(intra_flag) /* Intra */ |
1367 | 0 | { |
1368 | | /* While (MAX_TU_SIZE * 2 * 2) + 1 is the actaul size needed, |
1369 | | au1_ref_sub_out size is kept as multiple of 8, |
1370 | | so that SIMD functions can load 64 bits. Also some SIMD |
1371 | | modules read few bytes before the start of the array, so |
1372 | | allocate 16 extra bytes at the start */ |
1373 | 0 | UWORD8 au1_ref_sub_out[16 + (MAX_TU_SIZE * 2 * 2 * 2) + 8] = {0}; |
1374 | 0 | UWORD8 *pu1_ref_sub_out = &au1_ref_sub_out[16]; |
1375 | 0 | UWORD8 *pu1_top_left, *pu1_top, *pu1_left; |
1376 | 0 | WORD32 luma_pred_func_idx, chroma_pred_func_idx; |
1377 | | |
1378 | | /* Get the neighbour availability flags */ |
1379 | | /* Done for only Y */ |
1380 | 0 | if(c_idx == 0) |
1381 | 0 | { |
1382 | | /* Get neighbor availability for Y only */ |
1383 | 0 | luma_nbr_flags = ihevcd_get_intra_nbr_flag(ps_proc, |
1384 | 0 | ps_tu, |
1385 | 0 | au4_intra_nbr_avail, |
1386 | 0 | ps_sps->i2_pic_width_in_luma_samples, |
1387 | 0 | ps_pps->i1_constrained_intra_pred_flag, |
1388 | 0 | trans_size, |
1389 | 0 | ctb_size); |
1390 | |
|
1391 | 0 | if(trans_size == 4) |
1392 | 0 | luma_nbr_flags_4x4[(ps_tu->b4_pos_x % 2) + (ps_tu->b4_pos_y % 2) * 2] = luma_nbr_flags; |
1393 | |
|
1394 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444) |
1395 | 0 | { |
1396 | 0 | chroma_nbr_flags = luma_nbr_flags; |
1397 | 0 | } |
1398 | 0 | else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422) |
1399 | 0 | { |
1400 | | /* |
1401 | | * Neighbor Bitfield Layout in libhevc (17 bits): |
1402 | | * Bit 16: Top-Left (TL) |
1403 | | * Bits 15..12: Top-Right (TR) - 4 chunks of 8px (Bits 12, 13, 14, 15) |
1404 | | * Bits 11..8: Top (T) - 4 chunks of 8px (Bits 8, 9, 10, 11) |
1405 | | * Bits 7..4: Left (L) - 4 chunks of 8px (Bits 7, 6, 5, 4) |
1406 | | * Bits 3..0: Bottom-Left (BL) - 4 chunks of 8px (Bits 3, 2, 1, 0) |
1407 | | * |
1408 | | * Mapping Rules for 4:2:2: |
1409 | | * 1. Sub-TU 0 (Upper (trans_size/2) x (trans_size/2)): |
1410 | | * - Left: Upper half of parent Luma Left boundary. |
1411 | | * - Bottom-Left: Lower half of parent Luma Left boundary. |
1412 | | * 2. Sub-TU 1 (Lower (trans_size/2) x (trans_size/2)): |
1413 | | * - Top-Left: Bottom pixel of Sub-TU 0 Left boundary. |
1414 | | * - Top: Always available from reconstructed bottom row of Sub-TU 0. |
1415 | | * - Top-Right: 0 (not yet decoded in Z-scan order; padded by substitution). |
1416 | | * - Left: Lower half of parent Luma Left boundary. |
1417 | | * - Bottom-Left: Parent Luma Bottom-Left boundary. |
1418 | | */ |
1419 | 0 | WORD32 tp_left = (luma_nbr_flags & 0x10000); |
1420 | |
|
1421 | 0 | switch (trans_size) |
1422 | 0 | { |
1423 | 0 | case 8: |
1424 | 0 | { |
1425 | | /* Luma 8x8 -> Two 4x4 Chroma Sub-TUs (1 chunk of 4/8px per edge) */ |
1426 | 0 | WORD32 chroma_Left = (luma_nbr_flags & 0x80); |
1427 | 0 | WORD32 chroma_BL = (luma_nbr_flags & 0x80) ? 0x8 : 0; |
1428 | 0 | chroma_nbr_flags = tp_left | (luma_nbr_flags & 0x1000) | (luma_nbr_flags & 0x100) | chroma_Left | chroma_BL; |
1429 | |
|
1430 | 0 | WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x80) ? 0x10000 : 0; |
1431 | 0 | WORD32 chroma_Left_subtu = (luma_nbr_flags & 0x80); |
1432 | 0 | WORD32 chroma_BL_subtu = (luma_nbr_flags & 0x8); |
1433 | | /* Top of Sub-TU 1 is 1 chunk (Bit 8 = 0x100) from reconstructed Sub-TU 0 */ |
1434 | 0 | chroma_nbr_flags_subtu = tp_left_subtu1 | 0x100 | chroma_Left_subtu | chroma_BL_subtu; |
1435 | 0 | } |
1436 | 0 | break; |
1437 | 0 | case 16: |
1438 | 0 | { |
1439 | | /* Luma 16x16 -> Two 8x8 Chroma Sub-TUs (1 chunk of 8px per edge) */ |
1440 | 0 | WORD32 chroma_Left = (luma_nbr_flags & 0x80) ? 0xC0 : 0; |
1441 | 0 | WORD32 chroma_BL = (luma_nbr_flags & 0x40) ? 0xC : 0; |
1442 | 0 | chroma_nbr_flags = tp_left | (luma_nbr_flags & 0x3000) | (luma_nbr_flags & 0x300) | chroma_Left | chroma_BL; |
1443 | |
|
1444 | 0 | WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x80) ? 0x10000 : 0; |
1445 | 0 | WORD32 chroma_Left_subtu = (luma_nbr_flags & 0x40) ? 0xC0 : 0; |
1446 | 0 | WORD32 chroma_BL_subtu = (luma_nbr_flags & 0x8) ? 0xC : 0; |
1447 | | /* Top of Sub-TU 1 is 2 chunks (Bits 8,9 = 0x300) from reconstructed Sub-TU 0 */ |
1448 | 0 | chroma_nbr_flags_subtu = tp_left_subtu1 | 0x300 | chroma_Left_subtu | chroma_BL_subtu; |
1449 | 0 | } |
1450 | 0 | break; |
1451 | 0 | case 32: |
1452 | 0 | { |
1453 | | /* Luma 32x32 -> Two 16x16 Chroma Sub-TUs (2 chunks of 8px per edge) */ |
1454 | 0 | WORD32 chroma_Left = ((luma_nbr_flags & 0x80) ? 0xC0 : 0) | ((luma_nbr_flags & 0x40) ? 0x30 : 0); |
1455 | 0 | WORD32 chroma_BL = ((luma_nbr_flags & 0x20) ? 0xC : 0) | ((luma_nbr_flags & 0x10) ? 0x3 : 0); |
1456 | 0 | chroma_nbr_flags = tp_left | (luma_nbr_flags & 0xF000) | (luma_nbr_flags & 0xF00) | chroma_Left | chroma_BL; |
1457 | |
|
1458 | 0 | WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x40) ? 0x10000 : 0; |
1459 | 0 | WORD32 chroma_Left_subtu = ((luma_nbr_flags & 0x20) ? 0xC0 : 0) | ((luma_nbr_flags & 0x10) ? 0x30 : 0); |
1460 | 0 | WORD32 chroma_BL_subtu = ((luma_nbr_flags & 0x8) ? 0xC : 0) | ((luma_nbr_flags & 0x4) ? 0x3 : 0); |
1461 | | /* Top of Sub-TU 1 is 4 chunks (Bits 8..11 = 0xF00) from reconstructed Sub-TU 0 */ |
1462 | 0 | chroma_nbr_flags_subtu = tp_left_subtu1 | 0xF00 | chroma_Left_subtu | chroma_BL_subtu; |
1463 | 0 | } |
1464 | 0 | break; |
1465 | 0 | default: |
1466 | 0 | chroma_nbr_flags = (luma_nbr_flags & 0x1ff00) | (luma_nbr_flags & 0xf0) | ((luma_nbr_flags & 0xf0) >> 4); |
1467 | 0 | chroma_nbr_flags_subtu = (((luma_nbr_flags & 0xf0) != 0 ? 1 : 0) << 16) | (0xf << 8) | (luma_nbr_flags & 0xff); |
1468 | 0 | break; |
1469 | 0 | } |
1470 | 0 | } |
1471 | 0 | else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420) |
1472 | 0 | { |
1473 | 0 | if(((ps_tu->b4_pos_x % 2 == 0) && (ps_tu->b4_pos_y % 2 == 0))) |
1474 | 0 | chroma_nbr_flags = luma_nbr_flags; |
1475 | 0 | } |
1476 | | |
1477 | | /* Initializing nbr pointers */ |
1478 | 0 | pu1_top = y_cb_tu.pu1_pred - pic_strd; |
1479 | 0 | pu1_left = y_cb_tu.pu1_pred - 1; |
1480 | 0 | pu1_top_left = y_cb_tu.pu1_pred - pic_strd - 1; |
1481 | | |
1482 | | /* call reference array substitution */ |
1483 | 0 | if(luma_nbr_flags == 0x1ffff) |
1484 | 0 | ps_codec->s_func_selector.ihevc_intra_pred_luma_ref_subst_all_avlble_fptr( |
1485 | 0 | pu1_top_left, |
1486 | 0 | pu1_top, pu1_left, y_cb_tu.pred_strd, trans_size, luma_nbr_flags, pu1_ref_sub_out, 1); |
1487 | 0 | else |
1488 | 0 | ps_codec->s_func_selector.ihevc_intra_pred_luma_ref_substitution_fptr( |
1489 | 0 | pu1_top_left, |
1490 | 0 | pu1_top, pu1_left, y_cb_tu.pred_strd, trans_size, luma_nbr_flags, pu1_ref_sub_out, 1); |
1491 | | |
1492 | | /* call reference filtering */ |
1493 | 0 | ps_codec->s_func_selector.ihevc_intra_pred_ref_filtering_fptr( |
1494 | 0 | pu1_ref_sub_out, |
1495 | 0 | trans_size, |
1496 | 0 | pu1_ref_sub_out, |
1497 | 0 | u1_luma_pred_mode, |
1498 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1499 | 0 | (ps_sps->i1_intra_smoothing_disabled_flag << 3 |
1500 | 0 | | ps_sps->i1_strong_intra_smoothing_enable_flag) |
1501 | | #else |
1502 | | ps_sps->i1_strong_intra_smoothing_enable_flag |
1503 | | #endif |
1504 | 0 | ); |
1505 | | |
1506 | | /* use the look up to get the function idx */ |
1507 | 0 | luma_pred_func_idx = g_i4_ip_funcs[u1_luma_pred_mode]; |
1508 | |
|
1509 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1510 | 0 | if(ps_sps->i1_implicit_rdpcm_enabled_flag && ps_tu->b1_transquant_bypass |
1511 | 0 | && (u1_luma_pred_mode == 10 || u1_luma_pred_mode == 26)) |
1512 | 0 | disable_boundary_filter = 1; |
1513 | 0 | #endif |
1514 | | /* call the intra prediction function */ |
1515 | 0 | ps_codec->apf_intra_pred_luma[luma_pred_func_idx]( |
1516 | 0 | pu1_ref_sub_out, 1, |
1517 | 0 | y_cb_tu.pu1_pred, |
1518 | 0 | y_cb_tu.pred_strd, |
1519 | 0 | trans_size, |
1520 | 0 | (u1_luma_pred_mode == 10 || u1_luma_pred_mode == 26) ? |
1521 | 0 | disable_boundary_filter : |
1522 | 0 | u1_luma_pred_mode |
1523 | 0 | ); |
1524 | 0 | } |
1525 | 0 | else |
1526 | 0 | { |
1527 | | /* In case of yuv420sp_vu, prediction happens as usual. */ |
1528 | | /* So point the pu1_pred pointer to original prediction pointer */ |
1529 | 0 | UWORD8 *pu1_pred_orig = ps_cb_tu->pu1_pred - chroma_yuv420sp_vu_u_offset; |
1530 | | |
1531 | | /* Top-Left | Top-Right | Top | Left | Bottom-Left |
1532 | | * 1 4 4 4 4 |
1533 | | * |
1534 | | * Generating chroma_nbr_flags depending upon the transform size */ |
1535 | 0 | if(ps_tu->b3_size == 0) |
1536 | 0 | { |
1537 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420) |
1538 | 0 | { |
1539 | | /* Take TL,T,L flags of First luma 4x4 block */ |
1540 | 0 | chroma_nbr_flags = (luma_nbr_flags_4x4[0] & 0x10FF0); |
1541 | | /* Take TR flags of Second luma 4x4 block */ |
1542 | 0 | chroma_nbr_flags |= (luma_nbr_flags_4x4[1] & 0x0F000); |
1543 | | /* Take BL flags of Third luma 4x4 block */ |
1544 | 0 | chroma_nbr_flags |= (luma_nbr_flags_4x4[2] & 0x0000F); |
1545 | 0 | } |
1546 | 0 | else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422) |
1547 | 0 | { |
1548 | 0 | if(subtu_idx == 0) |
1549 | 0 | { |
1550 | | /* Take TL,T,L flags of First luma 4x4 block */ |
1551 | 0 | chroma_nbr_flags = (luma_nbr_flags_4x4[0] & 0x10FF0); |
1552 | | /* Take TR flags of Second luma 4x4 block */ |
1553 | 0 | chroma_nbr_flags |= (luma_nbr_flags_4x4[1] & 0x0F000); |
1554 | | /* Take BL flags of first luma 4x4 block */ |
1555 | 0 | chroma_nbr_flags |= (luma_nbr_flags_4x4[0] & 0x0000F); |
1556 | 0 | } |
1557 | 0 | else |
1558 | 0 | { |
1559 | | /* Take TL,T,L flags of Third luma 4x4 block */ |
1560 | 0 | chroma_nbr_flags = (luma_nbr_flags_4x4[2] & 0x10FF0); |
1561 | | /* Take BL flags of Third luma 4x4 block */ |
1562 | 0 | chroma_nbr_flags |= (luma_nbr_flags_4x4[2] & 0x0000F); |
1563 | 0 | } |
1564 | 0 | } |
1565 | 0 | } |
1566 | | |
1567 | | /* Initializing nbr pointers */ |
1568 | 0 | pu1_top = pu1_pred_orig - (pic_strd * chroma_pixel_strd / h_samp_factor); |
1569 | 0 | pu1_left = pu1_pred_orig - 2; |
1570 | 0 | pu1_top_left = pu1_pred_orig - (pic_strd * chroma_pixel_strd / h_samp_factor) - 2; |
1571 | |
|
1572 | 0 | if(subtu_idx == 0) |
1573 | 0 | { |
1574 | | /* Chroma pred mode derivation from luma pred mode */ |
1575 | 0 | { |
1576 | 0 | tu_t *ps_tu_tmp = ps_tu; |
1577 | 0 | if(ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_YUV444) |
1578 | 0 | { |
1579 | 0 | while(!ps_tu_tmp->b1_first_tu_in_cu) |
1580 | 0 | { |
1581 | 0 | ps_tu_tmp--; |
1582 | 0 | } |
1583 | 0 | } |
1584 | 0 | u1_luma_pred_mode_first_tu = ps_tu_tmp->b6_luma_intra_mode; |
1585 | 0 | } |
1586 | 0 | if(4 == u1_chroma_pred_mode) |
1587 | 0 | u1_chroma_pred_mode = u1_luma_pred_mode_first_tu; |
1588 | 0 | else |
1589 | 0 | { |
1590 | 0 | u1_chroma_pred_mode = gau1_intra_pred_chroma_modes[u1_chroma_pred_mode]; |
1591 | |
|
1592 | 0 | if(u1_chroma_pred_mode == u1_luma_pred_mode_first_tu) |
1593 | 0 | { |
1594 | 0 | u1_chroma_pred_mode = INTRA_ANGULAR(34); |
1595 | 0 | } |
1596 | 0 | } |
1597 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422) |
1598 | 0 | { |
1599 | 0 | u1_chroma_pred_mode = gau1_intra_pred_chroma_modes_422[u1_chroma_pred_mode]; |
1600 | 0 | } |
1601 | 0 | } |
1602 | | |
1603 | | /* call the chroma reference array substitution */ |
1604 | 0 | ps_codec->s_func_selector.ihevc_intra_pred_chroma_ref_substitution_fptr( |
1605 | 0 | pu1_top_left, |
1606 | 0 | pu1_top, pu1_left, |
1607 | 0 | ps_cb_tu->pred_strd, |
1608 | 0 | trans_size, chroma_nbr_flags, pu1_ref_sub_out, 1, |
1609 | 0 | ps_sps->i1_chroma_format_idc); |
1610 | |
|
1611 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1612 | | /* call reference filtering */ |
1613 | 0 | if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444) |
1614 | 0 | { |
1615 | 0 | ps_codec->s_func_selector.ihevc_intra_pred_chroma_ref_filtering_fptr( |
1616 | 0 | pu1_ref_sub_out, |
1617 | 0 | trans_size, |
1618 | 0 | pu1_ref_sub_out, |
1619 | 0 | u1_chroma_pred_mode, |
1620 | 0 | (ps_sps->i1_intra_smoothing_disabled_flag << 3 |
1621 | 0 | | ps_sps->i1_strong_intra_smoothing_enable_flag)); |
1622 | 0 | } |
1623 | 0 | #endif |
1624 | | |
1625 | | /* use the look up to get the function idx */ |
1626 | 0 | chroma_pred_func_idx = g_i4_ip_funcs[u1_chroma_pred_mode]; |
1627 | | |
1628 | | /* call the intra prediction function */ |
1629 | 0 | ps_codec->apf_intra_pred_chroma[chroma_pred_func_idx](pu1_ref_sub_out, 1, pu1_pred_orig, ps_cb_tu->pred_strd, trans_size, u1_chroma_pred_mode); |
1630 | 0 | } |
1631 | 0 | } |
1632 | | |
1633 | | /* Updating number of transform types */ |
1634 | 0 | STATS_UPDATE_ALL_TRANS(e_trans_type, c_idx); |
1635 | |
|
1636 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1637 | 0 | iqitrecon_fptr = get_iqitrec_func( |
1638 | 0 | ps_proc, ps_tu, ps_cb_tu, log2_trans_size, |
1639 | 0 | c_idx != 0 ? U_PLANE : NULL_PLANE, intra_flag, |
1640 | 0 | c_idx == 0 ? u1_luma_pred_mode : u1_chroma_pred_mode); |
1641 | 0 | #endif |
1642 | | /* IQ, IT and Recon for Y if c_idx == 0, and U if c_idx !=0 */ |
1643 | 0 | iqitrecon_fptr(ps_proc, ps_tu, ps_cb_tu, func_idx, log2_trans_size, |
1644 | 0 | c_idx != 0 ? U_PLANE : NULL_PLANE, intra_flag, |
1645 | 0 | c_idx == 0 ? u1_luma_pred_mode : u1_chroma_pred_mode); |
1646 | | /* IQ, IT and Recon for V */ |
1647 | 0 | if(c_idx != 0) |
1648 | 0 | { |
1649 | 0 | #ifdef ENABLE_MAIN_REXT_PROFILE |
1650 | 0 | iqitrecon_fptr = get_iqitrec_func(ps_proc, ps_tu, ps_cr_tu, log2_trans_size, |
1651 | 0 | V_PLANE, intra_flag, u1_chroma_pred_mode); |
1652 | 0 | #endif |
1653 | 0 | iqitrecon_fptr(ps_proc, ps_tu, ps_cr_tu, func_idx, log2_trans_size, V_PLANE, |
1654 | 0 | intra_flag, u1_chroma_pred_mode); |
1655 | 0 | } |
1656 | 0 | } |
1657 | 0 | while(c_idx != 0 && ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422 |
1658 | 0 | && ++subtu_idx < 2); |
1659 | 0 | } |
1660 | | |
1661 | | /* Neighbor availability inside CTB */ |
1662 | | /* 1bit per 4x4. Indicates whether that 4x4 block has been reconstructed(avialable) */ |
1663 | | /* Used for neighbor availability in intra pred */ |
1664 | 0 | if(c_idx == 0) |
1665 | 0 | { |
1666 | 0 | WORD32 i; |
1667 | 0 | WORD32 trans_in_min_tu; |
1668 | 0 | UWORD32 cur_tu_in_bits; |
1669 | 0 | UWORD32 cur_tu_avail_flag; |
1670 | |
|
1671 | 0 | trans_in_min_tu = trans_size / MIN_TU_SIZE; |
1672 | 0 | cur_tu_in_bits = (1 << trans_in_min_tu) - 1; |
1673 | 0 | cur_tu_in_bits = cur_tu_in_bits << (32 - trans_in_min_tu); |
1674 | |
|
1675 | 0 | cur_tu_avail_flag = cur_tu_in_bits >> (ps_tu->b4_pos_x + 1); |
1676 | |
|
1677 | 0 | for(i = 0; i < trans_in_min_tu; i++) |
1678 | 0 | au4_intra_nbr_avail[1 + ps_tu->b4_pos_y + i] |= |
1679 | 0 | cur_tu_avail_flag; |
1680 | 0 | } |
1681 | 0 | } |
1682 | 0 | } |
1683 | 0 | ps_proc->pv_tu_coeff_data = pu1_tu_coeff_data; |
1684 | |
|
1685 | 0 | return ps_proc->i4_ctb_tu_cnt; |
1686 | 0 | } |
1687 | | |