1 /******************************************************************************
2 *
3 * Copyright (C) 2018 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 ihevce_tu_tree_selector.c
24 *
25 * \brief
26 * Functions that facilitate selection of optimal TU tree
27 *
28 * \date
29 * 20/04/2016
30 *
31 * \author
32 * Ittiam
33 *
34 ******************************************************************************
35 */
36
37 /*****************************************************************************/
38 /* File Includes */
39 /*****************************************************************************/
40 /* System include files */
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <assert.h>
45 #include <stdarg.h>
46 #include <math.h>
47 #include <limits.h>
48
49 /* User include files */
50 #include "ihevc_typedefs.h"
51 #include "itt_video_api.h"
52 #include "ihevce_api.h"
53
54 #include "rc_cntrl_param.h"
55 #include "rc_frame_info_collector.h"
56 #include "rc_look_ahead_params.h"
57
58 #include "ihevc_defs.h"
59 #include "ihevc_structs.h"
60 #include "ihevc_platform_macros.h"
61 #include "ihevc_deblk.h"
62 #include "ihevc_itrans_recon.h"
63 #include "ihevc_chroma_itrans_recon.h"
64 #include "ihevc_chroma_intra_pred.h"
65 #include "ihevc_intra_pred.h"
66 #include "ihevc_inter_pred.h"
67 #include "ihevc_mem_fns.h"
68 #include "ihevc_padding.h"
69 #include "ihevc_weighted_pred.h"
70 #include "ihevc_sao.h"
71 #include "ihevc_resi_trans.h"
72 #include "ihevc_quant_iquant_ssd.h"
73 #include "ihevc_cabac_tables.h"
74
75 #include "ihevce_defs.h"
76 #include "ihevce_lap_enc_structs.h"
77 #include "ihevce_multi_thrd_structs.h"
78 #include "ihevce_me_common_defs.h"
79 #include "ihevce_had_satd.h"
80 #include "ihevce_error_codes.h"
81 #include "ihevce_bitstream.h"
82 #include "ihevce_cabac.h"
83 #include "ihevce_rdoq_macros.h"
84 #include "ihevce_function_selector.h"
85 #include "ihevce_enc_structs.h"
86 #include "ihevce_entropy_structs.h"
87 #include "ihevce_cmn_utils_instr_set_router.h"
88 #include "ihevce_enc_loop_structs.h"
89 #include "ihevce_enc_loop_utils.h"
90 #include "ihevce_tu_tree_selector.h"
91
92 /*****************************************************************************/
93 /* Function Definitions */
94 /*****************************************************************************/
95
96 /*!
97 ******************************************************************************
98 * \if Function name : ihevce_tu_tree_coverage_in_cu \endif
99 *
100 * \brief
101 * Determination of the area within the CU that is swept by the TU tree.
102 * Input : Pointer to a node of the TU tree
103 * Output : Area covered by the current TU or its children
104 *
105 *****************************************************************************
106 */
ihevce_tu_tree_coverage_in_cu(tu_tree_node_t * ps_node)107 WORD32 ihevce_tu_tree_coverage_in_cu(tu_tree_node_t *ps_node)
108 {
109 WORD32 i4_tu_tree_area = 0;
110
111 if(ps_node->u1_is_valid_node)
112 {
113 i4_tu_tree_area += ps_node->s_luma_data.u1_size * ps_node->s_luma_data.u1_size;
114 }
115 else
116 {
117 if(NULL != ps_node->ps_child_node_tl)
118 {
119 i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tl);
120 }
121
122 if(NULL != ps_node->ps_child_node_tr)
123 {
124 i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tr);
125 }
126
127 if(NULL != ps_node->ps_child_node_bl)
128 {
129 i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_bl);
130 }
131
132 if(NULL != ps_node->ps_child_node_br)
133 {
134 i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_br);
135 }
136 }
137
138 return i4_tu_tree_area;
139 }
140
ihevce_tu_node_data_init(tu_node_data_t * ps_tu_data,UWORD8 u1_size,UWORD8 u1_posx,UWORD8 u1_posy)141 static void ihevce_tu_node_data_init(
142 tu_node_data_t *ps_tu_data, UWORD8 u1_size, UWORD8 u1_posx, UWORD8 u1_posy)
143 {
144 ps_tu_data->u1_size = u1_size;
145 ps_tu_data->i8_ssd = 0;
146 ps_tu_data->i8_cost = 0;
147 #if ENABLE_INTER_ZCU_COST
148 ps_tu_data->i8_not_coded_cost = 0;
149 #endif
150 ps_tu_data->u4_sad = 0;
151 ps_tu_data->i4_bits = 0;
152 ps_tu_data->i4_num_bytes_used_for_ecd = 0;
153 ps_tu_data->u1_cbf = 0;
154 ps_tu_data->u1_reconBufId = UCHAR_MAX;
155 ps_tu_data->u1_posx = u1_posx;
156 ps_tu_data->u1_posy = u1_posy;
157 }
158
159 /*!
160 ******************************************************************************
161 * \if Function name : ihevce_tu_node_init \endif
162 *
163 * \brief
164 * This function initialises all nodes of the TU tree from the root upto and
165 * including the nodes at the max tree depth. Only those nodes that lie
166 * within the (max + 1) and (min - 1) depths are set as valid. Everything
167 * else is invalid. The pointers to the children nodes of the leaf-most
168 * nodes in the tree are assigned NULL.
169 * Input : Pointer to root of the tree containing TU info.
170 * Output : The memory of this node and all its progeny shall be modified
171 * returns Number of nodes of the TU tree that have been modified
172 *
173 *****************************************************************************
174 */
ihevce_tu_node_init(tu_tree_node_t * ps_root,UWORD8 u1_size,UWORD8 u1_parent_posx,UWORD8 u1_parent_posy,UWORD8 u1_cur_depth,UWORD8 u1_min_tree_depth,UWORD8 u1_max_tree_depth,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422,TU_POS_T e_tu_pos)175 static UWORD16 ihevce_tu_node_init(
176 tu_tree_node_t *ps_root,
177 UWORD8 u1_size,
178 UWORD8 u1_parent_posx,
179 UWORD8 u1_parent_posy,
180 UWORD8 u1_cur_depth,
181 UWORD8 u1_min_tree_depth,
182 UWORD8 u1_max_tree_depth,
183 UWORD8 u1_chroma_processing_enabled,
184 UWORD8 u1_is_422,
185 TU_POS_T e_tu_pos)
186 {
187 tu_tree_node_t *ps_node;
188 tu_tree_node_t *ps_childNodeTL;
189 tu_tree_node_t *ps_childNodeTR;
190 tu_tree_node_t *ps_childNodeBL;
191 tu_tree_node_t *ps_childNodeBR;
192
193 UWORD8 u1_start_index_for_parent = 0;
194 UWORD8 u1_start_index_for_child = 0;
195 UWORD16 u2_parent_offset = 0;
196 UWORD16 u2_child_offset = 0;
197 UWORD8 u1_posx = 0;
198 UWORD8 u1_posy = 0;
199
200 const UWORD8 u1_nxn_tu_node_start_index = 0;
201 const UWORD8 u1_nBye2xnBye2_tu_node_start_index = 1;
202 const UWORD8 u1_nBye4xnBye4_tu_node_start_index = 1 + 4;
203 const UWORD8 u1_nBye8xnBye8_tu_node_start_index = 1 + 4 + 16;
204 const UWORD8 u1_nBye16xnBye16_tu_node_start_index = 1 + 4 + 16 + 64;
205 UWORD16 u2_num_nodes_initialised = 0;
206
207 ASSERT(u1_cur_depth <= u1_max_tree_depth);
208 ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
209
210 switch(e_tu_pos)
211 {
212 case POS_TL:
213 {
214 u1_posx = u1_parent_posx;
215 u1_posy = u1_parent_posy;
216
217 break;
218 }
219 case POS_TR:
220 {
221 u1_posx = u1_parent_posx + u1_size;
222 u1_posy = u1_parent_posy;
223
224 break;
225 }
226 case POS_BL:
227 {
228 u1_posx = u1_parent_posx;
229 u1_posy = u1_parent_posy + u1_size;
230
231 break;
232 }
233 case POS_BR:
234 {
235 u1_posx = u1_parent_posx + u1_size;
236 u1_posy = u1_parent_posy + u1_size;
237
238 break;
239 }
240 default:
241 {
242 /* Here be dragons */
243 ASSERT(0);
244 }
245 }
246
247 switch(u1_cur_depth)
248 {
249 case 0:
250 {
251 u1_start_index_for_parent = u1_nxn_tu_node_start_index;
252 u1_start_index_for_child = u1_nBye2xnBye2_tu_node_start_index;
253
254 u2_parent_offset = 0;
255 u2_child_offset = 0;
256
257 break;
258 }
259 case 1:
260 {
261 u1_start_index_for_parent = u1_nBye2xnBye2_tu_node_start_index;
262 u1_start_index_for_child = u1_nBye4xnBye4_tu_node_start_index;
263
264 u2_parent_offset = e_tu_pos;
265 u2_child_offset = 4 * u1_posx / u1_size + 8 * u1_posy / u1_size;
266
267 break;
268 }
269 case 2:
270 {
271 u1_start_index_for_parent = u1_nBye4xnBye4_tu_node_start_index;
272 u1_start_index_for_child = u1_nBye8xnBye8_tu_node_start_index;
273
274 u2_parent_offset = 2 * u1_parent_posx / u1_size + 4 * u1_parent_posy / u1_size + e_tu_pos;
275 u2_child_offset = 4 * u1_posx / u1_size + 16 * u1_posy / u1_size;
276
277 break;
278 }
279 case 3:
280 {
281 u1_start_index_for_parent = u1_nBye8xnBye8_tu_node_start_index;
282 u1_start_index_for_child = u1_nBye16xnBye16_tu_node_start_index;
283
284 u2_parent_offset = 2 * u1_parent_posx / u1_size + 8 * u1_parent_posy / u1_size + e_tu_pos;
285 u2_child_offset = 4 * u1_posx / u1_size + 32 * u1_posy / u1_size;
286
287 break;
288 }
289 case 4:
290 {
291 u1_start_index_for_parent = u1_nBye16xnBye16_tu_node_start_index;
292 u1_start_index_for_child = 0;
293
294 u2_parent_offset = 2 * u1_parent_posx / u1_size + 16 * u1_parent_posy / u1_size + e_tu_pos;
295 u2_child_offset = 0;
296
297 break;
298 }
299 default:
300 {
301 /* Here be dragons */
302 ASSERT(0);
303 }
304 }
305
306 ASSERT((u1_start_index_for_parent + u2_parent_offset) < (256 + 64 + 16 + 4 + 1));
307 ASSERT((u1_start_index_for_child + u2_child_offset + POS_BR) < (256 + 64 + 16 + 4 + 1));
308
309 ps_node = ps_root + u1_start_index_for_parent + u2_parent_offset;
310 ps_childNodeTL = ps_root + u1_start_index_for_child + u2_child_offset + POS_TL;
311 ps_childNodeTR = ps_root + u1_start_index_for_child + u2_child_offset + POS_TR;
312 ps_childNodeBL = ps_root + u1_start_index_for_child + u2_child_offset + POS_BL;
313 ps_childNodeBR = ps_root + u1_start_index_for_child + u2_child_offset + POS_BR;
314
315 ihevce_tu_node_data_init(&ps_node->s_luma_data, u1_size, u1_posx, u1_posy);
316
317 if(u1_chroma_processing_enabled)
318 {
319 UWORD8 i;
320
321 if(u1_size > 4)
322 {
323 for(i = 0; i < (u1_is_422 + 1); i++)
324 {
325 ihevce_tu_node_data_init(
326 &ps_node->as_cb_data[i],
327 u1_size / 2,
328 u1_posx / 2,
329 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size / 2);
330
331 ihevce_tu_node_data_init(
332 &ps_node->as_cr_data[i],
333 u1_size / 2,
334 u1_posx / 2,
335 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size / 2);
336 }
337 }
338 else if(POS_TL == e_tu_pos)
339 {
340 for(i = 0; i < (u1_is_422 + 1); i++)
341 {
342 ihevce_tu_node_data_init(
343 &ps_node->as_cb_data[i],
344 u1_size,
345 u1_posx / 2,
346 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
347
348 ihevce_tu_node_data_init(
349 &ps_node->as_cr_data[i],
350 u1_size,
351 u1_posx / 2,
352 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
353 }
354 }
355 else
356 {
357 for(i = 0; i < (u1_is_422 + 1); i++)
358 {
359 ihevce_tu_node_data_init(
360 &ps_node->as_cb_data[i],
361 u1_size / 2,
362 u1_posx / 2,
363 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
364
365 ihevce_tu_node_data_init(
366 &ps_node->as_cr_data[i],
367 u1_size / 2,
368 u1_posx / 2,
369 !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
370 }
371 }
372 }
373
374 if((u1_cur_depth >= u1_min_tree_depth) && (u1_cur_depth <= u1_max_tree_depth))
375 {
376 ps_node->u1_is_valid_node = 1;
377 }
378 else
379 {
380 ps_node->u1_is_valid_node = 0;
381 }
382
383 u2_num_nodes_initialised++;
384
385 if((u1_cur_depth < u1_max_tree_depth) && (u1_size > MIN_TU_SIZE))
386 {
387 ps_node->ps_child_node_tl = ps_childNodeTL;
388 ps_node->ps_child_node_tr = ps_childNodeTR;
389 ps_node->ps_child_node_bl = ps_childNodeBL;
390 ps_node->ps_child_node_br = ps_childNodeBR;
391
392 u2_num_nodes_initialised += ihevce_tu_node_init(
393 ps_root,
394 u1_size / 2,
395 ps_node->s_luma_data.u1_posx,
396 ps_node->s_luma_data.u1_posy,
397 u1_cur_depth + 1,
398 u1_min_tree_depth,
399 u1_max_tree_depth,
400 u1_chroma_processing_enabled,
401 u1_is_422,
402 POS_TL);
403
404 u2_num_nodes_initialised += ihevce_tu_node_init(
405 ps_root,
406 u1_size / 2,
407 ps_node->s_luma_data.u1_posx,
408 ps_node->s_luma_data.u1_posy,
409 u1_cur_depth + 1,
410 u1_min_tree_depth,
411 u1_max_tree_depth,
412 u1_chroma_processing_enabled,
413 u1_is_422,
414 POS_TR);
415
416 u2_num_nodes_initialised += ihevce_tu_node_init(
417 ps_root,
418 u1_size / 2,
419 ps_node->s_luma_data.u1_posx,
420 ps_node->s_luma_data.u1_posy,
421 u1_cur_depth + 1,
422 u1_min_tree_depth,
423 u1_max_tree_depth,
424 u1_chroma_processing_enabled,
425 u1_is_422,
426 POS_BL);
427
428 u2_num_nodes_initialised += ihevce_tu_node_init(
429 ps_root,
430 u1_size / 2,
431 ps_node->s_luma_data.u1_posx,
432 ps_node->s_luma_data.u1_posy,
433 u1_cur_depth + 1,
434 u1_min_tree_depth,
435 u1_max_tree_depth,
436 u1_chroma_processing_enabled,
437 u1_is_422,
438 POS_BR);
439 }
440 else
441 {
442 ps_node->ps_child_node_tl = NULL;
443 ps_node->ps_child_node_tr = NULL;
444 ps_node->ps_child_node_bl = NULL;
445 ps_node->ps_child_node_br = NULL;
446 }
447
448 return u2_num_nodes_initialised;
449 }
450
451 /*!
452 ******************************************************************************
453 * \if Function name : ihevce_tu_tree_init \endif
454 *
455 * \brief
456 * Initialises all relevant data within all nodes for a specified TU tree
457 * Input : Pointer to root of the tree containing TU info.
458 * Output : Returns the number of nodes initialised
459 *
460 *****************************************************************************
461 */
ihevce_tu_tree_init(tu_tree_node_t * ps_root,UWORD8 u1_cu_size,UWORD8 u1_min_tree_depth,UWORD8 u1_max_tree_depth,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422)462 UWORD16 ihevce_tu_tree_init(
463 tu_tree_node_t *ps_root,
464 UWORD8 u1_cu_size,
465 UWORD8 u1_min_tree_depth,
466 UWORD8 u1_max_tree_depth,
467 UWORD8 u1_chroma_processing_enabled,
468 UWORD8 u1_is_422)
469 {
470 UWORD16 u2_num_nodes = 0;
471
472 ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
473
474 u2_num_nodes += ihevce_tu_node_init(
475 ps_root,
476 u1_cu_size,
477 0,
478 0,
479 0,
480 u1_min_tree_depth,
481 u1_max_tree_depth,
482 u1_chroma_processing_enabled,
483 u1_is_422,
484 POS_TL);
485
486 return u2_num_nodes;
487 }
488
489 /*!
490 ******************************************************************************
491 * \if Function name : ihevce_cabac_bins2Bits_converter_and_state_updater \endif
492 *
493 * \brief
494 * cabac bin to bits converter
495 * Input : 1. Pointer to buffer which stores the current CABAC state. This
496 * buffer shall be modified by this function. 2. Index to the cabac state
497 * that corresponds to the bin. 3. bin value
498 * Output : Number of bits required to encode the bin
499 *
500 *****************************************************************************
501 */
ihevce_cabac_bins2Bits_converter_and_state_updater(UWORD8 * pu1_cabac_ctxt,UWORD8 u1_cabac_state_idx,UWORD8 u1_bin_value)502 static INLINE UWORD32 ihevce_cabac_bins2Bits_converter_and_state_updater(
503 UWORD8 *pu1_cabac_ctxt, UWORD8 u1_cabac_state_idx, UWORD8 u1_bin_value)
504 {
505 UWORD32 u4_bits = 0;
506
507 u4_bits += gau2_ihevce_cabac_bin_to_bits[pu1_cabac_ctxt[u1_cabac_state_idx] ^ u1_bin_value];
508 pu1_cabac_ctxt[u1_cabac_state_idx] =
509 gau1_ihevc_next_state[(pu1_cabac_ctxt[u1_cabac_state_idx] << 1) | u1_bin_value];
510
511 return u4_bits;
512 }
513
514 static tu_tree_node_t *
ihevce_tu_node_parent_finder(tu_tree_node_t * ps_root,tu_tree_node_t * ps_leaf)515 ihevce_tu_node_parent_finder(tu_tree_node_t *ps_root, tu_tree_node_t *ps_leaf)
516 {
517 UWORD8 u1_depth_of_leaf;
518
519 GETRANGE(u1_depth_of_leaf, ps_root->s_luma_data.u1_size / ps_leaf->s_luma_data.u1_size);
520 u1_depth_of_leaf--;
521
522 if(0 == u1_depth_of_leaf)
523 {
524 return NULL;
525 }
526 else if(1 == u1_depth_of_leaf)
527 {
528 return ps_root;
529 }
530 else
531 {
532 UWORD8 u1_switch_conditional =
533 (ps_leaf->s_luma_data.u1_posx >= ps_root->ps_child_node_tl->s_luma_data.u1_size) +
534 (ps_leaf->s_luma_data.u1_posy >= ps_root->ps_child_node_tl->s_luma_data.u1_size) * 2;
535
536 ASSERT(NULL != ps_root->ps_child_node_tl);
537 ASSERT(NULL != ps_root->ps_child_node_tr);
538 ASSERT(NULL != ps_root->ps_child_node_bl);
539 ASSERT(NULL != ps_root->ps_child_node_br);
540
541 switch(u1_switch_conditional)
542 {
543 case 0:
544 {
545 return ihevce_tu_node_parent_finder(ps_root->ps_child_node_tl, ps_leaf);
546 }
547 case 1:
548 {
549 return ihevce_tu_node_parent_finder(ps_root->ps_child_node_tr, ps_leaf);
550 }
551 case 2:
552 {
553 return ihevce_tu_node_parent_finder(ps_root->ps_child_node_bl, ps_leaf);
554 }
555 case 3:
556 {
557 return ihevce_tu_node_parent_finder(ps_root->ps_child_node_br, ps_leaf);
558 }
559 }
560 }
561
562 return NULL;
563 }
564
565 /*!
566 ******************************************************************************
567 * \if Function name : ihevce_compute_bits_for_TUSplit_and_cbf \endif
568 *
569 * \notes
570 * 1. This function ought to be called before the call to 'ihevce_tu_tree_selector'
571 * of children TU's in order to determine bits to encode splitFlag as 1.
572 * This should also be called at the end of 'ihevce_tu_processor' in order
573 * to determine bits required to encode cbf and splitFlag.
574 * 2. When 'ENABLE_TOP_DOWN_TU_RECURSION' = 0 and 'INCLUDE_CHROMA_DURING_TU_RECURSION' = 1,
575 * it shall be assumed that parent chroma cbf is 1.
576 * 3. When 'INCLUDE_CHROMA_DURING_TU_RECURSION' = 0, this function works as
577 * though no chroma related syntax was included in the HEVC syntax for coding
578 * the transform tree
579 * Input : 1. ps_root: Pointer to root of the tree containing TU info
580 * 2. ps_leaf: Pointer to current node of the TU tree
581 * 3. pu1_cabac_ctxt: Pointer to buffer which stores the current CABAC
582 * state. This buffer shall be modified by this function
583 * Output : Number of bits required to encode cbf and splitFlags
584 *
585 *****************************************************************************
586 */
ihevce_compute_bits_for_TUSplit_and_cbf(tu_tree_node_t * ps_root,tu_tree_node_t * ps_leaf,UWORD8 * pu1_cabac_ctxt,UWORD8 u1_max_tu_size,UWORD8 u1_min_tu_size,UWORD8 u1_cur_depth,UWORD8 u1_max_depth,UWORD8 u1_is_intra,UWORD8 u1_is_intra_nxn_pu,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422)587 static WORD32 ihevce_compute_bits_for_TUSplit_and_cbf(
588 tu_tree_node_t *ps_root,
589 tu_tree_node_t *ps_leaf,
590 UWORD8 *pu1_cabac_ctxt,
591 UWORD8 u1_max_tu_size,
592 UWORD8 u1_min_tu_size,
593 UWORD8 u1_cur_depth,
594 UWORD8 u1_max_depth,
595 UWORD8 u1_is_intra,
596 UWORD8 u1_is_intra_nxn_pu,
597 UWORD8 u1_chroma_processing_enabled,
598 UWORD8 u1_is_422)
599 {
600 UWORD8 u1_cabac_state_idx;
601 UWORD8 u1_log2_tu_size;
602
603 UWORD32 u4_num_bits = 0;
604 UWORD8 u1_tu_size = ps_leaf->s_luma_data.u1_size;
605
606 ASSERT(u1_min_tu_size >= MIN_TU_SIZE);
607 ASSERT(u1_min_tu_size <= u1_max_tu_size);
608 ASSERT(u1_max_tu_size <= MAX_TU_SIZE);
609 ASSERT(u1_tu_size >= MIN_TU_SIZE);
610 ASSERT(u1_tu_size <= MAX_TU_SIZE);
611 ASSERT(u1_cur_depth <= u1_max_depth);
612
613 GETRANGE(u1_log2_tu_size, u1_tu_size);
614
615 if((ps_root->s_luma_data.u1_size >> u1_cur_depth) == u1_tu_size)
616 {
617 if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
618 (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
619 {
620 u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
621 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
622 pu1_cabac_ctxt, u1_cabac_state_idx, 0);
623 }
624
625 if(u1_chroma_processing_enabled && (u1_tu_size > 4))
626 {
627 tu_tree_node_t *ps_parent = ihevce_tu_node_parent_finder(ps_root, ps_leaf);
628
629 u1_cabac_state_idx = IHEVC_CAB_CBCR_IDX + u1_cur_depth;
630
631 if(!u1_cur_depth || ps_parent->as_cb_data[0].u1_cbf || ps_parent->as_cb_data[1].u1_cbf)
632 {
633 if(u1_is_422)
634 {
635 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
636 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
637
638 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
639 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[1].u1_cbf);
640 }
641 else
642 {
643 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
644 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
645 }
646 }
647
648 if(!u1_cur_depth || ps_parent->as_cr_data[0].u1_cbf || ps_parent->as_cr_data[1].u1_cbf)
649 {
650 if(u1_is_422)
651 {
652 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
653 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
654
655 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
656 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[1].u1_cbf);
657 }
658 else
659 {
660 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
661 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
662 }
663 }
664 }
665
666 if(u1_is_intra || u1_cur_depth)
667 {
668 u1_cabac_state_idx = IHEVC_CAB_CBF_LUMA_IDX + !u1_cur_depth;
669 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
670 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->s_luma_data.u1_cbf);
671 }
672 }
673 else
674 {
675 if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
676 (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
677 {
678 u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
679 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
680 pu1_cabac_ctxt, u1_cabac_state_idx, 1);
681 }
682
683 if(u1_chroma_processing_enabled && (u1_tu_size > 4))
684 {
685 tu_tree_node_t *ps_parent = ihevce_tu_node_parent_finder(ps_root, ps_leaf);
686
687 u1_cabac_state_idx = IHEVC_CAB_CBCR_IDX + u1_cur_depth;
688
689 if(!u1_cur_depth || ps_parent->as_cb_data[0].u1_cbf || ps_parent->as_cb_data[1].u1_cbf)
690 {
691 if(u1_is_422 && (8 == u1_tu_size))
692 {
693 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
694 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
695
696 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
697 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[1].u1_cbf);
698 }
699 else
700 {
701 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
702 pu1_cabac_ctxt,
703 u1_cabac_state_idx,
704 ps_leaf->as_cb_data[0].u1_cbf || ps_leaf->as_cb_data[1].u1_cbf);
705 }
706 }
707
708 if(!u1_cur_depth || ps_parent->as_cr_data[0].u1_cbf || ps_parent->as_cr_data[1].u1_cbf)
709 {
710 if(u1_is_422 && (8 == u1_tu_size))
711 {
712 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
713 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
714
715 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
716 pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[1].u1_cbf);
717 }
718 else
719 {
720 u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
721 pu1_cabac_ctxt,
722 u1_cabac_state_idx,
723 ps_leaf->as_cr_data[0].u1_cbf || ps_leaf->as_cr_data[1].u1_cbf);
724 }
725 }
726 }
727 }
728
729 return u4_num_bits;
730 }
731
732 /*!
733 ******************************************************************************
734 * \if Function name : ihevce_tu_processor \endif
735 *
736 * \notes
737 * Input : 1. ps_ctxt: Pointer to enc-loop's context. Parts of this structure
738 * shall be modified by this function. They include, au1_cu_csbf,
739 * i8_cu_not_coded_cost, ai2_scratch and s_rdoq_sbh_ctxt
740 * 2. ps_node: Pointer to current node of the TU tree. This struct
741 * shall be modified by this function
742 * 3. pv_src: Pointer to buffer which stores the source
743 * 4. pv_pred: Pointer to buffer which stores the pred
744 * 5. pv_recon: Pointer to buffer which stores the recon
745 * This buffer shall be modified by this function
746 * 6. pi2_deq_data: Pointer to buffer which stores the output of IQ.
747 * This buffer shall be modified by this function
748 * 7. pu1_ecd: Pointer to buffer which stores the data output by
749 * entropy coding. This buffer shall be modified by this function
750 * 8. pu1_cabac_ctxt: Pointer to buffer which stores the current CABAC
751 * state. This buffer shall be modified by this function
752 * Output : NA
753 *
754 *****************************************************************************
755 */
ihevce_tu_processor(ihevce_enc_loop_ctxt_t * ps_ctxt,tu_tree_node_t * ps_node,buffer_data_for_tu_t * ps_buffer_data,UWORD8 * pu1_cabac_ctxt,WORD32 i4_pred_mode,WORD32 i4_alpha_stim_multiplier,UWORD8 u1_is_cu_noisy,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_compute_spatial_ssd)756 static void ihevce_tu_processor(
757 ihevce_enc_loop_ctxt_t *ps_ctxt,
758 tu_tree_node_t *ps_node,
759 buffer_data_for_tu_t *ps_buffer_data,
760 UWORD8 *pu1_cabac_ctxt,
761 WORD32 i4_pred_mode,
762 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
763 WORD32 i4_alpha_stim_multiplier,
764 UWORD8 u1_is_cu_noisy,
765 #endif
766 UWORD8 u1_chroma_processing_enabled,
767 UWORD8 u1_compute_spatial_ssd)
768 {
769 UWORD8 u1_is_recon_available;
770
771 void *pv_src = ps_buffer_data->s_src_pred_rec_buf_luma.pv_src;
772 void *pv_pred = ps_buffer_data->s_src_pred_rec_buf_luma.pv_pred;
773 void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
774 WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
775 UWORD8 *pu1_ecd = ps_buffer_data->ppu1_ecd[0];
776 WORD32 i4_src_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_src_stride;
777 WORD32 i4_pred_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_pred_stride;
778 WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
779 WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
780 UWORD8 u1_size = ps_node->s_luma_data.u1_size;
781 UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
782 UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
783 WORD32 trans_size = (64 == u1_size) ? 32 : u1_size;
784 UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
785
786 (void)pu1_cabac_ctxt;
787 {
788 pv_src = ((UWORD8 *)pv_src) + u1_posx + u1_posy * i4_src_stride;
789 pv_pred = ((UWORD8 *)pv_pred) + u1_posx + u1_posy * i4_pred_stride;
790 pv_recon = ((UWORD8 *)pv_recon) + u1_posx + u1_posy * i4_recon_stride;
791 }
792
793 pi2_deq_data += u1_posx + u1_posy * i4_deq_data_stride;
794
795 /*2 Multi- dimensinal array based on trans size of rounding factor to be added here */
796 /* arrays are for rounding factor corr. to 0-1 decision and 1-2 decision */
797 /* Currently the complete array will contain only single value*/
798 /*The rounding factor is calculated with the formula
799 Deadzone val = (((R1 - R0) * (2^(-8/3)) * lamMod) + 1)/2
800 rounding factor = (1 - DeadZone Val)
801
802 Assumption: Cabac states of All the sub-blocks in the TU are considered independent
803 */
804 if((ps_ctxt->i4_quant_rounding_level == TU_LEVEL_QUANT_ROUNDING) &&
805 (ps_node->s_luma_data.u1_posx || ps_node->s_luma_data.u1_posy))
806 {
807 double i4_lamda_modifier;
808
809 if((BSLICE == ps_ctxt->i1_slice_type) && (ps_ctxt->i4_temporal_layer_id))
810 {
811 i4_lamda_modifier = ps_ctxt->i4_lamda_modifier *
812 CLIP3((((double)(ps_ctxt->i4_cu_qp - 12)) / 6.0), 2.00, 4.00);
813 }
814 else
815 {
816 i4_lamda_modifier = ps_ctxt->i4_lamda_modifier;
817 }
818 if(ps_ctxt->i4_use_const_lamda_modifier)
819 {
820 if(ISLICE == ps_ctxt->i1_slice_type)
821 {
822 i4_lamda_modifier = ps_ctxt->f_i_pic_lamda_modifier;
823 }
824 else
825 {
826 i4_lamda_modifier = CONST_LAMDA_MOD_VAL;
827 }
828 }
829 ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3] = &ps_ctxt->i4_quant_round_tu[0][0];
830 ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3] = &ps_ctxt->i4_quant_round_tu[1][0];
831
832 memset(
833 ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3],
834 0,
835 trans_size * trans_size * sizeof(WORD32));
836 memset(
837 ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3],
838 0,
839 trans_size * trans_size * sizeof(WORD32));
840
841 ihevce_quant_rounding_factor_gen(
842 trans_size,
843 1,
844 &ps_ctxt->s_rdopt_entropy_ctxt,
845 ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3],
846 ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3],
847 i4_lamda_modifier,
848 1);
849 }
850 else
851 {
852 ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3] =
853 ps_ctxt->pi4_quant_round_factor_cu_ctb_0_1[trans_size >> 3];
854 ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3] =
855 ps_ctxt->pi4_quant_round_factor_cu_ctb_1_2[trans_size >> 3];
856 }
857
858 #if ENABLE_INTER_ZCU_COST
859 ps_ctxt->i8_cu_not_coded_cost = 0;
860 #endif
861
862 {
863 ps_node->s_luma_data.u1_cbf = ihevce_t_q_iq_ssd_scan_fxn(
864 ps_ctxt,
865 (UWORD8 *)pv_pred,
866 i4_pred_stride,
867 (UWORD8 *)pv_src,
868 i4_src_stride,
869 pi2_deq_data,
870 i4_deq_data_stride,
871 (UWORD8 *)pv_recon,
872 i4_recon_stride,
873 pu1_ecd,
874 ps_ctxt->au1_cu_csbf,
875 ps_ctxt->i4_cu_csbf_strd,
876 u1_size,
877 i4_pred_mode,
878 &ps_node->s_luma_data.i8_ssd,
879 &ps_node->s_luma_data.i4_num_bytes_used_for_ecd,
880 &ps_node->s_luma_data.i4_bits,
881 &ps_node->s_luma_data.u4_sad,
882 &ps_node->s_luma_data.i4_zero_col,
883 &ps_node->s_luma_data.i4_zero_row,
884 &u1_is_recon_available,
885 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
886 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
887 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
888 i4_alpha_stim_multiplier,
889 u1_is_cu_noisy,
890 #endif
891 u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
892 1);
893 }
894
895 #if ENABLE_INTER_ZCU_COST
896 ps_node->s_luma_data.i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
897 #endif
898
899 if(u1_compute_spatial_ssd && u1_is_recon_available)
900 {
901 ps_node->s_luma_data.u1_reconBufId = 0;
902 }
903 else
904 {
905 ps_node->s_luma_data.u1_reconBufId = UCHAR_MAX;
906 }
907
908 ps_node->s_luma_data.i8_cost =
909 ps_node->s_luma_data.i8_ssd +
910 COMPUTE_RATE_COST_CLIP30(
911 ps_node->s_luma_data.i4_bits, ps_ctxt->i8_cl_ssd_lambda_qf, LAMBDA_Q_SHIFT);
912
913 pu1_ecd += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
914
915 if(u1_chroma_processing_enabled &&
916 ((!(u1_posx % 8) && !(u1_posy % 8) && (4 == u1_size)) || (u1_size > 4)))
917 {
918 UWORD8 i;
919 void *pv_chroma_src;
920 void *pv_chroma_pred;
921 void *pv_chroma_recon;
922 WORD16 *pi2_deq_data_chroma;
923
924 WORD32 i4_chroma_src_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_src_stride;
925 WORD32 i4_chroma_pred_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_pred_stride;
926 WORD32 i4_chroma_recon_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
927 WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
928
929 /* SubTU loop */
930 for(i = 0; i < u1_is_422 + 1; i++)
931 {
932 UWORD8 u1_chroma_size = ps_node->as_cb_data[i].u1_size;
933 UWORD8 u1_chroma_posx = ps_node->as_cb_data[i].u1_posx;
934 UWORD8 u1_chroma_posy = ps_node->as_cb_data[i].u1_posy;
935
936 #if ENABLE_INTER_ZCU_COST
937 ps_ctxt->i8_cu_not_coded_cost = 0;
938 #endif
939
940 pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma + (u1_chroma_posx * 2) +
941 u1_chroma_posy * i4_deq_data_stride_chroma;
942
943 {
944 pv_chroma_src = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_src) +
945 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_src_stride;
946 pv_chroma_pred = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_pred) +
947 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_pred_stride;
948 pv_chroma_recon = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon) +
949 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_recon_stride;
950
951 ps_node->as_cb_data[i].u1_cbf = ihevce_chroma_t_q_iq_ssd_scan_fxn(
952 ps_ctxt,
953 (UWORD8 *)pv_chroma_pred,
954 i4_chroma_pred_stride,
955 (UWORD8 *)pv_chroma_src,
956 i4_chroma_src_stride,
957 pi2_deq_data_chroma,
958 i4_deq_data_stride_chroma,
959 (UWORD8 *)pv_chroma_recon,
960 i4_chroma_recon_stride,
961 pu1_ecd,
962 ps_ctxt->au1_cu_csbf,
963 ps_ctxt->i4_cu_csbf_strd,
964 u1_chroma_size,
965 SCAN_DIAG_UPRIGHT,
966 0,
967 &ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd,
968 &ps_node->as_cb_data[i].i4_bits,
969 &ps_node->as_cb_data[i].i4_zero_col,
970 &ps_node->as_cb_data[i].i4_zero_row,
971 &u1_is_recon_available,
972 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
973 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
974 &ps_node->as_cb_data[i].i8_ssd,
975 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
976 i4_alpha_stim_multiplier,
977 u1_is_cu_noisy,
978 #endif
979 i4_pred_mode == PRED_MODE_SKIP,
980 u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
981 U_PLANE);
982 }
983
984 #if ENABLE_INTER_ZCU_COST
985 ps_node->as_cb_data[i].i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
986 #endif
987
988 if(u1_compute_spatial_ssd && u1_is_recon_available)
989 {
990 ps_node->as_cb_data[i].u1_reconBufId = 0;
991 }
992 else
993 {
994 ps_node->as_cb_data[i].u1_reconBufId = UCHAR_MAX;
995 }
996
997 ps_node->as_cb_data[i].i8_cost =
998 ps_node->as_cb_data[i].i8_ssd + COMPUTE_RATE_COST_CLIP30(
999 ps_node->as_cb_data[i].i4_bits,
1000 ps_ctxt->i8_cl_ssd_lambda_chroma_qf,
1001 LAMBDA_Q_SHIFT);
1002
1003 #if WEIGH_CHROMA_COST
1004 ps_node->as_cb_data[i].i8_cost =
1005 (ps_node->as_cb_data[i].i8_cost * ps_ctxt->u4_chroma_cost_weighing_factor +
1006 (1 << (CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT - 1))) >>
1007 CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT;
1008 #endif
1009
1010 pu1_ecd += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1011 }
1012
1013 for(i = 0; i < u1_is_422 + 1; i++)
1014 {
1015 UWORD8 u1_chroma_size = ps_node->as_cr_data[i].u1_size;
1016 UWORD8 u1_chroma_posx = ps_node->as_cr_data[i].u1_posx;
1017 UWORD8 u1_chroma_posy = ps_node->as_cr_data[i].u1_posy;
1018
1019 #if ENABLE_INTER_ZCU_COST
1020 ps_ctxt->i8_cu_not_coded_cost = 0;
1021 #endif
1022
1023 pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma + u1_chroma_size +
1024 (u1_chroma_posx * 2) + u1_chroma_posy * i4_deq_data_stride_chroma;
1025
1026 {
1027 pv_chroma_src = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_src) +
1028 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_src_stride;
1029 pv_chroma_pred = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_pred) +
1030 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_pred_stride;
1031 pv_chroma_recon = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon) +
1032 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_recon_stride;
1033
1034 ps_node->as_cr_data[i].u1_cbf = ihevce_chroma_t_q_iq_ssd_scan_fxn(
1035 ps_ctxt,
1036 (UWORD8 *)pv_chroma_pred,
1037 i4_chroma_pred_stride,
1038 (UWORD8 *)pv_chroma_src,
1039 i4_chroma_src_stride,
1040 pi2_deq_data_chroma,
1041 i4_deq_data_stride_chroma,
1042 (UWORD8 *)pv_chroma_recon,
1043 i4_chroma_recon_stride,
1044 pu1_ecd,
1045 ps_ctxt->au1_cu_csbf,
1046 ps_ctxt->i4_cu_csbf_strd,
1047 u1_chroma_size,
1048 SCAN_DIAG_UPRIGHT,
1049 0,
1050 &ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd,
1051 &ps_node->as_cr_data[i].i4_bits,
1052 &ps_node->as_cr_data[i].i4_zero_col,
1053 &ps_node->as_cr_data[i].i4_zero_row,
1054 &u1_is_recon_available,
1055 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
1056 ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
1057 &ps_node->as_cr_data[i].i8_ssd,
1058 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1059 i4_alpha_stim_multiplier,
1060 u1_is_cu_noisy,
1061 #endif
1062 i4_pred_mode == PRED_MODE_SKIP,
1063 u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
1064 V_PLANE);
1065 }
1066
1067 #if ENABLE_INTER_ZCU_COST
1068 ps_node->as_cr_data[i].i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
1069 #endif
1070
1071 if(u1_compute_spatial_ssd && u1_is_recon_available)
1072 {
1073 ps_node->as_cr_data[i].u1_reconBufId = 0;
1074 }
1075 else
1076 {
1077 ps_node->as_cr_data[i].u1_reconBufId = UCHAR_MAX;
1078 }
1079
1080 ps_node->as_cr_data[i].i8_cost =
1081 ps_node->as_cr_data[i].i8_ssd + COMPUTE_RATE_COST_CLIP30(
1082 ps_node->as_cr_data[i].i4_bits,
1083 ps_ctxt->i8_cl_ssd_lambda_chroma_qf,
1084 LAMBDA_Q_SHIFT);
1085
1086 #if WEIGH_CHROMA_COST
1087 ps_node->as_cr_data[i].i8_cost =
1088 (ps_node->as_cr_data[i].i8_cost * ps_ctxt->u4_chroma_cost_weighing_factor +
1089 (1 << (CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT - 1))) >>
1090 CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT;
1091 #endif
1092
1093 pu1_ecd += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1094 }
1095 }
1096 }
1097
ihevce_nbr_data_copier(nbr_4x4_t * ps_nbr_data_buf,WORD32 i4_nbr_data_buf_stride,WORD32 i4_cu_qp,UWORD8 u1_cbf,WORD32 u1_posx,UWORD8 u1_posy,UWORD8 u1_size)1098 static INLINE void ihevce_nbr_data_copier(
1099 nbr_4x4_t *ps_nbr_data_buf,
1100 WORD32 i4_nbr_data_buf_stride,
1101 WORD32 i4_cu_qp,
1102 UWORD8 u1_cbf,
1103 WORD32 u1_posx,
1104 UWORD8 u1_posy,
1105 UWORD8 u1_size)
1106 {
1107 WORD32 i, j;
1108
1109 UWORD8 u1_num_4x4_in_tu = u1_size / 4;
1110
1111 ps_nbr_data_buf += ((u1_posx) / 4) + (u1_posy / 4) * i4_nbr_data_buf_stride;
1112
1113 for(i = 0; i < u1_num_4x4_in_tu; i++)
1114 {
1115 for(j = 0; j < u1_num_4x4_in_tu; j++)
1116 {
1117 ps_nbr_data_buf[j].b8_qp = i4_cu_qp;
1118 ps_nbr_data_buf[j].b1_y_cbf = u1_cbf;
1119 }
1120
1121 ps_nbr_data_buf += i4_nbr_data_buf_stride;
1122 }
1123 }
1124
ihevce_debriefer_when_parent_wins(tu_tree_node_t * ps_node,FT_COPY_2D * pf_copy_2d,FT_CHROMA_INTERLEAVE_2D_COPY * pf_chroma_interleave_2d_copy,nbr_4x4_t * ps_nbr_data_buf,WORD16 * pi2_deq_data_src,WORD16 * pi2_deq_data_dst,WORD16 * pi2_deq_data_src_chroma,WORD16 * pi2_deq_data_dst_chroma,void * pv_recon_src,void * pv_recon_dst,void * pv_recon_src_chroma,void * pv_recon_dst_chroma,UWORD8 * pu1_cabac_ctxt_src,UWORD8 * pu1_cabac_ctxt_dst,UWORD8 * pu1_ecd_src,UWORD8 * pu1_ecd_dst,WORD32 i4_nbr_data_buf_stride,WORD32 i4_deq_data_src_stride,WORD32 i4_deq_data_dst_stride,WORD32 i4_deq_data_src_stride_chroma,WORD32 i4_deq_data_dst_stride_chroma,WORD32 i4_recon_src_stride,WORD32 i4_recon_dst_stride,WORD32 i4_recon_src_stride_chroma,WORD32 i4_recon_dst_stride_chroma,WORD32 i4_cabac_state_table_size,WORD32 i4_cu_qp,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422,UWORD8 u1_is_hbd)1125 static INLINE void ihevce_debriefer_when_parent_wins(
1126 tu_tree_node_t *ps_node,
1127 FT_COPY_2D *pf_copy_2d,
1128 FT_CHROMA_INTERLEAVE_2D_COPY *pf_chroma_interleave_2d_copy,
1129 nbr_4x4_t *ps_nbr_data_buf,
1130 WORD16 *pi2_deq_data_src,
1131 WORD16 *pi2_deq_data_dst,
1132 WORD16 *pi2_deq_data_src_chroma,
1133 WORD16 *pi2_deq_data_dst_chroma,
1134 void *pv_recon_src,
1135 void *pv_recon_dst,
1136 void *pv_recon_src_chroma,
1137 void *pv_recon_dst_chroma,
1138 UWORD8 *pu1_cabac_ctxt_src,
1139 UWORD8 *pu1_cabac_ctxt_dst,
1140 UWORD8 *pu1_ecd_src,
1141 UWORD8 *pu1_ecd_dst,
1142 WORD32 i4_nbr_data_buf_stride,
1143 WORD32 i4_deq_data_src_stride,
1144 WORD32 i4_deq_data_dst_stride,
1145 WORD32 i4_deq_data_src_stride_chroma,
1146 WORD32 i4_deq_data_dst_stride_chroma,
1147 WORD32 i4_recon_src_stride,
1148 WORD32 i4_recon_dst_stride,
1149 WORD32 i4_recon_src_stride_chroma,
1150 WORD32 i4_recon_dst_stride_chroma,
1151 WORD32 i4_cabac_state_table_size,
1152 WORD32 i4_cu_qp,
1153 UWORD8 u1_chroma_processing_enabled,
1154 UWORD8 u1_is_422,
1155 UWORD8 u1_is_hbd)
1156 {
1157 UWORD8 i;
1158
1159 UWORD32 u4_num_ecd_bytes = 0;
1160
1161 /* Y */
1162 {
1163 UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
1164 UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
1165 UWORD8 *pu1_deq_data_dst =
1166 (UWORD8 *)(pi2_deq_data_dst + u1_posx + u1_posy * i4_deq_data_dst_stride);
1167 UWORD8 *pu1_deq_data_src =
1168 (UWORD8 *)(pi2_deq_data_src + u1_posx + u1_posy * i4_deq_data_src_stride);
1169 UWORD8 *pu1_recon_dst;
1170 UWORD8 *pu1_recon_src;
1171
1172 {
1173 pu1_recon_dst = (((UWORD8 *)pv_recon_dst) + u1_posx + u1_posy * i4_recon_dst_stride);
1174 pu1_recon_src = (((UWORD8 *)pv_recon_src) + u1_posx + u1_posy * i4_recon_src_stride);
1175 }
1176 u4_num_ecd_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1177
1178 if(ps_node->s_luma_data.u1_reconBufId != UCHAR_MAX)
1179 {
1180 pf_copy_2d(
1181 pu1_recon_dst,
1182 i4_recon_dst_stride * (u1_is_hbd + 1),
1183 pu1_recon_src,
1184 i4_recon_src_stride * (u1_is_hbd + 1),
1185 ps_node->s_luma_data.u1_size * (u1_is_hbd + 1),
1186 ps_node->s_luma_data.u1_size);
1187 }
1188 else if(ps_node->s_luma_data.u1_cbf)
1189 {
1190 pf_copy_2d(
1191 pu1_deq_data_dst,
1192 i4_deq_data_dst_stride * 2,
1193 pu1_deq_data_src,
1194 i4_deq_data_src_stride * 2,
1195 ps_node->s_luma_data.u1_size * 2,
1196 ps_node->s_luma_data.u1_size);
1197 }
1198 }
1199
1200 /* Cb */
1201 if(u1_chroma_processing_enabled)
1202 {
1203 for(i = 0; i < u1_is_422 + 1; i++)
1204 {
1205 UWORD8 u1_posx = ps_node->as_cb_data[i].u1_posx;
1206 UWORD8 u1_posy = ps_node->as_cb_data[i].u1_posy;
1207 UWORD8 *pu1_deq_data_dst =
1208 (UWORD8
1209 *)(pi2_deq_data_dst_chroma + (u1_posx * 2) + (u1_posy * i4_deq_data_dst_stride_chroma));
1210 UWORD8 *pu1_deq_data_src =
1211 (UWORD8
1212 *)(pi2_deq_data_src_chroma + (u1_posx * 2) + (u1_posy * i4_deq_data_src_stride_chroma));
1213 UWORD8 *pu1_recon_dst;
1214 UWORD8 *pu1_recon_src;
1215
1216 {
1217 pu1_recon_dst =
1218 (((UWORD8 *)pv_recon_dst_chroma) + (u1_posx * 2) +
1219 u1_posy * i4_recon_dst_stride_chroma);
1220 pu1_recon_src =
1221 (((UWORD8 *)pv_recon_src_chroma) + (u1_posx * 2) +
1222 u1_posy * i4_recon_src_stride_chroma);
1223 }
1224 u4_num_ecd_bytes += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1225
1226 if(ps_node->as_cb_data[i].u1_reconBufId != UCHAR_MAX)
1227 {
1228 {
1229 pf_chroma_interleave_2d_copy(
1230 pu1_recon_src,
1231 i4_recon_src_stride_chroma * (u1_is_hbd + 1),
1232 pu1_recon_dst,
1233 i4_recon_dst_stride_chroma * (u1_is_hbd + 1),
1234 ps_node->as_cb_data[i].u1_size * (u1_is_hbd + 1),
1235 ps_node->as_cb_data[i].u1_size,
1236 U_PLANE);
1237 }
1238 }
1239 else if(ps_node->as_cb_data[i].u1_cbf)
1240 {
1241 pf_copy_2d(
1242 pu1_deq_data_dst,
1243 i4_deq_data_dst_stride_chroma * 2,
1244 pu1_deq_data_src,
1245 i4_deq_data_src_stride_chroma * 2,
1246 ps_node->as_cb_data[i].u1_size * 2,
1247 ps_node->as_cb_data[i].u1_size);
1248 }
1249 }
1250
1251 /* Cr */
1252 for(i = 0; i < u1_is_422 + 1; i++)
1253 {
1254 UWORD8 u1_posx = ps_node->as_cr_data[i].u1_posx;
1255 UWORD8 u1_posy = ps_node->as_cr_data[i].u1_posy;
1256 UWORD8 *pu1_deq_data_dst =
1257 (UWORD8
1258 *)(pi2_deq_data_dst_chroma + ps_node->as_cr_data[i].u1_size + (u1_posx * 2) + (u1_posy * i4_deq_data_dst_stride_chroma));
1259 UWORD8 *pu1_deq_data_src =
1260 (UWORD8
1261 *)(pi2_deq_data_src_chroma + ps_node->as_cr_data[i].u1_size + (u1_posx * 2) + (u1_posy * i4_deq_data_src_stride_chroma));
1262 UWORD8 *pu1_recon_dst;
1263 UWORD8 *pu1_recon_src;
1264
1265 {
1266 pu1_recon_dst =
1267 (((UWORD8 *)pv_recon_dst_chroma) + (u1_posx * 2) +
1268 u1_posy * i4_recon_dst_stride_chroma);
1269 pu1_recon_src =
1270 (((UWORD8 *)pv_recon_src_chroma) + (u1_posx * 2) +
1271 u1_posy * i4_recon_src_stride_chroma);
1272 }
1273 u4_num_ecd_bytes += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1274
1275 if(ps_node->as_cr_data[i].u1_reconBufId != UCHAR_MAX)
1276 {
1277 {
1278 pf_chroma_interleave_2d_copy(
1279 pu1_recon_src,
1280 i4_recon_src_stride_chroma * (u1_is_hbd + 1),
1281 pu1_recon_dst,
1282 i4_recon_dst_stride_chroma * (u1_is_hbd + 1),
1283 ps_node->as_cr_data[i].u1_size * (u1_is_hbd + 1),
1284 ps_node->as_cr_data[i].u1_size,
1285 V_PLANE);
1286 }
1287 }
1288 else if(ps_node->as_cr_data[i].u1_cbf)
1289 {
1290 pf_copy_2d(
1291 pu1_deq_data_dst,
1292 i4_deq_data_dst_stride_chroma * 2,
1293 pu1_deq_data_src,
1294 i4_deq_data_src_stride_chroma * 2,
1295 ps_node->as_cr_data[i].u1_size * 2,
1296 ps_node->as_cr_data[i].u1_size);
1297 }
1298 }
1299 }
1300
1301 if(pu1_ecd_dst != pu1_ecd_src)
1302 {
1303 memmove(pu1_ecd_dst, pu1_ecd_src, u4_num_ecd_bytes);
1304 }
1305
1306 memcpy(pu1_cabac_ctxt_dst, pu1_cabac_ctxt_src, i4_cabac_state_table_size);
1307
1308 ihevce_nbr_data_copier(
1309 ps_nbr_data_buf,
1310 i4_nbr_data_buf_stride,
1311 i4_cu_qp,
1312 ps_node->s_luma_data.u1_cbf,
1313 ps_node->s_luma_data.u1_posx,
1314 ps_node->s_luma_data.u1_posy,
1315 ps_node->s_luma_data.u1_size);
1316
1317 ps_node->ps_child_node_tl = NULL;
1318 ps_node->ps_child_node_tr = NULL;
1319 ps_node->ps_child_node_bl = NULL;
1320 ps_node->ps_child_node_br = NULL;
1321 }
1322
1323 /*!
1324 ******************************************************************************
1325 * \if Function name : ihevce_ecd_buffer_pointer_updater \endif
1326 *
1327 * \brief
1328 * Updates ppu1_ecd with current pointer
1329 * Output : Number of byte positions 'pu1_ecd_buf_ptr_at_t0' is incremented by
1330 *
1331 *****************************************************************************
1332 */
ihevce_ecd_buffer_pointer_updater(tu_tree_node_t * ps_node,UWORD8 ** ppu1_ecd,UWORD8 * pu1_ecd_buf_ptr_at_t0,UWORD8 u1_parent_has_won,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422)1333 static INLINE UWORD32 ihevce_ecd_buffer_pointer_updater(
1334 tu_tree_node_t *ps_node,
1335 UWORD8 **ppu1_ecd,
1336 UWORD8 *pu1_ecd_buf_ptr_at_t0,
1337 UWORD8 u1_parent_has_won,
1338 UWORD8 u1_chroma_processing_enabled,
1339 UWORD8 u1_is_422)
1340 {
1341 UWORD8 i;
1342
1343 UWORD32 u4_num_bytes = 0;
1344
1345 if(u1_parent_has_won)
1346 {
1347 u4_num_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1348
1349 if(u1_chroma_processing_enabled)
1350 {
1351 for(i = 0; i < u1_is_422 + 1; i++)
1352 {
1353 u4_num_bytes += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1354 u4_num_bytes += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1355 }
1356 }
1357 }
1358 else
1359 {
1360 u4_num_bytes += ps_node->ps_child_node_tl->s_luma_data.i4_num_bytes_used_for_ecd;
1361 u4_num_bytes += ps_node->ps_child_node_tr->s_luma_data.i4_num_bytes_used_for_ecd;
1362 u4_num_bytes += ps_node->ps_child_node_bl->s_luma_data.i4_num_bytes_used_for_ecd;
1363 u4_num_bytes += ps_node->ps_child_node_br->s_luma_data.i4_num_bytes_used_for_ecd;
1364
1365 if(u1_chroma_processing_enabled)
1366 {
1367 for(i = 0; i < u1_is_422 + 1; i++)
1368 {
1369 u4_num_bytes += ps_node->ps_child_node_tl->as_cb_data[i].i4_num_bytes_used_for_ecd;
1370 u4_num_bytes += ps_node->ps_child_node_tl->as_cr_data[i].i4_num_bytes_used_for_ecd;
1371 u4_num_bytes += ps_node->ps_child_node_tr->as_cb_data[i].i4_num_bytes_used_for_ecd;
1372 u4_num_bytes += ps_node->ps_child_node_tr->as_cr_data[i].i4_num_bytes_used_for_ecd;
1373 u4_num_bytes += ps_node->ps_child_node_bl->as_cb_data[i].i4_num_bytes_used_for_ecd;
1374 u4_num_bytes += ps_node->ps_child_node_bl->as_cr_data[i].i4_num_bytes_used_for_ecd;
1375 u4_num_bytes += ps_node->ps_child_node_br->as_cb_data[i].i4_num_bytes_used_for_ecd;
1376 u4_num_bytes += ps_node->ps_child_node_br->as_cr_data[i].i4_num_bytes_used_for_ecd;
1377 }
1378 }
1379 }
1380
1381 ppu1_ecd[0] = pu1_ecd_buf_ptr_at_t0 + u4_num_bytes;
1382
1383 return u4_num_bytes;
1384 }
1385
ihevce_tu_node_cost_collator(tu_tree_node_t * ps_node,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422)1386 static INLINE LWORD64 ihevce_tu_node_cost_collator(
1387 tu_tree_node_t *ps_node, UWORD8 u1_chroma_processing_enabled, UWORD8 u1_is_422)
1388 {
1389 UWORD8 i;
1390
1391 LWORD64 i8_cost = 0;
1392
1393 i8_cost += ps_node->s_luma_data.i8_cost;
1394
1395 if(u1_chroma_processing_enabled)
1396 {
1397 for(i = 0; i < u1_is_422 + 1; i++)
1398 {
1399 i8_cost += ps_node->as_cb_data[i].i8_cost;
1400 i8_cost += ps_node->as_cr_data[i].i8_cost;
1401 }
1402 }
1403
1404 return i8_cost;
1405 }
1406
1407 #if !ENABLE_TOP_DOWN_TU_RECURSION
1408 /*!
1409 ******************************************************************************
1410 * \if Function name : ihevce_tu_processor \endif
1411 *
1412 * \notes
1413 * Determines RDO TU Tree using DFS. If the parent is the winner, then all
1414 * pointers to the children nodes are set to NULL
1415 * Input : 1. ps_ctxt: Pointer to enc-loop's context. Parts of this structure
1416 * shall be modified by this function. They include, au1_cu_csbf,
1417 * i8_cu_not_coded_cost, ai2_scratch, s_rdoq_sbh_ctxt,
1418 * pi4_quant_round_factor_tu_0_1, pi4_quant_round_factor_tu_1_2,
1419 * i4_quant_round_tu
1420 * 2. ps_node: Pointer to current node of the TU tree. This struct
1421 * shall be modified by this function
1422 * 3. pv_recon: Pointer to buffer which stores the recon
1423 * This buffer shall be modified by this function
1424 * 4. ps_nbr_data_buf: Pointer to struct used by succeeding CU's
1425 * during RDOPT. This buffer shall be modifie by this function
1426 * 6. pi2_deq_data: Pointer to buffer which stores the output of IQ.
1427 * This buffer shall be modified by this function
1428 * 7. pu1_ecd: Pointer to buffer which stores the data output by
1429 * entropy coding. This buffer shall be modified by this function
1430 * 8. pu1_cabac_ctxt: Pointer to buffer which stores the current CABAC
1431 * state. This buffer shall be modified by this function
1432 * Output : Cost of coding the current branch of the TU tree
1433 *
1434 *****************************************************************************
1435 */
ihevce_tu_tree_selector(ihevce_enc_loop_ctxt_t * ps_ctxt,tu_tree_node_t * ps_node,buffer_data_for_tu_t * ps_buffer_data,UWORD8 * pu1_cabac_ctxt,WORD32 i4_pred_mode,WORD32 i4_alpha_stim_multiplier,UWORD8 u1_is_cu_noisy,UWORD8 u1_cur_depth,UWORD8 u1_max_depth,UWORD8 u1_part_type,UWORD8 u1_compute_spatial_ssd)1436 LWORD64 ihevce_tu_tree_selector(
1437 ihevce_enc_loop_ctxt_t *ps_ctxt,
1438 tu_tree_node_t *ps_node,
1439 buffer_data_for_tu_t *ps_buffer_data,
1440 UWORD8 *pu1_cabac_ctxt,
1441 WORD32 i4_pred_mode,
1442 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1443 WORD32 i4_alpha_stim_multiplier,
1444 UWORD8 u1_is_cu_noisy,
1445 #endif
1446 UWORD8 u1_cur_depth,
1447 UWORD8 u1_max_depth,
1448 UWORD8 u1_part_type,
1449 UWORD8 u1_compute_spatial_ssd)
1450 {
1451 UWORD8 au1_cabac_ctxt_backup[IHEVC_CAB_CTXT_END];
1452 UWORD8 u1_are_children_available;
1453 UWORD32 u4_tuSplitFlag_and_cbf_coding_bits;
1454
1455 nbr_4x4_t *ps_nbr_data_buf = ps_buffer_data->ps_nbr_data_buf;
1456 void *pv_recon_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon;
1457 WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
1458 WORD16 *pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma;
1459 UWORD8 **ppu1_ecd = ps_buffer_data->ppu1_ecd;
1460 WORD32 i4_nbr_data_buf_stride = ps_buffer_data->i4_nbr_data_buf_stride;
1461 WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
1462 WORD32 i4_recon_stride_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
1463 WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
1464 WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
1465 UWORD8 *pu1_ecd_bPtr_backup_t1 = ppu1_ecd[0];
1466 UWORD8 *pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1467 LWORD64 i8_winning_cost = 0;
1468
1469 ASSERT(ps_node != NULL);
1470 ASSERT(
1471 !(!ps_node->u1_is_valid_node &&
1472 ((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
1473 (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br))));
1474
1475 u1_are_children_available =
1476 !((NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
1477 (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br)) &&
1478 (ps_node->s_luma_data.u1_size > MIN_TU_SIZE);
1479
1480 if(u1_are_children_available)
1481 {
1482 if(ps_node->u1_is_valid_node)
1483 {
1484 memcpy(au1_cabac_ctxt_backup, pu1_cabac_ctxt, sizeof(au1_cabac_ctxt_backup));
1485 }
1486
1487 if(i4_pred_mode != PRED_MODE_SKIP)
1488 {
1489 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1490 ps_node,
1491 ps_node->ps_child_node_tl,
1492 pu1_cabac_ctxt,
1493 MAX_TU_SIZE,
1494 MIN_TU_SIZE,
1495 0,
1496 1,
1497 i4_pred_mode == PRED_MODE_INTRA,
1498 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1499 0,
1500 0);
1501
1502 i8_winning_cost += COMPUTE_RATE_COST_CLIP30(
1503 u4_tuSplitFlag_and_cbf_coding_bits,
1504 ps_ctxt->i8_cl_ssd_lambda_qf,
1505 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1506 }
1507
1508 i8_winning_cost += ihevce_tu_tree_selector(
1509 ps_ctxt,
1510 ps_node->ps_child_node_tl,
1511 ps_buffer_data,
1512 pu1_cabac_ctxt,
1513 i4_pred_mode,
1514 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1515 i4_alpha_stim_multiplier,
1516 u1_is_cu_noisy,
1517 #endif
1518 u1_cur_depth,
1519 u1_max_depth,
1520 u1_part_type,
1521 u1_compute_spatial_ssd);
1522
1523 i8_winning_cost += ihevce_tu_tree_selector(
1524 ps_ctxt,
1525 ps_node->ps_child_node_tr,
1526 ps_buffer_data,
1527 pu1_cabac_ctxt,
1528 i4_pred_mode,
1529 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1530 i4_alpha_stim_multiplier,
1531 u1_is_cu_noisy,
1532 #endif
1533 u1_cur_depth,
1534 u1_max_depth,
1535 u1_part_type,
1536 u1_compute_spatial_ssd);
1537
1538 i8_winning_cost += ihevce_tu_tree_selector(
1539 ps_ctxt,
1540 ps_node->ps_child_node_bl,
1541 ps_buffer_data,
1542 pu1_cabac_ctxt,
1543 i4_pred_mode,
1544 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1545 i4_alpha_stim_multiplier,
1546 u1_is_cu_noisy,
1547 #endif
1548 u1_cur_depth,
1549 u1_max_depth,
1550 u1_part_type,
1551 u1_compute_spatial_ssd);
1552
1553 i8_winning_cost += ihevce_tu_tree_selector(
1554 ps_ctxt,
1555 ps_node->ps_child_node_br,
1556 ps_buffer_data,
1557 pu1_cabac_ctxt,
1558 i4_pred_mode,
1559 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1560 i4_alpha_stim_multiplier,
1561 u1_is_cu_noisy,
1562 #endif
1563 u1_cur_depth,
1564 u1_max_depth,
1565 u1_part_type,
1566 u1_compute_spatial_ssd);
1567
1568 if(ps_node->u1_is_valid_node)
1569 {
1570 WORD16 ai2_deq_data_backup[MAX_CU_SIZE * MAX_CU_SIZE];
1571 UWORD16 au2_recon_backup[MAX_CU_SIZE * MAX_CU_SIZE];
1572
1573 buffer_data_for_tu_t s_buffer_data = ps_buffer_data[0];
1574
1575 pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1576 s_buffer_data.pi2_deq_data = ai2_deq_data_backup;
1577 s_buffer_data.i4_deq_data_stride = MAX_CU_SIZE;
1578 s_buffer_data.s_src_pred_rec_buf_luma.pv_recon = au2_recon_backup;
1579 s_buffer_data.s_src_pred_rec_buf_luma.i4_recon_stride = MAX_CU_SIZE;
1580
1581 ihevce_tu_processor(
1582 ps_ctxt,
1583 ps_node,
1584 &s_buffer_data,
1585 au1_cabac_ctxt_backup,
1586 i4_pred_mode,
1587 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1588 i4_alpha_stim_multiplier,
1589 u1_is_cu_noisy,
1590 #endif
1591 0,
1592 u1_compute_spatial_ssd);
1593
1594 if(i4_pred_mode != PRED_MODE_SKIP)
1595 {
1596 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1597 ps_node,
1598 ps_node,
1599 au1_cabac_ctxt_backup,
1600 MAX_TU_SIZE,
1601 MIN_TU_SIZE,
1602 0,
1603 (u1_cur_depth == u1_max_depth) ? 0 : 1,
1604 i4_pred_mode == PRED_MODE_INTRA,
1605 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1606 0,
1607 0);
1608
1609 ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
1610 u4_tuSplitFlag_and_cbf_coding_bits,
1611 ps_ctxt->i8_cl_ssd_lambda_qf,
1612 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1613 }
1614
1615 if(ps_node->s_luma_data.i8_cost <= i8_winning_cost)
1616 {
1617 ihevce_debriefer_when_parent_wins(
1618 ps_node,
1619 ps_ctxt->s_cmn_opt_func.pf_copy_2d,
1620 ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
1621 ps_nbr_data_buf,
1622 ai2_deq_data_backup,
1623 pi2_deq_data,
1624 ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
1625 pi2_deq_data_chroma,
1626 au2_recon_backup,
1627 pv_recon_chroma,
1628 au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
1629 pv_recon_chroma,
1630 au1_cabac_ctxt_backup,
1631 pu1_cabac_ctxt,
1632 pu1_ecd_bPtr_backup_t2,
1633 pu1_ecd_bPtr_backup_t1,
1634 i4_nbr_data_buf_stride,
1635 MAX_CU_SIZE,
1636 i4_deq_data_stride,
1637 MAX_CU_SIZE,
1638 i4_deq_data_stride_chroma,
1639 MAX_CU_SIZE,
1640 i4_recon_stride,
1641 MAX_CU_SIZE,
1642 i4_recon_stride_chroma,
1643 sizeof(au1_cabac_ctxt_backup),
1644 ps_ctxt->i4_cu_qp,
1645 0,
1646 ps_ctxt->u1_chroma_array_type == 2,
1647 ps_ctxt->u1_bit_depth > 8);
1648
1649 ppu1_ecd[0] =
1650 pu1_ecd_bPtr_backup_t1 + ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1651 i8_winning_cost = ps_node->s_luma_data.i8_cost;
1652 }
1653 else
1654 {
1655 ps_node->u1_is_valid_node = 0;
1656 }
1657 }
1658 }
1659 else
1660 {
1661 ASSERT(ps_node->u1_is_valid_node);
1662
1663 ihevce_tu_processor(
1664 ps_ctxt,
1665 ps_node,
1666 ps_buffer_data,
1667 pu1_cabac_ctxt,
1668 i4_pred_mode,
1669 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1670 i4_alpha_stim_multiplier,
1671 u1_is_cu_noisy,
1672 #endif
1673 0,
1674 u1_compute_spatial_ssd);
1675
1676 if(i4_pred_mode != PRED_MODE_SKIP)
1677 {
1678 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1679 ps_node,
1680 ps_node,
1681 pu1_cabac_ctxt,
1682 MAX_TU_SIZE,
1683 MIN_TU_SIZE,
1684 0,
1685 (u1_cur_depth == u1_max_depth) ? 0 : 1,
1686 i4_pred_mode == PRED_MODE_INTRA,
1687 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1688 0,
1689 0);
1690
1691 ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
1692 u4_tuSplitFlag_and_cbf_coding_bits,
1693 ps_ctxt->i8_cl_ssd_lambda_qf,
1694 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1695 }
1696
1697 ppu1_ecd[0] = pu1_ecd_bPtr_backup_t1 + ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1698
1699 ihevce_nbr_data_copier(
1700 ps_nbr_data_buf,
1701 i4_nbr_data_buf_stride,
1702 ps_ctxt->i4_cu_qp,
1703 ps_node->s_luma_data.u1_cbf,
1704 ps_node->s_luma_data.u1_posx,
1705 ps_node->s_luma_data.u1_posy,
1706 ps_node->s_luma_data.u1_size);
1707
1708 i8_winning_cost = ps_node->s_luma_data.i8_cost;
1709 }
1710
1711 return i8_winning_cost;
1712 }
1713 #endif
1714
1715 /*!
1716 ******************************************************************************
1717 * \if Function name : ihevce_topDown_tu_tree_selector \endif
1718 *
1719 * \notes
1720 * Determines RDO TU Tree using DFS. If the parent is the winner, then all
1721 * pointers to the children nodes are set to NULL
1722 * Input : 1. ps_ctxt: Pointer to enc-loop's context. Parts of this structure
1723 * shall be modified by this function. They include, au1_cu_csbf,
1724 * i8_cu_not_coded_cost, ai2_scratch, s_rdoq_sbh_ctxt,
1725 * pi4_quant_round_factor_tu_0_1, pi4_quant_round_factor_tu_1_2,
1726 * i4_quant_round_tu
1727 * 2. ps_node: Pointer to current node of the TU tree. This struct
1728 * shall be modified by this function
1729 * 3. pv_recon: Pointer to buffer which stores the recon
1730 * This buffer shall be modified by this function
1731 * 4. ps_nbr_data_buf: Pointer to struct used by succeeding CU's
1732 * during RDOPT. This buffer shall be modifie by this function
1733 * 6. pi2_deq_data: Pointer to buffer which stores the output of IQ.
1734 * This buffer shall be modified by this function
1735 * 7. pu1_ecd: Pointer to buffer which stores the data output by
1736 * entropy coding. This buffer shall be modified by this function
1737 * 8. pu1_cabac_ctxt: Pointer to buffer which stores the current CABAC
1738 * state. This buffer shall be modified by this function
1739 * Output : Cost of coding the current branch of the TU tree
1740 *
1741 *****************************************************************************
1742 */
ihevce_topDown_tu_tree_selector(ihevce_enc_loop_ctxt_t * ps_ctxt,tu_tree_node_t * ps_node,buffer_data_for_tu_t * ps_buffer_data,UWORD8 * pu1_cabac_ctxt,WORD32 i4_pred_mode,WORD32 i4_alpha_stim_multiplier,UWORD8 u1_is_cu_noisy,UWORD8 u1_cur_depth,UWORD8 u1_max_depth,UWORD8 u1_part_type,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_compute_spatial_ssd)1743 LWORD64 ihevce_topDown_tu_tree_selector(
1744 ihevce_enc_loop_ctxt_t *ps_ctxt,
1745 tu_tree_node_t *ps_node,
1746 buffer_data_for_tu_t *ps_buffer_data,
1747 UWORD8 *pu1_cabac_ctxt,
1748 WORD32 i4_pred_mode,
1749 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1750 WORD32 i4_alpha_stim_multiplier,
1751 UWORD8 u1_is_cu_noisy,
1752 #endif
1753 UWORD8 u1_cur_depth,
1754 UWORD8 u1_max_depth,
1755 UWORD8 u1_part_type,
1756 UWORD8 u1_chroma_processing_enabled,
1757 UWORD8 u1_compute_spatial_ssd)
1758 {
1759 UWORD8 au1_cabac_ctxt_backup[IHEVC_CAB_CTXT_END];
1760 UWORD8 u1_are_children_available;
1761 UWORD32 u4_tuSplitFlag_and_cbf_coding_bits;
1762
1763 nbr_4x4_t *ps_nbr_data_buf = ps_buffer_data->ps_nbr_data_buf;
1764
1765 void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
1766 void *pv_recon_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon;
1767 WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
1768 WORD16 *pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma;
1769 UWORD8 **ppu1_ecd = ps_buffer_data->ppu1_ecd;
1770 WORD32 i4_nbr_data_buf_stride = ps_buffer_data->i4_nbr_data_buf_stride;
1771 WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
1772 WORD32 i4_recon_stride_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
1773 WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
1774 WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
1775 UWORD8 *pu1_ecd_bPtr_backup_t1 = ppu1_ecd[0];
1776 UWORD8 *pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1777 LWORD64 i8_parent_cost = 0;
1778 LWORD64 i8_child_cost = 0;
1779 LWORD64 i8_winning_cost = 0;
1780 UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
1781
1782 ASSERT(ps_node != NULL);
1783 ASSERT(
1784 !(!ps_node->u1_is_valid_node &&
1785 ((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
1786 (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br))));
1787
1788 u1_are_children_available =
1789 !((NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
1790 (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br)) &&
1791 (ps_node->s_luma_data.u1_size > MIN_TU_SIZE);
1792
1793 if(u1_are_children_available)
1794 {
1795 WORD16 ai2_deq_data_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1796 UWORD16 au2_recon_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1797
1798 UWORD8 u1_is_tu_coded = 0;
1799
1800 if(ps_node->u1_is_valid_node)
1801 {
1802 buffer_data_for_tu_t s_buffer_data = ps_buffer_data[0];
1803
1804 memcpy(au1_cabac_ctxt_backup, pu1_cabac_ctxt, sizeof(au1_cabac_ctxt_backup));
1805
1806 s_buffer_data.pi2_deq_data = ai2_deq_data_backup;
1807 s_buffer_data.i4_deq_data_stride = MAX_CU_SIZE;
1808 s_buffer_data.pi2_deq_data_chroma = ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1809 s_buffer_data.i4_deq_data_stride_chroma = MAX_CU_SIZE;
1810 s_buffer_data.s_src_pred_rec_buf_luma.pv_recon = au2_recon_backup;
1811 s_buffer_data.s_src_pred_rec_buf_luma.i4_recon_stride = MAX_CU_SIZE;
1812 s_buffer_data.s_src_pred_rec_buf_chroma.pv_recon =
1813 au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1814 s_buffer_data.s_src_pred_rec_buf_chroma.i4_recon_stride = MAX_CU_SIZE;
1815
1816 ihevce_tu_processor(
1817 ps_ctxt,
1818 ps_node,
1819 &s_buffer_data,
1820 au1_cabac_ctxt_backup,
1821 i4_pred_mode,
1822 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1823 i4_alpha_stim_multiplier,
1824 u1_is_cu_noisy,
1825 #endif
1826 u1_chroma_processing_enabled,
1827 u1_compute_spatial_ssd);
1828
1829 if(i4_pred_mode != PRED_MODE_SKIP)
1830 {
1831 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1832 ps_node,
1833 ps_node,
1834 au1_cabac_ctxt_backup,
1835 MAX_TU_SIZE,
1836 MIN_TU_SIZE,
1837 0,
1838 (u1_cur_depth == u1_max_depth) ? 0 : 1,
1839 i4_pred_mode == PRED_MODE_INTRA,
1840 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1841 u1_chroma_processing_enabled,
1842 u1_is_422);
1843
1844 ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
1845 u4_tuSplitFlag_and_cbf_coding_bits,
1846 ps_ctxt->i8_cl_ssd_lambda_qf,
1847 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1848 }
1849
1850 i8_parent_cost +=
1851 ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
1852
1853 ihevce_ecd_buffer_pointer_updater(
1854 ps_node,
1855 ppu1_ecd,
1856 pu1_ecd_bPtr_backup_t1,
1857 1,
1858 u1_chroma_processing_enabled,
1859 u1_is_422);
1860 }
1861 else
1862 {
1863 ps_node->s_luma_data.i8_cost = i8_parent_cost = LLONG_MAX;
1864 ps_node->s_luma_data.i4_num_bytes_used_for_ecd = 0;
1865 }
1866
1867 u1_is_tu_coded |= ps_node->s_luma_data.u1_cbf;
1868
1869 if(u1_chroma_processing_enabled)
1870 {
1871 UWORD8 i;
1872
1873 for(i = 0; i < u1_is_422 + 1; i++)
1874 {
1875 u1_is_tu_coded |= ps_node->as_cb_data[i].u1_cbf;
1876 u1_is_tu_coded |= ps_node->as_cr_data[i].u1_cbf;
1877 }
1878 }
1879
1880 if(!ps_node->u1_is_valid_node || u1_is_tu_coded)
1881 {
1882 pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1883
1884 if(i4_pred_mode != PRED_MODE_SKIP)
1885 {
1886 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1887 ps_node,
1888 ps_node->ps_child_node_tl,
1889 pu1_cabac_ctxt,
1890 MAX_TU_SIZE,
1891 MIN_TU_SIZE,
1892 0,
1893 1,
1894 i4_pred_mode == PRED_MODE_INTRA,
1895 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1896 u1_chroma_processing_enabled,
1897 u1_is_422);
1898
1899 i8_child_cost += COMPUTE_RATE_COST_CLIP30(
1900 u4_tuSplitFlag_and_cbf_coding_bits,
1901 ps_ctxt->i8_cl_ssd_lambda_qf,
1902 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1903 }
1904
1905 if(i8_child_cost < i8_parent_cost)
1906 {
1907 i8_child_cost += ihevce_topDown_tu_tree_selector(
1908 ps_ctxt,
1909 ps_node->ps_child_node_tl,
1910 ps_buffer_data,
1911 pu1_cabac_ctxt,
1912 i4_pred_mode,
1913 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1914 i4_alpha_stim_multiplier,
1915 u1_is_cu_noisy,
1916 #endif
1917 u1_cur_depth,
1918 u1_max_depth,
1919 u1_part_type,
1920 u1_chroma_processing_enabled,
1921 u1_compute_spatial_ssd);
1922
1923 ps_node->ps_child_node_tl->s_luma_data.i8_cost +=
1924 i8_child_cost - ps_node->ps_child_node_tl->s_luma_data.i8_cost;
1925 }
1926
1927 if(i8_child_cost < i8_parent_cost)
1928 {
1929 i8_child_cost += ihevce_topDown_tu_tree_selector(
1930 ps_ctxt,
1931 ps_node->ps_child_node_tr,
1932 ps_buffer_data,
1933 pu1_cabac_ctxt,
1934 i4_pred_mode,
1935 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1936 i4_alpha_stim_multiplier,
1937 u1_is_cu_noisy,
1938 #endif
1939 u1_cur_depth,
1940 u1_max_depth,
1941 u1_part_type,
1942 u1_chroma_processing_enabled,
1943 u1_compute_spatial_ssd);
1944 }
1945
1946 if(i8_child_cost < i8_parent_cost)
1947 {
1948 i8_child_cost += ihevce_topDown_tu_tree_selector(
1949 ps_ctxt,
1950 ps_node->ps_child_node_bl,
1951 ps_buffer_data,
1952 pu1_cabac_ctxt,
1953 i4_pred_mode,
1954 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1955 i4_alpha_stim_multiplier,
1956 u1_is_cu_noisy,
1957 #endif
1958 u1_cur_depth,
1959 u1_max_depth,
1960 u1_part_type,
1961 u1_chroma_processing_enabled,
1962 u1_compute_spatial_ssd);
1963 }
1964
1965 if(i8_child_cost < i8_parent_cost)
1966 {
1967 i8_child_cost += ihevce_topDown_tu_tree_selector(
1968 ps_ctxt,
1969 ps_node->ps_child_node_br,
1970 ps_buffer_data,
1971 pu1_cabac_ctxt,
1972 i4_pred_mode,
1973 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1974 i4_alpha_stim_multiplier,
1975 u1_is_cu_noisy,
1976 #endif
1977 u1_cur_depth,
1978 u1_max_depth,
1979 u1_part_type,
1980 u1_chroma_processing_enabled,
1981 u1_compute_spatial_ssd);
1982 }
1983
1984 if(i8_parent_cost > i8_child_cost)
1985 {
1986 UWORD32 u4_num_bytes = ihevce_ecd_buffer_pointer_updater(
1987 ps_node,
1988 ppu1_ecd,
1989 pu1_ecd_bPtr_backup_t1,
1990 0,
1991 u1_chroma_processing_enabled,
1992 u1_is_422);
1993
1994 if(pu1_ecd_bPtr_backup_t2 != pu1_ecd_bPtr_backup_t1)
1995 {
1996 memmove(pu1_ecd_bPtr_backup_t1, pu1_ecd_bPtr_backup_t2, u4_num_bytes);
1997 }
1998
1999 ps_node->s_luma_data.i4_num_bytes_used_for_ecd = u4_num_bytes;
2000 ps_node->as_cb_data[0].i4_num_bytes_used_for_ecd = 0;
2001 ps_node->as_cb_data[1].i4_num_bytes_used_for_ecd = 0;
2002 ps_node->as_cr_data[0].i4_num_bytes_used_for_ecd = 0;
2003 ps_node->as_cr_data[1].i4_num_bytes_used_for_ecd = 0;
2004
2005 ps_node->u1_is_valid_node = 0;
2006
2007 i8_winning_cost = i8_child_cost;
2008 }
2009 else
2010 {
2011 ihevce_debriefer_when_parent_wins(
2012 ps_node,
2013 ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2014 ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2015 ps_nbr_data_buf,
2016 ai2_deq_data_backup,
2017 pi2_deq_data,
2018 ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2019 pi2_deq_data_chroma,
2020 au2_recon_backup,
2021 pv_recon,
2022 au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2023 pv_recon_chroma,
2024 au1_cabac_ctxt_backup,
2025 pu1_cabac_ctxt,
2026 NULL,
2027 NULL,
2028 i4_nbr_data_buf_stride,
2029 MAX_CU_SIZE,
2030 i4_deq_data_stride,
2031 MAX_CU_SIZE,
2032 i4_deq_data_stride_chroma,
2033 MAX_CU_SIZE,
2034 i4_recon_stride,
2035 MAX_CU_SIZE,
2036 i4_recon_stride_chroma,
2037 sizeof(au1_cabac_ctxt_backup),
2038 ps_ctxt->i4_cu_qp,
2039 u1_chroma_processing_enabled,
2040 u1_is_422,
2041 ps_ctxt->u1_bit_depth > 8);
2042
2043 ihevce_ecd_buffer_pointer_updater(
2044 ps_node,
2045 ppu1_ecd,
2046 pu1_ecd_bPtr_backup_t1,
2047 1,
2048 u1_chroma_processing_enabled,
2049 u1_is_422);
2050
2051 i8_winning_cost = i8_parent_cost;
2052 }
2053 }
2054 else
2055 {
2056 ihevce_debriefer_when_parent_wins(
2057 ps_node,
2058 ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2059 ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2060 ps_nbr_data_buf,
2061 ai2_deq_data_backup,
2062 pi2_deq_data,
2063 ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2064 pi2_deq_data_chroma,
2065 au2_recon_backup,
2066 pv_recon,
2067 au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2068 pv_recon_chroma,
2069 au1_cabac_ctxt_backup,
2070 pu1_cabac_ctxt,
2071 NULL,
2072 NULL,
2073 i4_nbr_data_buf_stride,
2074 MAX_CU_SIZE,
2075 i4_deq_data_stride,
2076 MAX_CU_SIZE,
2077 i4_deq_data_stride_chroma,
2078 MAX_CU_SIZE,
2079 i4_recon_stride,
2080 MAX_CU_SIZE,
2081 i4_recon_stride_chroma,
2082 sizeof(au1_cabac_ctxt_backup),
2083 ps_ctxt->i4_cu_qp,
2084 u1_chroma_processing_enabled,
2085 u1_is_422,
2086 ps_ctxt->u1_bit_depth > 8);
2087
2088 ihevce_ecd_buffer_pointer_updater(
2089 ps_node,
2090 ppu1_ecd,
2091 pu1_ecd_bPtr_backup_t1,
2092 1,
2093 u1_chroma_processing_enabled,
2094 u1_is_422);
2095
2096 i8_winning_cost = i8_parent_cost;
2097 }
2098 }
2099 else
2100 {
2101 ASSERT(ps_node->u1_is_valid_node);
2102
2103 ihevce_tu_processor(
2104 ps_ctxt,
2105 ps_node,
2106 ps_buffer_data,
2107 pu1_cabac_ctxt,
2108 i4_pred_mode,
2109 #if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
2110 i4_alpha_stim_multiplier,
2111 u1_is_cu_noisy,
2112 #endif
2113 u1_chroma_processing_enabled,
2114 u1_compute_spatial_ssd);
2115
2116 if(i4_pred_mode != PRED_MODE_SKIP)
2117 {
2118 u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
2119 ps_node,
2120 ps_node,
2121 pu1_cabac_ctxt,
2122 MAX_TU_SIZE,
2123 MIN_TU_SIZE,
2124 0,
2125 (u1_cur_depth == u1_max_depth) ? 0 : 1,
2126 i4_pred_mode == PRED_MODE_INTRA,
2127 (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
2128 u1_chroma_processing_enabled,
2129 u1_is_422);
2130
2131 ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
2132 u4_tuSplitFlag_and_cbf_coding_bits,
2133 ps_ctxt->i8_cl_ssd_lambda_qf,
2134 (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
2135 }
2136
2137 i8_winning_cost +=
2138 ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
2139
2140 ihevce_ecd_buffer_pointer_updater(
2141 ps_node, ppu1_ecd, pu1_ecd_bPtr_backup_t1, 1, u1_chroma_processing_enabled, u1_is_422);
2142
2143 ihevce_nbr_data_copier(
2144 ps_nbr_data_buf,
2145 i4_nbr_data_buf_stride,
2146 ps_ctxt->i4_cu_qp,
2147 ps_node->s_luma_data.u1_cbf,
2148 ps_node->s_luma_data.u1_posx,
2149 ps_node->s_luma_data.u1_posy,
2150 ps_node->s_luma_data.u1_size);
2151 }
2152
2153 return i8_winning_cost;
2154 }
2155
2156 /*!
2157 ******************************************************************************
2158 * \if Function name : ihevce_tu_selector_debriefer \endif
2159 *
2160 * \notes
2161 * Conversion of TU Tree struct into TU info array. Collection of myriad CU
2162 * level data
2163 * Input : 1. ps_node: Pointer to current node of the TU tree. This struct
2164 * shall be modified by this function
2165 * 2. ps_final_prms: Pointer to struct that stores RDOPT output data.
2166 * This buffer shall be modified by this function
2167 * Output : 1. pi8_total_cost: Total CU-level cost
2168 * 2. pi8_total_non_coded_cost: Total CU level cost when no residue
2169 * is coded
2170 * 3. pi4_num_bytes_used_for_ecd: Number of bytes used for storing
2171 * entropy coding data
2172 * 4. pi4_num_bits_used_for_encoding: Number of bits used for encoding
2173 * 5. pu2_tu_ctr: Number of TU's in the CU
2174 *
2175 *****************************************************************************
2176 */
ihevce_tu_selector_debriefer(tu_tree_node_t * ps_node,enc_loop_cu_final_prms_t * ps_final_prms,LWORD64 * pi8_total_cost,LWORD64 * pi8_total_non_coded_cost,WORD32 * pi4_num_bytes_used_for_ecd,WORD32 * pi4_num_bits_used_for_encoding,UWORD16 * pu2_tu_ctr,WORD32 i4_cu_qp,UWORD8 u1_cu_posx,UWORD8 u1_cu_posy,UWORD8 u1_chroma_processing_enabled,UWORD8 u1_is_422,TU_POS_T e_tu_pos)2177 void ihevce_tu_selector_debriefer(
2178 tu_tree_node_t *ps_node,
2179 enc_loop_cu_final_prms_t *ps_final_prms,
2180 LWORD64 *pi8_total_cost,
2181 LWORD64 *pi8_total_non_coded_cost,
2182 WORD32 *pi4_num_bytes_used_for_ecd,
2183 WORD32 *pi4_num_bits_used_for_encoding,
2184 UWORD16 *pu2_tu_ctr,
2185 WORD32 i4_cu_qp,
2186 UWORD8 u1_cu_posx,
2187 UWORD8 u1_cu_posy,
2188 UWORD8 u1_chroma_processing_enabled,
2189 UWORD8 u1_is_422,
2190 TU_POS_T e_tu_pos)
2191 {
2192 UWORD8 u1_is_chroma_tu_valid = 1;
2193 WORD32 i4_log2_size;
2194
2195 ASSERT(ps_node != NULL);
2196
2197 if(ps_node->u1_is_valid_node)
2198 {
2199 ASSERT(
2200 (NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
2201 (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br));
2202 }
2203 else
2204 {
2205 ASSERT(
2206 !((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
2207 (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br)));
2208 }
2209
2210 if(ps_node->u1_is_valid_node)
2211 {
2212 if((4 == ps_node->s_luma_data.u1_size) && (POS_TL != e_tu_pos))
2213 {
2214 u1_is_chroma_tu_valid = INTRA_PRED_CHROMA_IDX_NONE;
2215 }
2216
2217 GETRANGE(i4_log2_size, ps_node->s_luma_data.u1_size);
2218
2219 ps_final_prms->s_recon_datastore.au1_bufId_with_winning_LumaRecon[pu2_tu_ctr[0]] =
2220 ps_node->s_luma_data.u1_reconBufId;
2221 ps_final_prms->u4_cu_sad += ps_node->s_luma_data.u4_sad;
2222 ps_final_prms->u1_is_cu_coded |= ps_node->s_luma_data.u1_cbf;
2223 ps_final_prms->u4_cu_luma_res_bits += ps_node->s_luma_data.i4_bits;
2224
2225 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].i4_luma_coeff_offset =
2226 pi4_num_bytes_used_for_ecd[0];
2227 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_y_cbf = ps_node->s_luma_data.u1_cbf;
2228 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf = 0;
2229 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf = 0;
2230 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf_subtu1 = 0;
2231 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf_subtu1 = 0;
2232 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_chroma_intra_mode_idx =
2233 u1_is_chroma_tu_valid;
2234 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b7_qp = i4_cu_qp;
2235 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_first_tu_in_cu =
2236 (!ps_node->s_luma_data.u1_posx && !ps_node->s_luma_data.u1_posx);
2237 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_transquant_bypass = 0;
2238 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_size = i4_log2_size - 3;
2239 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_x =
2240 (u1_cu_posx + ps_node->s_luma_data.u1_posx) / 4;
2241 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_y =
2242 (u1_cu_posy + ps_node->s_luma_data.u1_posy) / 4;
2243
2244 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].i2_luma_bytes_consumed =
2245 ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2246 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_col =
2247 ps_node->s_luma_data.i4_zero_col;
2248 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_row =
2249 ps_node->s_luma_data.i4_zero_row;
2250
2251 pi8_total_cost[0] += ps_node->s_luma_data.i8_cost;
2252 pi8_total_non_coded_cost[0] += ps_node->s_luma_data.i8_not_coded_cost;
2253 pi4_num_bytes_used_for_ecd[0] += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2254 pi4_num_bits_used_for_encoding[0] += ps_node->s_luma_data.i4_bits;
2255
2256 if(u1_chroma_processing_enabled)
2257 {
2258 UWORD8 i;
2259
2260 for(i = 0; i < u1_is_422 + 1; i++)
2261 {
2262 ps_final_prms->s_recon_datastore
2263 .au1_bufId_with_winning_ChromaRecon[U_PLANE][pu2_tu_ctr[0]][i] =
2264 ps_node->as_cb_data[i].u1_reconBufId;
2265 ps_final_prms->u1_is_cu_coded |= ps_node->as_cb_data[i].u1_cbf;
2266 ps_final_prms->u4_cu_chroma_res_bits += ps_node->as_cb_data[i].i4_bits;
2267
2268 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].ai4_cb_coeff_offset[i] =
2269 pi4_num_bytes_used_for_ecd[0];
2270
2271 if(!i)
2272 {
2273 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf =
2274 ps_node->as_cb_data[i].u1_cbf;
2275 }
2276 else
2277 {
2278 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf_subtu1 =
2279 ps_node->as_cb_data[i].u1_cbf;
2280 }
2281
2282 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].ai2_cb_bytes_consumed[i] =
2283 ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
2284 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cb_zero_col[i] =
2285 ps_node->as_cb_data[i].i4_zero_col;
2286 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cb_zero_row[i] =
2287 ps_node->as_cb_data[i].i4_zero_row;
2288
2289 pi8_total_cost[0] += ps_node->as_cb_data[i].i8_cost;
2290 pi8_total_non_coded_cost[0] += ps_node->as_cb_data[i].i8_not_coded_cost;
2291 pi4_num_bytes_used_for_ecd[0] += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
2292 pi4_num_bits_used_for_encoding[0] += ps_node->as_cb_data[i].i4_bits;
2293 }
2294
2295 for(i = 0; i < u1_is_422 + 1; i++)
2296 {
2297 ps_final_prms->s_recon_datastore
2298 .au1_bufId_with_winning_ChromaRecon[V_PLANE][pu2_tu_ctr[0]][i] =
2299 ps_node->as_cr_data[i].u1_reconBufId;
2300 ps_final_prms->u1_is_cu_coded |= ps_node->as_cr_data[i].u1_cbf;
2301 ps_final_prms->u4_cu_chroma_res_bits += ps_node->as_cr_data[i].i4_bits;
2302
2303 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].ai4_cr_coeff_offset[i] =
2304 pi4_num_bytes_used_for_ecd[0];
2305
2306 if(!i)
2307 {
2308 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf =
2309 ps_node->as_cr_data[i].u1_cbf;
2310 }
2311 else
2312 {
2313 ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf_subtu1 =
2314 ps_node->as_cr_data[i].u1_cbf;
2315 }
2316
2317 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].ai2_cr_bytes_consumed[i] =
2318 ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
2319 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cr_zero_col[i] =
2320 ps_node->as_cr_data[i].i4_zero_col;
2321 ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cr_zero_row[i] =
2322 ps_node->as_cr_data[i].i4_zero_row;
2323
2324 pi8_total_cost[0] += ps_node->as_cr_data[i].i8_cost;
2325 pi8_total_non_coded_cost[0] += ps_node->as_cr_data[i].i8_not_coded_cost;
2326 pi4_num_bytes_used_for_ecd[0] += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
2327 pi4_num_bits_used_for_encoding[0] += ps_node->as_cr_data[i].i4_bits;
2328 }
2329 }
2330
2331 pu2_tu_ctr[0]++;
2332 }
2333 else
2334 {
2335 ihevce_tu_selector_debriefer(
2336 ps_node->ps_child_node_tl,
2337 ps_final_prms,
2338 pi8_total_cost,
2339 pi8_total_non_coded_cost,
2340 pi4_num_bytes_used_for_ecd,
2341 pi4_num_bits_used_for_encoding,
2342 pu2_tu_ctr,
2343 i4_cu_qp,
2344 u1_cu_posx,
2345 u1_cu_posy,
2346 u1_chroma_processing_enabled,
2347 u1_is_422,
2348 POS_TL);
2349
2350 ihevce_tu_selector_debriefer(
2351 ps_node->ps_child_node_tr,
2352 ps_final_prms,
2353 pi8_total_cost,
2354 pi8_total_non_coded_cost,
2355 pi4_num_bytes_used_for_ecd,
2356 pi4_num_bits_used_for_encoding,
2357 pu2_tu_ctr,
2358 i4_cu_qp,
2359 u1_cu_posx,
2360 u1_cu_posy,
2361 u1_chroma_processing_enabled,
2362 u1_is_422,
2363 POS_TR);
2364
2365 ihevce_tu_selector_debriefer(
2366 ps_node->ps_child_node_bl,
2367 ps_final_prms,
2368 pi8_total_cost,
2369 pi8_total_non_coded_cost,
2370 pi4_num_bytes_used_for_ecd,
2371 pi4_num_bits_used_for_encoding,
2372 pu2_tu_ctr,
2373 i4_cu_qp,
2374 u1_cu_posx,
2375 u1_cu_posy,
2376 u1_chroma_processing_enabled,
2377 u1_is_422,
2378 POS_BL);
2379
2380 ihevce_tu_selector_debriefer(
2381 ps_node->ps_child_node_br,
2382 ps_final_prms,
2383 pi8_total_cost,
2384 pi8_total_non_coded_cost,
2385 pi4_num_bytes_used_for_ecd,
2386 pi4_num_bits_used_for_encoding,
2387 pu2_tu_ctr,
2388 i4_cu_qp,
2389 u1_cu_posx,
2390 u1_cu_posy,
2391 u1_chroma_processing_enabled,
2392 u1_is_422,
2393 POS_BR);
2394 }
2395 }
2396
ihevce_get_curTUSplit_from_TUSplitArray(WORD32 ai4_tuSplitArray[4],UWORD8 u1_cu_size,UWORD8 u1_tu_size,UWORD8 u1_posx,UWORD8 u1_posy)2397 static UWORD8 ihevce_get_curTUSplit_from_TUSplitArray(
2398 WORD32 ai4_tuSplitArray[4], UWORD8 u1_cu_size, UWORD8 u1_tu_size, UWORD8 u1_posx, UWORD8 u1_posy)
2399 {
2400 UWORD8 u1_is_split = 0;
2401
2402 UWORD8 u1_tuSplitArrayIndex = 0;
2403 UWORD8 u1_bit_index = 0;
2404
2405 switch(u1_cu_size)
2406 {
2407 case 8:
2408 {
2409 switch(u1_tu_size)
2410 {
2411 case 8:
2412 {
2413 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2414
2415 break;
2416 }
2417 case 4:
2418 {
2419 u1_is_split = 0;
2420
2421 break;
2422 }
2423 }
2424
2425 break;
2426 }
2427 case 16:
2428 {
2429 switch(u1_tu_size)
2430 {
2431 case 16:
2432 {
2433 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2434
2435 break;
2436 }
2437 case 8:
2438 {
2439 u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2440 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2441
2442 break;
2443 }
2444 case 4:
2445 {
2446 u1_is_split = 0;
2447
2448 break;
2449 }
2450 }
2451
2452 break;
2453 }
2454 case 32:
2455 {
2456 switch(u1_tu_size)
2457 {
2458 case 32:
2459 {
2460 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2461
2462 break;
2463 }
2464 case 16:
2465 {
2466 u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2467 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2468
2469 break;
2470 }
2471 case 8:
2472 {
2473 u1_bit_index = 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2474 u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2475 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2476
2477 break;
2478 }
2479 case 4:
2480 {
2481 u1_is_split = 0;
2482
2483 break;
2484 }
2485 }
2486
2487 break;
2488 }
2489 case 64:
2490 {
2491 switch(u1_tu_size)
2492 {
2493 case 64:
2494 {
2495 u1_is_split = 1;
2496
2497 break;
2498 }
2499 case 32:
2500 {
2501 u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2502 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2503
2504 break;
2505 }
2506 case 16:
2507 {
2508 u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2509 u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2510 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2511
2512 break;
2513 }
2514 case 8:
2515 {
2516 u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2517 u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2518 u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2519 u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2520
2521 break;
2522 }
2523 case 4:
2524 {
2525 u1_is_split = 0;
2526
2527 break;
2528 }
2529 }
2530
2531 break;
2532 }
2533 }
2534
2535 return u1_is_split;
2536 }
2537
2538 /*!
2539 ******************************************************************************
2540 * \if Function name : ihevce_tuSplitArray_to_tuTree_mapper \endif
2541 *
2542 * \notes
2543 * This function assumes that ihevce_tu_tree_init' has been called already.
2544 * The pointers to the children nodes of the leaf-most nodes in the tree
2545 * are assigned NULL
2546 * Input : 1. ps_root: Pointer to root of the tree containing TU info.
2547 * This struct shall be modified by this function
2548 * 2. ai4_tuSplitArray: Array containing information about TU splits
2549 * Output : 1. TU tree is modified such that it reflects the information
2550 * coded in ai4_tuSplitArray
2551 *
2552 *****************************************************************************
2553 */
ihevce_tuSplitArray_to_tuTree_mapper(tu_tree_node_t * ps_root,WORD32 ai4_tuSplitArray[4],UWORD8 u1_cu_size,UWORD8 u1_tu_size,UWORD8 u1_min_tu_size,UWORD8 u1_max_tu_size,UWORD8 u1_is_skip)2554 void ihevce_tuSplitArray_to_tuTree_mapper(
2555 tu_tree_node_t *ps_root,
2556 WORD32 ai4_tuSplitArray[4],
2557 UWORD8 u1_cu_size,
2558 UWORD8 u1_tu_size,
2559 UWORD8 u1_min_tu_size,
2560 UWORD8 u1_max_tu_size,
2561 UWORD8 u1_is_skip)
2562 {
2563 UWORD8 u1_is_split;
2564
2565 ASSERT(u1_min_tu_size >= MIN_TU_SIZE);
2566 ASSERT(u1_max_tu_size <= MAX_TU_SIZE);
2567 ASSERT(u1_min_tu_size <= u1_max_tu_size);
2568
2569 ASSERT(!u1_is_skip);
2570
2571 ASSERT(ps_root != NULL);
2572 ASSERT(ps_root->s_luma_data.u1_size == u1_tu_size);
2573
2574 if(u1_tu_size <= u1_max_tu_size)
2575 {
2576 ASSERT(ps_root->u1_is_valid_node);
2577 }
2578 else
2579 {
2580 ASSERT(!ps_root->u1_is_valid_node);
2581 }
2582
2583 if(u1_tu_size > u1_min_tu_size)
2584 {
2585 ASSERT(ps_root->ps_child_node_tl != NULL);
2586 ASSERT(ps_root->ps_child_node_tr != NULL);
2587 ASSERT(ps_root->ps_child_node_bl != NULL);
2588 ASSERT(ps_root->ps_child_node_br != NULL);
2589 ASSERT(ps_root->ps_child_node_tl->s_luma_data.u1_size == (u1_tu_size / 2));
2590 ASSERT(ps_root->ps_child_node_tr->s_luma_data.u1_size == (u1_tu_size / 2));
2591 ASSERT(ps_root->ps_child_node_bl->s_luma_data.u1_size == (u1_tu_size / 2));
2592 ASSERT(ps_root->ps_child_node_br->s_luma_data.u1_size == (u1_tu_size / 2));
2593 ASSERT(ps_root->ps_child_node_tl->u1_is_valid_node);
2594 ASSERT(ps_root->ps_child_node_tr->u1_is_valid_node);
2595 ASSERT(ps_root->ps_child_node_bl->u1_is_valid_node);
2596 ASSERT(ps_root->ps_child_node_br->u1_is_valid_node);
2597 }
2598 else
2599 {
2600 ASSERT(ps_root->ps_child_node_tl == NULL);
2601 ASSERT(ps_root->ps_child_node_tr == NULL);
2602 ASSERT(ps_root->ps_child_node_bl == NULL);
2603 ASSERT(ps_root->ps_child_node_br == NULL);
2604 }
2605
2606 u1_is_split = ihevce_get_curTUSplit_from_TUSplitArray(
2607 ai4_tuSplitArray,
2608 u1_cu_size,
2609 u1_tu_size,
2610 ps_root->s_luma_data.u1_posx,
2611 ps_root->s_luma_data.u1_posy);
2612
2613 if(u1_tu_size == u1_min_tu_size)
2614 {
2615 ASSERT(!u1_is_split);
2616 }
2617
2618 if(u1_is_split)
2619 {
2620 ps_root->u1_is_valid_node = 0;
2621
2622 ihevce_tuSplitArray_to_tuTree_mapper(
2623 ps_root->ps_child_node_tl,
2624 ai4_tuSplitArray,
2625 u1_cu_size,
2626 ps_root->ps_child_node_tl->s_luma_data.u1_size,
2627 u1_min_tu_size,
2628 u1_max_tu_size,
2629 u1_is_skip);
2630
2631 ihevce_tuSplitArray_to_tuTree_mapper(
2632 ps_root->ps_child_node_tr,
2633 ai4_tuSplitArray,
2634 u1_cu_size,
2635 ps_root->ps_child_node_tr->s_luma_data.u1_size,
2636 u1_min_tu_size,
2637 u1_max_tu_size,
2638 u1_is_skip);
2639
2640 ihevce_tuSplitArray_to_tuTree_mapper(
2641 ps_root->ps_child_node_bl,
2642 ai4_tuSplitArray,
2643 u1_cu_size,
2644 ps_root->ps_child_node_bl->s_luma_data.u1_size,
2645 u1_min_tu_size,
2646 u1_max_tu_size,
2647 u1_is_skip);
2648
2649 ihevce_tuSplitArray_to_tuTree_mapper(
2650 ps_root->ps_child_node_br,
2651 ai4_tuSplitArray,
2652 u1_cu_size,
2653 ps_root->ps_child_node_br->s_luma_data.u1_size,
2654 u1_min_tu_size,
2655 u1_max_tu_size,
2656 u1_is_skip);
2657 }
2658 else
2659 {
2660 ps_root->ps_child_node_tl = NULL;
2661 ps_root->ps_child_node_tr = NULL;
2662 ps_root->ps_child_node_bl = NULL;
2663 ps_root->ps_child_node_br = NULL;
2664 }
2665 }
2666