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