Coverage Report

Created: 2023-09-25 07:43

/src/libhevc/encoder/ihevce_tu_tree_selector.c
Line
Count
Source (jump to first uncovered line)
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
*/
107
WORD32 ihevce_tu_tree_coverage_in_cu(tu_tree_node_t *ps_node)
108
0
{
109
0
    WORD32 i4_tu_tree_area = 0;
110
111
0
    if(ps_node->u1_is_valid_node)
112
0
    {
113
0
        i4_tu_tree_area += ps_node->s_luma_data.u1_size * ps_node->s_luma_data.u1_size;
114
0
    }
115
0
    else
116
0
    {
117
0
        if(NULL != ps_node->ps_child_node_tl)
118
0
        {
119
0
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tl);
120
0
        }
121
122
0
        if(NULL != ps_node->ps_child_node_tr)
123
0
        {
124
0
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tr);
125
0
        }
126
127
0
        if(NULL != ps_node->ps_child_node_bl)
128
0
        {
129
0
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_bl);
130
0
        }
131
132
0
        if(NULL != ps_node->ps_child_node_br)
133
0
        {
134
0
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_br);
135
0
        }
136
0
    }
137
138
0
    return i4_tu_tree_area;
139
0
}
140
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
0
{
144
0
    ps_tu_data->u1_size = u1_size;
145
0
    ps_tu_data->i8_ssd = 0;
146
0
    ps_tu_data->i8_cost = 0;
147
0
#if ENABLE_INTER_ZCU_COST
148
0
    ps_tu_data->i8_not_coded_cost = 0;
149
0
#endif
150
0
    ps_tu_data->u4_sad = 0;
151
0
    ps_tu_data->i4_bits = 0;
152
0
    ps_tu_data->i4_num_bytes_used_for_ecd = 0;
153
0
    ps_tu_data->u1_cbf = 0;
154
0
    ps_tu_data->u1_reconBufId = UCHAR_MAX;
155
0
    ps_tu_data->u1_posx = u1_posx;
156
0
    ps_tu_data->u1_posy = u1_posy;
157
0
}
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
*/
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
0
{
187
0
    tu_tree_node_t *ps_node;
188
0
    tu_tree_node_t *ps_childNodeTL;
189
0
    tu_tree_node_t *ps_childNodeTR;
190
0
    tu_tree_node_t *ps_childNodeBL;
191
0
    tu_tree_node_t *ps_childNodeBR;
192
193
0
    UWORD8 u1_start_index_for_parent = 0;
194
0
    UWORD8 u1_start_index_for_child = 0;
195
0
    UWORD16 u2_parent_offset = 0;
196
0
    UWORD16 u2_child_offset = 0;
197
0
    UWORD8 u1_posx = 0;
198
0
    UWORD8 u1_posy = 0;
199
200
0
    const UWORD8 u1_nxn_tu_node_start_index = 0;
201
0
    const UWORD8 u1_nBye2xnBye2_tu_node_start_index = 1;
202
0
    const UWORD8 u1_nBye4xnBye4_tu_node_start_index = 1 + 4;
203
0
    const UWORD8 u1_nBye8xnBye8_tu_node_start_index = 1 + 4 + 16;
204
0
    const UWORD8 u1_nBye16xnBye16_tu_node_start_index = 1 + 4 + 16 + 64;
205
0
    UWORD16 u2_num_nodes_initialised = 0;
206
207
0
    ASSERT(u1_cur_depth <= u1_max_tree_depth);
208
0
    ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
209
210
0
    switch(e_tu_pos)
211
0
    {
212
0
    case POS_TL:
213
0
    {
214
0
        u1_posx = u1_parent_posx;
215
0
        u1_posy = u1_parent_posy;
216
217
0
        break;
218
0
    }
219
0
    case POS_TR:
220
0
    {
221
0
        u1_posx = u1_parent_posx + u1_size;
222
0
        u1_posy = u1_parent_posy;
223
224
0
        break;
225
0
    }
226
0
    case POS_BL:
227
0
    {
228
0
        u1_posx = u1_parent_posx;
229
0
        u1_posy = u1_parent_posy + u1_size;
230
231
0
        break;
232
0
    }
233
0
    case POS_BR:
234
0
    {
235
0
        u1_posx = u1_parent_posx + u1_size;
236
0
        u1_posy = u1_parent_posy + u1_size;
237
238
0
        break;
239
0
    }
240
0
    default:
241
0
    {
242
        /* Here be dragons */
243
0
        ASSERT(0);
244
0
    }
245
0
    }
246
247
0
    switch(u1_cur_depth)
248
0
    {
249
0
    case 0:
250
0
    {
251
0
        u1_start_index_for_parent = u1_nxn_tu_node_start_index;
252
0
        u1_start_index_for_child = u1_nBye2xnBye2_tu_node_start_index;
253
254
0
        u2_parent_offset = 0;
255
0
        u2_child_offset = 0;
256
257
0
        break;
258
0
    }
259
0
    case 1:
260
0
    {
261
0
        u1_start_index_for_parent = u1_nBye2xnBye2_tu_node_start_index;
262
0
        u1_start_index_for_child = u1_nBye4xnBye4_tu_node_start_index;
263
264
0
        u2_parent_offset = e_tu_pos;
265
0
        u2_child_offset = 4 * u1_posx / u1_size + 8 * u1_posy / u1_size;
266
267
0
        break;
268
0
    }
269
0
    case 2:
270
0
    {
271
0
        u1_start_index_for_parent = u1_nBye4xnBye4_tu_node_start_index;
272
0
        u1_start_index_for_child = u1_nBye8xnBye8_tu_node_start_index;
273
274
0
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 4 * u1_parent_posy / u1_size + e_tu_pos;
275
0
        u2_child_offset = 4 * u1_posx / u1_size + 16 * u1_posy / u1_size;
276
277
0
        break;
278
0
    }
279
0
    case 3:
280
0
    {
281
0
        u1_start_index_for_parent = u1_nBye8xnBye8_tu_node_start_index;
282
0
        u1_start_index_for_child = u1_nBye16xnBye16_tu_node_start_index;
283
284
0
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 8 * u1_parent_posy / u1_size + e_tu_pos;
285
0
        u2_child_offset = 4 * u1_posx / u1_size + 32 * u1_posy / u1_size;
286
287
0
        break;
288
0
    }
289
0
    case 4:
290
0
    {
291
0
        u1_start_index_for_parent = u1_nBye16xnBye16_tu_node_start_index;
292
0
        u1_start_index_for_child = 0;
293
294
0
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 16 * u1_parent_posy / u1_size + e_tu_pos;
295
0
        u2_child_offset = 0;
296
297
0
        break;
298
0
    }
299
0
    default:
300
0
    {
301
        /* Here be dragons */
302
0
        ASSERT(0);
303
0
    }
304
0
    }
305
306
0
    ASSERT((u1_start_index_for_parent + u2_parent_offset) < (256 + 64 + 16 + 4 + 1));
307
0
    ASSERT((u1_start_index_for_child + u2_child_offset + POS_BR) < (256 + 64 + 16 + 4 + 1));
308
309
0
    ps_node = ps_root + u1_start_index_for_parent + u2_parent_offset;
310
0
    ps_childNodeTL = ps_root + u1_start_index_for_child + u2_child_offset + POS_TL;
311
0
    ps_childNodeTR = ps_root + u1_start_index_for_child + u2_child_offset + POS_TR;
312
0
    ps_childNodeBL = ps_root + u1_start_index_for_child + u2_child_offset + POS_BL;
313
0
    ps_childNodeBR = ps_root + u1_start_index_for_child + u2_child_offset + POS_BR;
314
315
0
    ihevce_tu_node_data_init(&ps_node->s_luma_data, u1_size, u1_posx, u1_posy);
316
317
0
    if(u1_chroma_processing_enabled)
318
0
    {
319
0
        UWORD8 i;
320
321
0
        if(u1_size > 4)
322
0
        {
323
0
            for(i = 0; i < (u1_is_422 + 1); i++)
324
0
            {
325
0
                ihevce_tu_node_data_init(
326
0
                    &ps_node->as_cb_data[i],
327
0
                    u1_size / 2,
328
0
                    u1_posx / 2,
329
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size / 2);
330
331
0
                ihevce_tu_node_data_init(
332
0
                    &ps_node->as_cr_data[i],
333
0
                    u1_size / 2,
334
0
                    u1_posx / 2,
335
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size / 2);
336
0
            }
337
0
        }
338
0
        else if(POS_TL == e_tu_pos)
339
0
        {
340
0
            for(i = 0; i < (u1_is_422 + 1); i++)
341
0
            {
342
0
                ihevce_tu_node_data_init(
343
0
                    &ps_node->as_cb_data[i],
344
0
                    u1_size,
345
0
                    u1_posx / 2,
346
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
347
348
0
                ihevce_tu_node_data_init(
349
0
                    &ps_node->as_cr_data[i],
350
0
                    u1_size,
351
0
                    u1_posx / 2,
352
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
353
0
            }
354
0
        }
355
0
        else
356
0
        {
357
0
            for(i = 0; i < (u1_is_422 + 1); i++)
358
0
            {
359
0
                ihevce_tu_node_data_init(
360
0
                    &ps_node->as_cb_data[i],
361
0
                    u1_size / 2,
362
0
                    u1_posx / 2,
363
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
364
365
0
                ihevce_tu_node_data_init(
366
0
                    &ps_node->as_cr_data[i],
367
0
                    u1_size / 2,
368
0
                    u1_posx / 2,
369
0
                    !u1_is_422 ? u1_posy / 2 : u1_posy + i * u1_size);
370
0
            }
371
0
        }
372
0
    }
373
374
0
    if((u1_cur_depth >= u1_min_tree_depth) && (u1_cur_depth <= u1_max_tree_depth))
375
0
    {
376
0
        ps_node->u1_is_valid_node = 1;
377
0
    }
378
0
    else
379
0
    {
380
0
        ps_node->u1_is_valid_node = 0;
381
0
    }
382
383
0
    u2_num_nodes_initialised++;
384
385
0
    if((u1_cur_depth < u1_max_tree_depth) && (u1_size > MIN_TU_SIZE))
386
0
    {
387
0
        ps_node->ps_child_node_tl = ps_childNodeTL;
388
0
        ps_node->ps_child_node_tr = ps_childNodeTR;
389
0
        ps_node->ps_child_node_bl = ps_childNodeBL;
390
0
        ps_node->ps_child_node_br = ps_childNodeBR;
391
392
0
        u2_num_nodes_initialised += ihevce_tu_node_init(
393
0
            ps_root,
394
0
            u1_size / 2,
395
0
            ps_node->s_luma_data.u1_posx,
396
0
            ps_node->s_luma_data.u1_posy,
397
0
            u1_cur_depth + 1,
398
0
            u1_min_tree_depth,
399
0
            u1_max_tree_depth,
400
0
            u1_chroma_processing_enabled,
401
0
            u1_is_422,
402
0
            POS_TL);
403
404
0
        u2_num_nodes_initialised += ihevce_tu_node_init(
405
0
            ps_root,
406
0
            u1_size / 2,
407
0
            ps_node->s_luma_data.u1_posx,
408
0
            ps_node->s_luma_data.u1_posy,
409
0
            u1_cur_depth + 1,
410
0
            u1_min_tree_depth,
411
0
            u1_max_tree_depth,
412
0
            u1_chroma_processing_enabled,
413
0
            u1_is_422,
414
0
            POS_TR);
415
416
0
        u2_num_nodes_initialised += ihevce_tu_node_init(
417
0
            ps_root,
418
0
            u1_size / 2,
419
0
            ps_node->s_luma_data.u1_posx,
420
0
            ps_node->s_luma_data.u1_posy,
421
0
            u1_cur_depth + 1,
422
0
            u1_min_tree_depth,
423
0
            u1_max_tree_depth,
424
0
            u1_chroma_processing_enabled,
425
0
            u1_is_422,
426
0
            POS_BL);
427
428
0
        u2_num_nodes_initialised += ihevce_tu_node_init(
429
0
            ps_root,
430
0
            u1_size / 2,
431
0
            ps_node->s_luma_data.u1_posx,
432
0
            ps_node->s_luma_data.u1_posy,
433
0
            u1_cur_depth + 1,
434
0
            u1_min_tree_depth,
435
0
            u1_max_tree_depth,
436
0
            u1_chroma_processing_enabled,
437
0
            u1_is_422,
438
0
            POS_BR);
439
0
    }
440
0
    else
441
0
    {
442
0
        ps_node->ps_child_node_tl = NULL;
443
0
        ps_node->ps_child_node_tr = NULL;
444
0
        ps_node->ps_child_node_bl = NULL;
445
0
        ps_node->ps_child_node_br = NULL;
446
0
    }
447
448
0
    return u2_num_nodes_initialised;
449
0
}
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
*/
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
0
{
470
0
    UWORD16 u2_num_nodes = 0;
471
472
0
    ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
473
474
0
    u2_num_nodes += ihevce_tu_node_init(
475
0
        ps_root,
476
0
        u1_cu_size,
477
0
        0,
478
0
        0,
479
0
        0,
480
0
        u1_min_tree_depth,
481
0
        u1_max_tree_depth,
482
0
        u1_chroma_processing_enabled,
483
0
        u1_is_422,
484
0
        POS_TL);
485
486
0
    return u2_num_nodes;
487
0
}
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
*/
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
0
{
505
0
    UWORD32 u4_bits = 0;
506
507
0
    u4_bits += gau2_ihevce_cabac_bin_to_bits[pu1_cabac_ctxt[u1_cabac_state_idx] ^ u1_bin_value];
508
0
    pu1_cabac_ctxt[u1_cabac_state_idx] =
509
0
        gau1_ihevc_next_state[(pu1_cabac_ctxt[u1_cabac_state_idx] << 1) | u1_bin_value];
510
511
0
    return u4_bits;
512
0
}
513
514
static tu_tree_node_t *
515
    ihevce_tu_node_parent_finder(tu_tree_node_t *ps_root, tu_tree_node_t *ps_leaf)
516
0
{
517
0
    UWORD8 u1_depth_of_leaf;
518
519
0
    GETRANGE(u1_depth_of_leaf, ps_root->s_luma_data.u1_size / ps_leaf->s_luma_data.u1_size);
520
0
    u1_depth_of_leaf--;
521
522
0
    if(0 == u1_depth_of_leaf)
523
0
    {
524
0
        return NULL;
525
0
    }
526
0
    else if(1 == u1_depth_of_leaf)
527
0
    {
528
0
        return ps_root;
529
0
    }
530
0
    else
531
0
    {
532
0
        UWORD8 u1_switch_conditional =
533
0
            (ps_leaf->s_luma_data.u1_posx >= ps_root->ps_child_node_tl->s_luma_data.u1_size) +
534
0
            (ps_leaf->s_luma_data.u1_posy >= ps_root->ps_child_node_tl->s_luma_data.u1_size) * 2;
535
536
0
        ASSERT(NULL != ps_root->ps_child_node_tl);
537
0
        ASSERT(NULL != ps_root->ps_child_node_tr);
538
0
        ASSERT(NULL != ps_root->ps_child_node_bl);
539
0
        ASSERT(NULL != ps_root->ps_child_node_br);
540
541
0
        switch(u1_switch_conditional)
542
0
        {
543
0
        case 0:
544
0
        {
545
0
            return ihevce_tu_node_parent_finder(ps_root->ps_child_node_tl, ps_leaf);
546
0
        }
547
0
        case 1:
548
0
        {
549
0
            return ihevce_tu_node_parent_finder(ps_root->ps_child_node_tr, ps_leaf);
550
0
        }
551
0
        case 2:
552
0
        {
553
0
            return ihevce_tu_node_parent_finder(ps_root->ps_child_node_bl, ps_leaf);
554
0
        }
555
0
        case 3:
556
0
        {
557
0
            return ihevce_tu_node_parent_finder(ps_root->ps_child_node_br, ps_leaf);
558
0
        }
559
0
        }
560
0
    }
561
562
0
    return NULL;
563
0
}
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
*/
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
0
{
600
0
    UWORD8 u1_cabac_state_idx;
601
0
    UWORD8 u1_log2_tu_size;
602
603
0
    UWORD32 u4_num_bits = 0;
604
0
    UWORD8 u1_tu_size = ps_leaf->s_luma_data.u1_size;
605
606
0
    ASSERT(u1_min_tu_size >= MIN_TU_SIZE);
607
0
    ASSERT(u1_min_tu_size <= u1_max_tu_size);
608
0
    ASSERT(u1_max_tu_size <= MAX_TU_SIZE);
609
0
    ASSERT(u1_tu_size >= MIN_TU_SIZE);
610
0
    ASSERT(u1_tu_size <= MAX_TU_SIZE);
611
0
    ASSERT(u1_cur_depth <= u1_max_depth);
612
613
0
    GETRANGE(u1_log2_tu_size, u1_tu_size);
614
615
0
    if((ps_root->s_luma_data.u1_size >> u1_cur_depth) == u1_tu_size)
616
0
    {
617
0
        if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
618
0
           (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
619
0
        {
620
0
            u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
621
0
            u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
622
0
                pu1_cabac_ctxt, u1_cabac_state_idx, 0);
623
0
        }
624
625
0
        if(u1_chroma_processing_enabled && (u1_tu_size > 4))
626
0
        {
627
0
            tu_tree_node_t *ps_parent = ihevce_tu_node_parent_finder(ps_root, ps_leaf);
628
629
0
            u1_cabac_state_idx = IHEVC_CAB_CBCR_IDX + u1_cur_depth;
630
631
0
            if(!u1_cur_depth || ps_parent->as_cb_data[0].u1_cbf || ps_parent->as_cb_data[1].u1_cbf)
632
0
            {
633
0
                if(u1_is_422)
634
0
                {
635
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
636
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
637
638
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
639
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[1].u1_cbf);
640
0
                }
641
0
                else
642
0
                {
643
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
644
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
645
0
                }
646
0
            }
647
648
0
            if(!u1_cur_depth || ps_parent->as_cr_data[0].u1_cbf || ps_parent->as_cr_data[1].u1_cbf)
649
0
            {
650
0
                if(u1_is_422)
651
0
                {
652
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
653
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
654
655
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
656
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[1].u1_cbf);
657
0
                }
658
0
                else
659
0
                {
660
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
661
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
662
0
                }
663
0
            }
664
0
        }
665
666
0
        if(u1_is_intra || u1_cur_depth)
667
0
        {
668
0
            u1_cabac_state_idx = IHEVC_CAB_CBF_LUMA_IDX + !u1_cur_depth;
669
0
            u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
670
0
                pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->s_luma_data.u1_cbf);
671
0
        }
672
0
    }
673
0
    else
674
0
    {
675
0
        if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
676
0
           (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
677
0
        {
678
0
            u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
679
0
            u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
680
0
                pu1_cabac_ctxt, u1_cabac_state_idx, 1);
681
0
        }
682
683
0
        if(u1_chroma_processing_enabled && (u1_tu_size > 4))
684
0
        {
685
0
            tu_tree_node_t *ps_parent = ihevce_tu_node_parent_finder(ps_root, ps_leaf);
686
687
0
            u1_cabac_state_idx = IHEVC_CAB_CBCR_IDX + u1_cur_depth;
688
689
0
            if(!u1_cur_depth || ps_parent->as_cb_data[0].u1_cbf || ps_parent->as_cb_data[1].u1_cbf)
690
0
            {
691
0
                if(u1_is_422 && (8 == u1_tu_size))
692
0
                {
693
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
694
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[0].u1_cbf);
695
696
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
697
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cb_data[1].u1_cbf);
698
0
                }
699
0
                else
700
0
                {
701
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
702
0
                        pu1_cabac_ctxt,
703
0
                        u1_cabac_state_idx,
704
0
                        ps_leaf->as_cb_data[0].u1_cbf || ps_leaf->as_cb_data[1].u1_cbf);
705
0
                }
706
0
            }
707
708
0
            if(!u1_cur_depth || ps_parent->as_cr_data[0].u1_cbf || ps_parent->as_cr_data[1].u1_cbf)
709
0
            {
710
0
                if(u1_is_422 && (8 == u1_tu_size))
711
0
                {
712
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
713
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[0].u1_cbf);
714
715
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
716
0
                        pu1_cabac_ctxt, u1_cabac_state_idx, ps_leaf->as_cr_data[1].u1_cbf);
717
0
                }
718
0
                else
719
0
                {
720
0
                    u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
721
0
                        pu1_cabac_ctxt,
722
0
                        u1_cabac_state_idx,
723
0
                        ps_leaf->as_cr_data[0].u1_cbf || ps_leaf->as_cr_data[1].u1_cbf);
724
0
                }
725
0
            }
726
0
        }
727
0
    }
728
729
0
    return u4_num_bits;
730
0
}
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
*/
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
0
{
769
0
    UWORD8 u1_is_recon_available;
770
771
0
    void *pv_src = ps_buffer_data->s_src_pred_rec_buf_luma.pv_src;
772
0
    void *pv_pred = ps_buffer_data->s_src_pred_rec_buf_luma.pv_pred;
773
0
    void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
774
0
    WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
775
0
    UWORD8 *pu1_ecd = ps_buffer_data->ppu1_ecd[0];
776
0
    WORD32 i4_src_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_src_stride;
777
0
    WORD32 i4_pred_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_pred_stride;
778
0
    WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
779
0
    WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
780
0
    UWORD8 u1_size = ps_node->s_luma_data.u1_size;
781
0
    UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
782
0
    UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
783
0
    WORD32 trans_size = (64 == u1_size) ? 32 : u1_size;
784
0
    UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
785
786
0
    (void)pu1_cabac_ctxt;
787
0
    {
788
0
        pv_src = ((UWORD8 *)pv_src) + u1_posx + u1_posy * i4_src_stride;
789
0
        pv_pred = ((UWORD8 *)pv_pred) + u1_posx + u1_posy * i4_pred_stride;
790
0
        pv_recon = ((UWORD8 *)pv_recon) + u1_posx + u1_posy * i4_recon_stride;
791
0
    }
792
793
0
    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
0
    if((ps_ctxt->i4_quant_rounding_level == TU_LEVEL_QUANT_ROUNDING) &&
805
0
       (ps_node->s_luma_data.u1_posx || ps_node->s_luma_data.u1_posy))
806
0
    {
807
0
        double i4_lamda_modifier;
808
809
0
        if((BSLICE == ps_ctxt->i1_slice_type) && (ps_ctxt->i4_temporal_layer_id))
810
0
        {
811
0
            i4_lamda_modifier = ps_ctxt->i4_lamda_modifier *
812
0
                                CLIP3((((double)(ps_ctxt->i4_cu_qp - 12)) / 6.0), 2.00, 4.00);
813
0
        }
814
0
        else
815
0
        {
816
0
            i4_lamda_modifier = ps_ctxt->i4_lamda_modifier;
817
0
        }
818
0
        if(ps_ctxt->i4_use_const_lamda_modifier)
819
0
        {
820
0
            if(ISLICE == ps_ctxt->i1_slice_type)
821
0
            {
822
0
                i4_lamda_modifier = ps_ctxt->f_i_pic_lamda_modifier;
823
0
            }
824
0
            else
825
0
            {
826
0
                i4_lamda_modifier = CONST_LAMDA_MOD_VAL;
827
0
            }
828
0
        }
829
0
        ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3] = &ps_ctxt->i4_quant_round_tu[0][0];
830
0
        ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3] = &ps_ctxt->i4_quant_round_tu[1][0];
831
832
0
        memset(
833
0
            ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3],
834
0
            0,
835
0
            trans_size * trans_size * sizeof(WORD32));
836
0
        memset(
837
0
            ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3],
838
0
            0,
839
0
            trans_size * trans_size * sizeof(WORD32));
840
841
0
        ihevce_quant_rounding_factor_gen(
842
0
            trans_size,
843
0
            1,
844
0
            &ps_ctxt->s_rdopt_entropy_ctxt,
845
0
            ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3],
846
0
            ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3],
847
0
            i4_lamda_modifier,
848
0
            1);
849
0
    }
850
0
    else
851
0
    {
852
0
        ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3] =
853
0
            ps_ctxt->pi4_quant_round_factor_cu_ctb_0_1[trans_size >> 3];
854
0
        ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3] =
855
0
            ps_ctxt->pi4_quant_round_factor_cu_ctb_1_2[trans_size >> 3];
856
0
    }
857
858
0
#if ENABLE_INTER_ZCU_COST
859
0
    ps_ctxt->i8_cu_not_coded_cost = 0;
860
0
#endif
861
862
0
    {
863
0
        ps_node->s_luma_data.u1_cbf = ihevce_t_q_iq_ssd_scan_fxn(
864
0
            ps_ctxt,
865
0
            (UWORD8 *)pv_pred,
866
0
            i4_pred_stride,
867
0
            (UWORD8 *)pv_src,
868
0
            i4_src_stride,
869
0
            pi2_deq_data,
870
0
            i4_deq_data_stride,
871
0
            (UWORD8 *)pv_recon,
872
0
            i4_recon_stride,
873
0
            pu1_ecd,
874
0
            ps_ctxt->au1_cu_csbf,
875
0
            ps_ctxt->i4_cu_csbf_strd,
876
0
            u1_size,
877
0
            i4_pred_mode,
878
0
            &ps_node->s_luma_data.i8_ssd,
879
0
            &ps_node->s_luma_data.i4_num_bytes_used_for_ecd,
880
0
            &ps_node->s_luma_data.i4_bits,
881
0
            &ps_node->s_luma_data.u4_sad,
882
0
            &ps_node->s_luma_data.i4_zero_col,
883
0
            &ps_node->s_luma_data.i4_zero_row,
884
0
            &u1_is_recon_available,
885
0
            ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
886
0
            ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
887
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
888
0
            i4_alpha_stim_multiplier,
889
0
            u1_is_cu_noisy,
890
0
#endif
891
0
            u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
892
0
            1);
893
0
    }
894
895
0
#if ENABLE_INTER_ZCU_COST
896
0
    ps_node->s_luma_data.i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
897
0
#endif
898
899
0
    if(u1_compute_spatial_ssd && u1_is_recon_available)
900
0
    {
901
0
        ps_node->s_luma_data.u1_reconBufId = 0;
902
0
    }
903
0
    else
904
0
    {
905
0
        ps_node->s_luma_data.u1_reconBufId = UCHAR_MAX;
906
0
    }
907
908
0
    ps_node->s_luma_data.i8_cost =
909
0
        ps_node->s_luma_data.i8_ssd +
910
0
        COMPUTE_RATE_COST_CLIP30(
911
0
            ps_node->s_luma_data.i4_bits, ps_ctxt->i8_cl_ssd_lambda_qf, LAMBDA_Q_SHIFT);
912
913
0
    pu1_ecd += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
914
915
0
    if(u1_chroma_processing_enabled &&
916
0
       ((!(u1_posx % 8) && !(u1_posy % 8) && (4 == u1_size)) || (u1_size > 4)))
917
0
    {
918
0
        UWORD8 i;
919
0
        void *pv_chroma_src;
920
0
        void *pv_chroma_pred;
921
0
        void *pv_chroma_recon;
922
0
        WORD16 *pi2_deq_data_chroma;
923
924
0
        WORD32 i4_chroma_src_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_src_stride;
925
0
        WORD32 i4_chroma_pred_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_pred_stride;
926
0
        WORD32 i4_chroma_recon_stride = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
927
0
        WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
928
929
        /* SubTU loop */
930
0
        for(i = 0; i < u1_is_422 + 1; i++)
931
0
        {
932
0
            UWORD8 u1_chroma_size = ps_node->as_cb_data[i].u1_size;
933
0
            UWORD8 u1_chroma_posx = ps_node->as_cb_data[i].u1_posx;
934
0
            UWORD8 u1_chroma_posy = ps_node->as_cb_data[i].u1_posy;
935
936
0
#if ENABLE_INTER_ZCU_COST
937
0
            ps_ctxt->i8_cu_not_coded_cost = 0;
938
0
#endif
939
940
0
            pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma + (u1_chroma_posx * 2) +
941
0
                                  u1_chroma_posy * i4_deq_data_stride_chroma;
942
943
0
            {
944
0
                pv_chroma_src = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_src) +
945
0
                                (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_src_stride;
946
0
                pv_chroma_pred = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_pred) +
947
0
                                 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_pred_stride;
948
0
                pv_chroma_recon = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon) +
949
0
                                  (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_recon_stride;
950
951
0
                ps_node->as_cb_data[i].u1_cbf = ihevce_chroma_t_q_iq_ssd_scan_fxn(
952
0
                    ps_ctxt,
953
0
                    (UWORD8 *)pv_chroma_pred,
954
0
                    i4_chroma_pred_stride,
955
0
                    (UWORD8 *)pv_chroma_src,
956
0
                    i4_chroma_src_stride,
957
0
                    pi2_deq_data_chroma,
958
0
                    i4_deq_data_stride_chroma,
959
0
                    (UWORD8 *)pv_chroma_recon,
960
0
                    i4_chroma_recon_stride,
961
0
                    pu1_ecd,
962
0
                    ps_ctxt->au1_cu_csbf,
963
0
                    ps_ctxt->i4_cu_csbf_strd,
964
0
                    u1_chroma_size,
965
0
                    SCAN_DIAG_UPRIGHT,
966
0
                    0,
967
0
                    &ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd,
968
0
                    &ps_node->as_cb_data[i].i4_bits,
969
0
                    &ps_node->as_cb_data[i].i4_zero_col,
970
0
                    &ps_node->as_cb_data[i].i4_zero_row,
971
0
                    &u1_is_recon_available,
972
0
                    ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
973
0
                    ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
974
0
                    &ps_node->as_cb_data[i].i8_ssd,
975
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
976
0
                    i4_alpha_stim_multiplier,
977
0
                    u1_is_cu_noisy,
978
0
#endif
979
0
                    i4_pred_mode == PRED_MODE_SKIP,
980
0
                    u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
981
0
                    U_PLANE);
982
0
            }
983
984
0
#if ENABLE_INTER_ZCU_COST
985
0
            ps_node->as_cb_data[i].i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
986
0
#endif
987
988
0
            if(u1_compute_spatial_ssd && u1_is_recon_available)
989
0
            {
990
0
                ps_node->as_cb_data[i].u1_reconBufId = 0;
991
0
            }
992
0
            else
993
0
            {
994
0
                ps_node->as_cb_data[i].u1_reconBufId = UCHAR_MAX;
995
0
            }
996
997
0
            ps_node->as_cb_data[i].i8_cost =
998
0
                ps_node->as_cb_data[i].i8_ssd + COMPUTE_RATE_COST_CLIP30(
999
0
                                                    ps_node->as_cb_data[i].i4_bits,
1000
0
                                                    ps_ctxt->i8_cl_ssd_lambda_chroma_qf,
1001
0
                                                    LAMBDA_Q_SHIFT);
1002
1003
0
#if WEIGH_CHROMA_COST
1004
0
            ps_node->as_cb_data[i].i8_cost =
1005
0
                (ps_node->as_cb_data[i].i8_cost * ps_ctxt->u4_chroma_cost_weighing_factor +
1006
0
                 (1 << (CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT - 1))) >>
1007
0
                CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT;
1008
0
#endif
1009
1010
0
            pu1_ecd += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1011
0
        }
1012
1013
0
        for(i = 0; i < u1_is_422 + 1; i++)
1014
0
        {
1015
0
            UWORD8 u1_chroma_size = ps_node->as_cr_data[i].u1_size;
1016
0
            UWORD8 u1_chroma_posx = ps_node->as_cr_data[i].u1_posx;
1017
0
            UWORD8 u1_chroma_posy = ps_node->as_cr_data[i].u1_posy;
1018
1019
0
#if ENABLE_INTER_ZCU_COST
1020
0
            ps_ctxt->i8_cu_not_coded_cost = 0;
1021
0
#endif
1022
1023
0
            pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma + u1_chroma_size +
1024
0
                                  (u1_chroma_posx * 2) + u1_chroma_posy * i4_deq_data_stride_chroma;
1025
1026
0
            {
1027
0
                pv_chroma_src = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_src) +
1028
0
                                (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_src_stride;
1029
0
                pv_chroma_pred = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_pred) +
1030
0
                                 (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_pred_stride;
1031
0
                pv_chroma_recon = ((UWORD8 *)ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon) +
1032
0
                                  (u1_chroma_posx * 2) + u1_chroma_posy * i4_chroma_recon_stride;
1033
1034
0
                ps_node->as_cr_data[i].u1_cbf = ihevce_chroma_t_q_iq_ssd_scan_fxn(
1035
0
                    ps_ctxt,
1036
0
                    (UWORD8 *)pv_chroma_pred,
1037
0
                    i4_chroma_pred_stride,
1038
0
                    (UWORD8 *)pv_chroma_src,
1039
0
                    i4_chroma_src_stride,
1040
0
                    pi2_deq_data_chroma,
1041
0
                    i4_deq_data_stride_chroma,
1042
0
                    (UWORD8 *)pv_chroma_recon,
1043
0
                    i4_chroma_recon_stride,
1044
0
                    pu1_ecd,
1045
0
                    ps_ctxt->au1_cu_csbf,
1046
0
                    ps_ctxt->i4_cu_csbf_strd,
1047
0
                    u1_chroma_size,
1048
0
                    SCAN_DIAG_UPRIGHT,
1049
0
                    0,
1050
0
                    &ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd,
1051
0
                    &ps_node->as_cr_data[i].i4_bits,
1052
0
                    &ps_node->as_cr_data[i].i4_zero_col,
1053
0
                    &ps_node->as_cr_data[i].i4_zero_row,
1054
0
                    &u1_is_recon_available,
1055
0
                    ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
1056
0
                    ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
1057
0
                    &ps_node->as_cr_data[i].i8_ssd,
1058
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1059
0
                    i4_alpha_stim_multiplier,
1060
0
                    u1_is_cu_noisy,
1061
0
#endif
1062
0
                    i4_pred_mode == PRED_MODE_SKIP,
1063
0
                    u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
1064
0
                    V_PLANE);
1065
0
            }
1066
1067
0
#if ENABLE_INTER_ZCU_COST
1068
0
            ps_node->as_cr_data[i].i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
1069
0
#endif
1070
1071
0
            if(u1_compute_spatial_ssd && u1_is_recon_available)
1072
0
            {
1073
0
                ps_node->as_cr_data[i].u1_reconBufId = 0;
1074
0
            }
1075
0
            else
1076
0
            {
1077
0
                ps_node->as_cr_data[i].u1_reconBufId = UCHAR_MAX;
1078
0
            }
1079
1080
0
            ps_node->as_cr_data[i].i8_cost =
1081
0
                ps_node->as_cr_data[i].i8_ssd + COMPUTE_RATE_COST_CLIP30(
1082
0
                                                    ps_node->as_cr_data[i].i4_bits,
1083
0
                                                    ps_ctxt->i8_cl_ssd_lambda_chroma_qf,
1084
0
                                                    LAMBDA_Q_SHIFT);
1085
1086
0
#if WEIGH_CHROMA_COST
1087
0
            ps_node->as_cr_data[i].i8_cost =
1088
0
                (ps_node->as_cr_data[i].i8_cost * ps_ctxt->u4_chroma_cost_weighing_factor +
1089
0
                 (1 << (CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT - 1))) >>
1090
0
                CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT;
1091
0
#endif
1092
1093
0
            pu1_ecd += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1094
0
        }
1095
0
    }
1096
0
}
1097
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
0
{
1107
0
    WORD32 i, j;
1108
1109
0
    UWORD8 u1_num_4x4_in_tu = u1_size / 4;
1110
1111
0
    ps_nbr_data_buf += ((u1_posx) / 4) + (u1_posy / 4) * i4_nbr_data_buf_stride;
1112
1113
0
    for(i = 0; i < u1_num_4x4_in_tu; i++)
1114
0
    {
1115
0
        for(j = 0; j < u1_num_4x4_in_tu; j++)
1116
0
        {
1117
0
            ps_nbr_data_buf[j].b8_qp = i4_cu_qp;
1118
0
            ps_nbr_data_buf[j].b1_y_cbf = u1_cbf;
1119
0
        }
1120
1121
0
        ps_nbr_data_buf += i4_nbr_data_buf_stride;
1122
0
    }
1123
0
}
1124
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
0
{
1157
0
    UWORD8 i;
1158
1159
0
    UWORD32 u4_num_ecd_bytes = 0;
1160
1161
    /* Y */
1162
0
    {
1163
0
        UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
1164
0
        UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
1165
0
        UWORD8 *pu1_deq_data_dst =
1166
0
            (UWORD8 *)(pi2_deq_data_dst + u1_posx + u1_posy * i4_deq_data_dst_stride);
1167
0
        UWORD8 *pu1_deq_data_src =
1168
0
            (UWORD8 *)(pi2_deq_data_src + u1_posx + u1_posy * i4_deq_data_src_stride);
1169
0
        UWORD8 *pu1_recon_dst;
1170
0
        UWORD8 *pu1_recon_src;
1171
1172
0
        {
1173
0
            pu1_recon_dst = (((UWORD8 *)pv_recon_dst) + u1_posx + u1_posy * i4_recon_dst_stride);
1174
0
            pu1_recon_src = (((UWORD8 *)pv_recon_src) + u1_posx + u1_posy * i4_recon_src_stride);
1175
0
        }
1176
0
        u4_num_ecd_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1177
1178
0
        if(ps_node->s_luma_data.u1_reconBufId != UCHAR_MAX)
1179
0
        {
1180
0
            pf_copy_2d(
1181
0
                pu1_recon_dst,
1182
0
                i4_recon_dst_stride * (u1_is_hbd + 1),
1183
0
                pu1_recon_src,
1184
0
                i4_recon_src_stride * (u1_is_hbd + 1),
1185
0
                ps_node->s_luma_data.u1_size * (u1_is_hbd + 1),
1186
0
                ps_node->s_luma_data.u1_size);
1187
0
        }
1188
0
        else if(ps_node->s_luma_data.u1_cbf)
1189
0
        {
1190
0
            pf_copy_2d(
1191
0
                pu1_deq_data_dst,
1192
0
                i4_deq_data_dst_stride * 2,
1193
0
                pu1_deq_data_src,
1194
0
                i4_deq_data_src_stride * 2,
1195
0
                ps_node->s_luma_data.u1_size * 2,
1196
0
                ps_node->s_luma_data.u1_size);
1197
0
        }
1198
0
    }
1199
1200
    /* Cb */
1201
0
    if(u1_chroma_processing_enabled)
1202
0
    {
1203
0
        for(i = 0; i < u1_is_422 + 1; i++)
1204
0
        {
1205
0
            UWORD8 u1_posx = ps_node->as_cb_data[i].u1_posx;
1206
0
            UWORD8 u1_posy = ps_node->as_cb_data[i].u1_posy;
1207
0
            UWORD8 *pu1_deq_data_dst =
1208
0
                (UWORD8
1209
0
                     *)(pi2_deq_data_dst_chroma + (u1_posx * 2) + (u1_posy * i4_deq_data_dst_stride_chroma));
1210
0
            UWORD8 *pu1_deq_data_src =
1211
0
                (UWORD8
1212
0
                     *)(pi2_deq_data_src_chroma + (u1_posx * 2) + (u1_posy * i4_deq_data_src_stride_chroma));
1213
0
            UWORD8 *pu1_recon_dst;
1214
0
            UWORD8 *pu1_recon_src;
1215
1216
0
            {
1217
0
                pu1_recon_dst =
1218
0
                    (((UWORD8 *)pv_recon_dst_chroma) + (u1_posx * 2) +
1219
0
                     u1_posy * i4_recon_dst_stride_chroma);
1220
0
                pu1_recon_src =
1221
0
                    (((UWORD8 *)pv_recon_src_chroma) + (u1_posx * 2) +
1222
0
                     u1_posy * i4_recon_src_stride_chroma);
1223
0
            }
1224
0
            u4_num_ecd_bytes += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1225
1226
0
            if(ps_node->as_cb_data[i].u1_reconBufId != UCHAR_MAX)
1227
0
            {
1228
0
                {
1229
0
                    pf_chroma_interleave_2d_copy(
1230
0
                        pu1_recon_src,
1231
0
                        i4_recon_src_stride_chroma * (u1_is_hbd + 1),
1232
0
                        pu1_recon_dst,
1233
0
                        i4_recon_dst_stride_chroma * (u1_is_hbd + 1),
1234
0
                        ps_node->as_cb_data[i].u1_size * (u1_is_hbd + 1),
1235
0
                        ps_node->as_cb_data[i].u1_size,
1236
0
                        U_PLANE);
1237
0
                }
1238
0
            }
1239
0
            else if(ps_node->as_cb_data[i].u1_cbf)
1240
0
            {
1241
0
                pf_copy_2d(
1242
0
                    pu1_deq_data_dst,
1243
0
                    i4_deq_data_dst_stride_chroma * 2,
1244
0
                    pu1_deq_data_src,
1245
0
                    i4_deq_data_src_stride_chroma * 2,
1246
0
                    ps_node->as_cb_data[i].u1_size * 2,
1247
0
                    ps_node->as_cb_data[i].u1_size);
1248
0
            }
1249
0
        }
1250
1251
        /* Cr */
1252
0
        for(i = 0; i < u1_is_422 + 1; i++)
1253
0
        {
1254
0
            UWORD8 u1_posx = ps_node->as_cr_data[i].u1_posx;
1255
0
            UWORD8 u1_posy = ps_node->as_cr_data[i].u1_posy;
1256
0
            UWORD8 *pu1_deq_data_dst =
1257
0
                (UWORD8
1258
0
                     *)(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
0
            UWORD8 *pu1_deq_data_src =
1260
0
                (UWORD8
1261
0
                     *)(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
0
            UWORD8 *pu1_recon_dst;
1263
0
            UWORD8 *pu1_recon_src;
1264
1265
0
            {
1266
0
                pu1_recon_dst =
1267
0
                    (((UWORD8 *)pv_recon_dst_chroma) + (u1_posx * 2) +
1268
0
                     u1_posy * i4_recon_dst_stride_chroma);
1269
0
                pu1_recon_src =
1270
0
                    (((UWORD8 *)pv_recon_src_chroma) + (u1_posx * 2) +
1271
0
                     u1_posy * i4_recon_src_stride_chroma);
1272
0
            }
1273
0
            u4_num_ecd_bytes += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1274
1275
0
            if(ps_node->as_cr_data[i].u1_reconBufId != UCHAR_MAX)
1276
0
            {
1277
0
                {
1278
0
                    pf_chroma_interleave_2d_copy(
1279
0
                        pu1_recon_src,
1280
0
                        i4_recon_src_stride_chroma * (u1_is_hbd + 1),
1281
0
                        pu1_recon_dst,
1282
0
                        i4_recon_dst_stride_chroma * (u1_is_hbd + 1),
1283
0
                        ps_node->as_cr_data[i].u1_size * (u1_is_hbd + 1),
1284
0
                        ps_node->as_cr_data[i].u1_size,
1285
0
                        V_PLANE);
1286
0
                }
1287
0
            }
1288
0
            else if(ps_node->as_cr_data[i].u1_cbf)
1289
0
            {
1290
0
                pf_copy_2d(
1291
0
                    pu1_deq_data_dst,
1292
0
                    i4_deq_data_dst_stride_chroma * 2,
1293
0
                    pu1_deq_data_src,
1294
0
                    i4_deq_data_src_stride_chroma * 2,
1295
0
                    ps_node->as_cr_data[i].u1_size * 2,
1296
0
                    ps_node->as_cr_data[i].u1_size);
1297
0
            }
1298
0
        }
1299
0
    }
1300
1301
0
    if(pu1_ecd_dst != pu1_ecd_src)
1302
0
    {
1303
0
        memmove(pu1_ecd_dst, pu1_ecd_src, u4_num_ecd_bytes);
1304
0
    }
1305
1306
0
    memcpy(pu1_cabac_ctxt_dst, pu1_cabac_ctxt_src, i4_cabac_state_table_size);
1307
1308
0
    ihevce_nbr_data_copier(
1309
0
        ps_nbr_data_buf,
1310
0
        i4_nbr_data_buf_stride,
1311
0
        i4_cu_qp,
1312
0
        ps_node->s_luma_data.u1_cbf,
1313
0
        ps_node->s_luma_data.u1_posx,
1314
0
        ps_node->s_luma_data.u1_posy,
1315
0
        ps_node->s_luma_data.u1_size);
1316
1317
0
    ps_node->ps_child_node_tl = NULL;
1318
0
    ps_node->ps_child_node_tr = NULL;
1319
0
    ps_node->ps_child_node_bl = NULL;
1320
0
    ps_node->ps_child_node_br = NULL;
1321
0
}
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
*/
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
0
{
1341
0
    UWORD8 i;
1342
1343
0
    UWORD32 u4_num_bytes = 0;
1344
1345
0
    if(u1_parent_has_won)
1346
0
    {
1347
0
        u4_num_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1348
1349
0
        if(u1_chroma_processing_enabled)
1350
0
        {
1351
0
            for(i = 0; i < u1_is_422 + 1; i++)
1352
0
            {
1353
0
                u4_num_bytes += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
1354
0
                u4_num_bytes += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
1355
0
            }
1356
0
        }
1357
0
    }
1358
0
    else
1359
0
    {
1360
0
        u4_num_bytes += ps_node->ps_child_node_tl->s_luma_data.i4_num_bytes_used_for_ecd;
1361
0
        u4_num_bytes += ps_node->ps_child_node_tr->s_luma_data.i4_num_bytes_used_for_ecd;
1362
0
        u4_num_bytes += ps_node->ps_child_node_bl->s_luma_data.i4_num_bytes_used_for_ecd;
1363
0
        u4_num_bytes += ps_node->ps_child_node_br->s_luma_data.i4_num_bytes_used_for_ecd;
1364
1365
0
        if(u1_chroma_processing_enabled)
1366
0
        {
1367
0
            for(i = 0; i < u1_is_422 + 1; i++)
1368
0
            {
1369
0
                u4_num_bytes += ps_node->ps_child_node_tl->as_cb_data[i].i4_num_bytes_used_for_ecd;
1370
0
                u4_num_bytes += ps_node->ps_child_node_tl->as_cr_data[i].i4_num_bytes_used_for_ecd;
1371
0
                u4_num_bytes += ps_node->ps_child_node_tr->as_cb_data[i].i4_num_bytes_used_for_ecd;
1372
0
                u4_num_bytes += ps_node->ps_child_node_tr->as_cr_data[i].i4_num_bytes_used_for_ecd;
1373
0
                u4_num_bytes += ps_node->ps_child_node_bl->as_cb_data[i].i4_num_bytes_used_for_ecd;
1374
0
                u4_num_bytes += ps_node->ps_child_node_bl->as_cr_data[i].i4_num_bytes_used_for_ecd;
1375
0
                u4_num_bytes += ps_node->ps_child_node_br->as_cb_data[i].i4_num_bytes_used_for_ecd;
1376
0
                u4_num_bytes += ps_node->ps_child_node_br->as_cr_data[i].i4_num_bytes_used_for_ecd;
1377
0
            }
1378
0
        }
1379
0
    }
1380
1381
0
    ppu1_ecd[0] = pu1_ecd_buf_ptr_at_t0 + u4_num_bytes;
1382
1383
0
    return u4_num_bytes;
1384
0
}
1385
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
0
{
1389
0
    UWORD8 i;
1390
1391
0
    LWORD64 i8_cost = 0;
1392
1393
0
    i8_cost += ps_node->s_luma_data.i8_cost;
1394
1395
0
    if(u1_chroma_processing_enabled)
1396
0
    {
1397
0
        for(i = 0; i < u1_is_422 + 1; i++)
1398
0
        {
1399
0
            i8_cost += ps_node->as_cb_data[i].i8_cost;
1400
0
            i8_cost += ps_node->as_cr_data[i].i8_cost;
1401
0
        }
1402
0
    }
1403
1404
0
    return i8_cost;
1405
0
}
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
*/
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
*/
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
0
{
1759
0
    UWORD8 au1_cabac_ctxt_backup[IHEVC_CAB_CTXT_END];
1760
0
    UWORD8 u1_are_children_available;
1761
0
    UWORD32 u4_tuSplitFlag_and_cbf_coding_bits;
1762
1763
0
    nbr_4x4_t *ps_nbr_data_buf = ps_buffer_data->ps_nbr_data_buf;
1764
1765
0
    void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
1766
0
    void *pv_recon_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon;
1767
0
    WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
1768
0
    WORD16 *pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma;
1769
0
    UWORD8 **ppu1_ecd = ps_buffer_data->ppu1_ecd;
1770
0
    WORD32 i4_nbr_data_buf_stride = ps_buffer_data->i4_nbr_data_buf_stride;
1771
0
    WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
1772
0
    WORD32 i4_recon_stride_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
1773
0
    WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
1774
0
    WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
1775
0
    UWORD8 *pu1_ecd_bPtr_backup_t1 = ppu1_ecd[0];
1776
0
    UWORD8 *pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1777
0
    LWORD64 i8_parent_cost = 0;
1778
0
    LWORD64 i8_child_cost = 0;
1779
0
    LWORD64 i8_winning_cost = 0;
1780
0
    UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
1781
1782
0
    ASSERT(ps_node != NULL);
1783
0
    ASSERT(
1784
0
        !(!ps_node->u1_is_valid_node &&
1785
0
          ((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
1786
0
           (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br))));
1787
1788
0
    u1_are_children_available =
1789
0
        !((NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
1790
0
          (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br)) &&
1791
0
        (ps_node->s_luma_data.u1_size > MIN_TU_SIZE);
1792
1793
0
    if(u1_are_children_available)
1794
0
    {
1795
0
        WORD16 ai2_deq_data_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1796
0
        UWORD16 au2_recon_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1797
1798
0
        UWORD8 u1_is_tu_coded = 0;
1799
1800
0
        if(ps_node->u1_is_valid_node)
1801
0
        {
1802
0
            buffer_data_for_tu_t s_buffer_data = ps_buffer_data[0];
1803
1804
0
            memcpy(au1_cabac_ctxt_backup, pu1_cabac_ctxt, sizeof(au1_cabac_ctxt_backup));
1805
1806
0
            s_buffer_data.pi2_deq_data = ai2_deq_data_backup;
1807
0
            s_buffer_data.i4_deq_data_stride = MAX_CU_SIZE;
1808
0
            s_buffer_data.pi2_deq_data_chroma = ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1809
0
            s_buffer_data.i4_deq_data_stride_chroma = MAX_CU_SIZE;
1810
0
            s_buffer_data.s_src_pred_rec_buf_luma.pv_recon = au2_recon_backup;
1811
0
            s_buffer_data.s_src_pred_rec_buf_luma.i4_recon_stride = MAX_CU_SIZE;
1812
0
            s_buffer_data.s_src_pred_rec_buf_chroma.pv_recon =
1813
0
                au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1814
0
            s_buffer_data.s_src_pred_rec_buf_chroma.i4_recon_stride = MAX_CU_SIZE;
1815
1816
0
            ihevce_tu_processor(
1817
0
                ps_ctxt,
1818
0
                ps_node,
1819
0
                &s_buffer_data,
1820
0
                au1_cabac_ctxt_backup,
1821
0
                i4_pred_mode,
1822
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1823
0
                i4_alpha_stim_multiplier,
1824
0
                u1_is_cu_noisy,
1825
0
#endif
1826
0
                u1_chroma_processing_enabled,
1827
0
                u1_compute_spatial_ssd);
1828
1829
0
            if(i4_pred_mode != PRED_MODE_SKIP)
1830
0
            {
1831
0
                u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1832
0
                    ps_node,
1833
0
                    ps_node,
1834
0
                    au1_cabac_ctxt_backup,
1835
0
                    MAX_TU_SIZE,
1836
0
                    MIN_TU_SIZE,
1837
0
                    0,
1838
0
                    (u1_cur_depth == u1_max_depth) ? 0 : 1,
1839
0
                    i4_pred_mode == PRED_MODE_INTRA,
1840
0
                    (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1841
0
                    u1_chroma_processing_enabled,
1842
0
                    u1_is_422);
1843
1844
0
                ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
1845
0
                    u4_tuSplitFlag_and_cbf_coding_bits,
1846
0
                    ps_ctxt->i8_cl_ssd_lambda_qf,
1847
0
                    (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1848
0
            }
1849
1850
0
            i8_parent_cost +=
1851
0
                ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
1852
1853
0
            ihevce_ecd_buffer_pointer_updater(
1854
0
                ps_node,
1855
0
                ppu1_ecd,
1856
0
                pu1_ecd_bPtr_backup_t1,
1857
0
                1,
1858
0
                u1_chroma_processing_enabled,
1859
0
                u1_is_422);
1860
0
        }
1861
0
        else
1862
0
        {
1863
0
            ps_node->s_luma_data.i8_cost = i8_parent_cost = LLONG_MAX;
1864
0
            ps_node->s_luma_data.i4_num_bytes_used_for_ecd = 0;
1865
0
        }
1866
1867
0
        u1_is_tu_coded |= ps_node->s_luma_data.u1_cbf;
1868
1869
0
        if(u1_chroma_processing_enabled)
1870
0
        {
1871
0
            UWORD8 i;
1872
1873
0
            for(i = 0; i < u1_is_422 + 1; i++)
1874
0
            {
1875
0
                u1_is_tu_coded |= ps_node->as_cb_data[i].u1_cbf;
1876
0
                u1_is_tu_coded |= ps_node->as_cr_data[i].u1_cbf;
1877
0
            }
1878
0
        }
1879
1880
0
        if(!ps_node->u1_is_valid_node || u1_is_tu_coded)
1881
0
        {
1882
0
            pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1883
1884
0
            if(i4_pred_mode != PRED_MODE_SKIP)
1885
0
            {
1886
0
                u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1887
0
                    ps_node,
1888
0
                    ps_node->ps_child_node_tl,
1889
0
                    pu1_cabac_ctxt,
1890
0
                    MAX_TU_SIZE,
1891
0
                    MIN_TU_SIZE,
1892
0
                    0,
1893
0
                    1,
1894
0
                    i4_pred_mode == PRED_MODE_INTRA,
1895
0
                    (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1896
0
                    u1_chroma_processing_enabled,
1897
0
                    u1_is_422);
1898
1899
0
                i8_child_cost += COMPUTE_RATE_COST_CLIP30(
1900
0
                    u4_tuSplitFlag_and_cbf_coding_bits,
1901
0
                    ps_ctxt->i8_cl_ssd_lambda_qf,
1902
0
                    (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1903
0
            }
1904
1905
0
            if(i8_child_cost < i8_parent_cost)
1906
0
            {
1907
0
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1908
0
                    ps_ctxt,
1909
0
                    ps_node->ps_child_node_tl,
1910
0
                    ps_buffer_data,
1911
0
                    pu1_cabac_ctxt,
1912
0
                    i4_pred_mode,
1913
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1914
0
                    i4_alpha_stim_multiplier,
1915
0
                    u1_is_cu_noisy,
1916
0
#endif
1917
0
                    u1_cur_depth,
1918
0
                    u1_max_depth,
1919
0
                    u1_part_type,
1920
0
                    u1_chroma_processing_enabled,
1921
0
                    u1_compute_spatial_ssd);
1922
1923
0
                ps_node->ps_child_node_tl->s_luma_data.i8_cost +=
1924
0
                    i8_child_cost - ps_node->ps_child_node_tl->s_luma_data.i8_cost;
1925
0
            }
1926
1927
0
            if(i8_child_cost < i8_parent_cost)
1928
0
            {
1929
0
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1930
0
                    ps_ctxt,
1931
0
                    ps_node->ps_child_node_tr,
1932
0
                    ps_buffer_data,
1933
0
                    pu1_cabac_ctxt,
1934
0
                    i4_pred_mode,
1935
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1936
0
                    i4_alpha_stim_multiplier,
1937
0
                    u1_is_cu_noisy,
1938
0
#endif
1939
0
                    u1_cur_depth,
1940
0
                    u1_max_depth,
1941
0
                    u1_part_type,
1942
0
                    u1_chroma_processing_enabled,
1943
0
                    u1_compute_spatial_ssd);
1944
0
            }
1945
1946
0
            if(i8_child_cost < i8_parent_cost)
1947
0
            {
1948
0
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1949
0
                    ps_ctxt,
1950
0
                    ps_node->ps_child_node_bl,
1951
0
                    ps_buffer_data,
1952
0
                    pu1_cabac_ctxt,
1953
0
                    i4_pred_mode,
1954
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1955
0
                    i4_alpha_stim_multiplier,
1956
0
                    u1_is_cu_noisy,
1957
0
#endif
1958
0
                    u1_cur_depth,
1959
0
                    u1_max_depth,
1960
0
                    u1_part_type,
1961
0
                    u1_chroma_processing_enabled,
1962
0
                    u1_compute_spatial_ssd);
1963
0
            }
1964
1965
0
            if(i8_child_cost < i8_parent_cost)
1966
0
            {
1967
0
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1968
0
                    ps_ctxt,
1969
0
                    ps_node->ps_child_node_br,
1970
0
                    ps_buffer_data,
1971
0
                    pu1_cabac_ctxt,
1972
0
                    i4_pred_mode,
1973
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1974
0
                    i4_alpha_stim_multiplier,
1975
0
                    u1_is_cu_noisy,
1976
0
#endif
1977
0
                    u1_cur_depth,
1978
0
                    u1_max_depth,
1979
0
                    u1_part_type,
1980
0
                    u1_chroma_processing_enabled,
1981
0
                    u1_compute_spatial_ssd);
1982
0
            }
1983
1984
0
            if(i8_parent_cost > i8_child_cost)
1985
0
            {
1986
0
                UWORD32 u4_num_bytes = ihevce_ecd_buffer_pointer_updater(
1987
0
                    ps_node,
1988
0
                    ppu1_ecd,
1989
0
                    pu1_ecd_bPtr_backup_t1,
1990
0
                    0,
1991
0
                    u1_chroma_processing_enabled,
1992
0
                    u1_is_422);
1993
1994
0
                if(pu1_ecd_bPtr_backup_t2 != pu1_ecd_bPtr_backup_t1)
1995
0
                {
1996
0
                    memmove(pu1_ecd_bPtr_backup_t1, pu1_ecd_bPtr_backup_t2, u4_num_bytes);
1997
0
                }
1998
1999
0
                ps_node->s_luma_data.i4_num_bytes_used_for_ecd = u4_num_bytes;
2000
0
                ps_node->as_cb_data[0].i4_num_bytes_used_for_ecd = 0;
2001
0
                ps_node->as_cb_data[1].i4_num_bytes_used_for_ecd = 0;
2002
0
                ps_node->as_cr_data[0].i4_num_bytes_used_for_ecd = 0;
2003
0
                ps_node->as_cr_data[1].i4_num_bytes_used_for_ecd = 0;
2004
2005
0
                ps_node->u1_is_valid_node = 0;
2006
2007
0
                i8_winning_cost = i8_child_cost;
2008
0
            }
2009
0
            else
2010
0
            {
2011
0
                ihevce_debriefer_when_parent_wins(
2012
0
                    ps_node,
2013
0
                    ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2014
0
                    ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2015
0
                    ps_nbr_data_buf,
2016
0
                    ai2_deq_data_backup,
2017
0
                    pi2_deq_data,
2018
0
                    ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2019
0
                    pi2_deq_data_chroma,
2020
0
                    au2_recon_backup,
2021
0
                    pv_recon,
2022
0
                    au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2023
0
                    pv_recon_chroma,
2024
0
                    au1_cabac_ctxt_backup,
2025
0
                    pu1_cabac_ctxt,
2026
0
                    NULL,
2027
0
                    NULL,
2028
0
                    i4_nbr_data_buf_stride,
2029
0
                    MAX_CU_SIZE,
2030
0
                    i4_deq_data_stride,
2031
0
                    MAX_CU_SIZE,
2032
0
                    i4_deq_data_stride_chroma,
2033
0
                    MAX_CU_SIZE,
2034
0
                    i4_recon_stride,
2035
0
                    MAX_CU_SIZE,
2036
0
                    i4_recon_stride_chroma,
2037
0
                    sizeof(au1_cabac_ctxt_backup),
2038
0
                    ps_ctxt->i4_cu_qp,
2039
0
                    u1_chroma_processing_enabled,
2040
0
                    u1_is_422,
2041
0
                    ps_ctxt->u1_bit_depth > 8);
2042
2043
0
                ihevce_ecd_buffer_pointer_updater(
2044
0
                    ps_node,
2045
0
                    ppu1_ecd,
2046
0
                    pu1_ecd_bPtr_backup_t1,
2047
0
                    1,
2048
0
                    u1_chroma_processing_enabled,
2049
0
                    u1_is_422);
2050
2051
0
                i8_winning_cost = i8_parent_cost;
2052
0
            }
2053
0
        }
2054
0
        else
2055
0
        {
2056
0
            ihevce_debriefer_when_parent_wins(
2057
0
                ps_node,
2058
0
                ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2059
0
                ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2060
0
                ps_nbr_data_buf,
2061
0
                ai2_deq_data_backup,
2062
0
                pi2_deq_data,
2063
0
                ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2064
0
                pi2_deq_data_chroma,
2065
0
                au2_recon_backup,
2066
0
                pv_recon,
2067
0
                au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2068
0
                pv_recon_chroma,
2069
0
                au1_cabac_ctxt_backup,
2070
0
                pu1_cabac_ctxt,
2071
0
                NULL,
2072
0
                NULL,
2073
0
                i4_nbr_data_buf_stride,
2074
0
                MAX_CU_SIZE,
2075
0
                i4_deq_data_stride,
2076
0
                MAX_CU_SIZE,
2077
0
                i4_deq_data_stride_chroma,
2078
0
                MAX_CU_SIZE,
2079
0
                i4_recon_stride,
2080
0
                MAX_CU_SIZE,
2081
0
                i4_recon_stride_chroma,
2082
0
                sizeof(au1_cabac_ctxt_backup),
2083
0
                ps_ctxt->i4_cu_qp,
2084
0
                u1_chroma_processing_enabled,
2085
0
                u1_is_422,
2086
0
                ps_ctxt->u1_bit_depth > 8);
2087
2088
0
            ihevce_ecd_buffer_pointer_updater(
2089
0
                ps_node,
2090
0
                ppu1_ecd,
2091
0
                pu1_ecd_bPtr_backup_t1,
2092
0
                1,
2093
0
                u1_chroma_processing_enabled,
2094
0
                u1_is_422);
2095
2096
0
            i8_winning_cost = i8_parent_cost;
2097
0
        }
2098
0
    }
2099
0
    else
2100
0
    {
2101
0
        ASSERT(ps_node->u1_is_valid_node);
2102
2103
0
        ihevce_tu_processor(
2104
0
            ps_ctxt,
2105
0
            ps_node,
2106
0
            ps_buffer_data,
2107
0
            pu1_cabac_ctxt,
2108
0
            i4_pred_mode,
2109
0
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
2110
0
            i4_alpha_stim_multiplier,
2111
0
            u1_is_cu_noisy,
2112
0
#endif
2113
0
            u1_chroma_processing_enabled,
2114
0
            u1_compute_spatial_ssd);
2115
2116
0
        if(i4_pred_mode != PRED_MODE_SKIP)
2117
0
        {
2118
0
            u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
2119
0
                ps_node,
2120
0
                ps_node,
2121
0
                pu1_cabac_ctxt,
2122
0
                MAX_TU_SIZE,
2123
0
                MIN_TU_SIZE,
2124
0
                0,
2125
0
                (u1_cur_depth == u1_max_depth) ? 0 : 1,
2126
0
                i4_pred_mode == PRED_MODE_INTRA,
2127
0
                (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
2128
0
                u1_chroma_processing_enabled,
2129
0
                u1_is_422);
2130
2131
0
            ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
2132
0
                u4_tuSplitFlag_and_cbf_coding_bits,
2133
0
                ps_ctxt->i8_cl_ssd_lambda_qf,
2134
0
                (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
2135
0
        }
2136
2137
0
        i8_winning_cost +=
2138
0
            ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
2139
2140
0
        ihevce_ecd_buffer_pointer_updater(
2141
0
            ps_node, ppu1_ecd, pu1_ecd_bPtr_backup_t1, 1, u1_chroma_processing_enabled, u1_is_422);
2142
2143
0
        ihevce_nbr_data_copier(
2144
0
            ps_nbr_data_buf,
2145
0
            i4_nbr_data_buf_stride,
2146
0
            ps_ctxt->i4_cu_qp,
2147
0
            ps_node->s_luma_data.u1_cbf,
2148
0
            ps_node->s_luma_data.u1_posx,
2149
0
            ps_node->s_luma_data.u1_posy,
2150
0
            ps_node->s_luma_data.u1_size);
2151
0
    }
2152
2153
0
    return i8_winning_cost;
2154
0
}
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
*/
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
0
{
2192
0
    UWORD8 u1_is_chroma_tu_valid = 1;
2193
0
    WORD32 i4_log2_size;
2194
2195
0
    ASSERT(ps_node != NULL);
2196
2197
0
    if(ps_node->u1_is_valid_node)
2198
0
    {
2199
0
        ASSERT(
2200
0
            (NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
2201
0
            (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br));
2202
0
    }
2203
0
    else
2204
0
    {
2205
0
        ASSERT(
2206
0
            !((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
2207
0
              (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br)));
2208
0
    }
2209
2210
0
    if(ps_node->u1_is_valid_node)
2211
0
    {
2212
0
        if((4 == ps_node->s_luma_data.u1_size) && (POS_TL != e_tu_pos))
2213
0
        {
2214
0
            u1_is_chroma_tu_valid = INTRA_PRED_CHROMA_IDX_NONE;
2215
0
        }
2216
2217
0
        GETRANGE(i4_log2_size, ps_node->s_luma_data.u1_size);
2218
2219
0
        ps_final_prms->s_recon_datastore.au1_bufId_with_winning_LumaRecon[pu2_tu_ctr[0]] =
2220
0
            ps_node->s_luma_data.u1_reconBufId;
2221
0
        ps_final_prms->u4_cu_sad += ps_node->s_luma_data.u4_sad;
2222
0
        ps_final_prms->u1_is_cu_coded |= ps_node->s_luma_data.u1_cbf;
2223
0
        ps_final_prms->u4_cu_luma_res_bits += ps_node->s_luma_data.i4_bits;
2224
2225
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].i4_luma_coeff_offset =
2226
0
            pi4_num_bytes_used_for_ecd[0];
2227
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_y_cbf = ps_node->s_luma_data.u1_cbf;
2228
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf = 0;
2229
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf = 0;
2230
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf_subtu1 = 0;
2231
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf_subtu1 = 0;
2232
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_chroma_intra_mode_idx =
2233
0
            u1_is_chroma_tu_valid;
2234
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b7_qp = i4_cu_qp;
2235
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_first_tu_in_cu =
2236
0
            (!ps_node->s_luma_data.u1_posx && !ps_node->s_luma_data.u1_posx);
2237
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_transquant_bypass = 0;
2238
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_size = i4_log2_size - 3;
2239
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_x =
2240
0
            (u1_cu_posx + ps_node->s_luma_data.u1_posx) / 4;
2241
0
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_y =
2242
0
            (u1_cu_posy + ps_node->s_luma_data.u1_posy) / 4;
2243
2244
0
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].i2_luma_bytes_consumed =
2245
0
            ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2246
0
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_col =
2247
0
            ps_node->s_luma_data.i4_zero_col;
2248
0
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_row =
2249
0
            ps_node->s_luma_data.i4_zero_row;
2250
2251
0
        pi8_total_cost[0] += ps_node->s_luma_data.i8_cost;
2252
0
        pi8_total_non_coded_cost[0] += ps_node->s_luma_data.i8_not_coded_cost;
2253
0
        pi4_num_bytes_used_for_ecd[0] += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2254
0
        pi4_num_bits_used_for_encoding[0] += ps_node->s_luma_data.i4_bits;
2255
2256
0
        if(u1_chroma_processing_enabled)
2257
0
        {
2258
0
            UWORD8 i;
2259
2260
0
            for(i = 0; i < u1_is_422 + 1; i++)
2261
0
            {
2262
0
                ps_final_prms->s_recon_datastore
2263
0
                    .au1_bufId_with_winning_ChromaRecon[U_PLANE][pu2_tu_ctr[0]][i] =
2264
0
                    ps_node->as_cb_data[i].u1_reconBufId;
2265
0
                ps_final_prms->u1_is_cu_coded |= ps_node->as_cb_data[i].u1_cbf;
2266
0
                ps_final_prms->u4_cu_chroma_res_bits += ps_node->as_cb_data[i].i4_bits;
2267
2268
0
                ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].ai4_cb_coeff_offset[i] =
2269
0
                    pi4_num_bytes_used_for_ecd[0];
2270
2271
0
                if(!i)
2272
0
                {
2273
0
                    ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf =
2274
0
                        ps_node->as_cb_data[i].u1_cbf;
2275
0
                }
2276
0
                else
2277
0
                {
2278
0
                    ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf_subtu1 =
2279
0
                        ps_node->as_cb_data[i].u1_cbf;
2280
0
                }
2281
2282
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].ai2_cb_bytes_consumed[i] =
2283
0
                    ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
2284
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cb_zero_col[i] =
2285
0
                    ps_node->as_cb_data[i].i4_zero_col;
2286
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cb_zero_row[i] =
2287
0
                    ps_node->as_cb_data[i].i4_zero_row;
2288
2289
0
                pi8_total_cost[0] += ps_node->as_cb_data[i].i8_cost;
2290
0
                pi8_total_non_coded_cost[0] += ps_node->as_cb_data[i].i8_not_coded_cost;
2291
0
                pi4_num_bytes_used_for_ecd[0] += ps_node->as_cb_data[i].i4_num_bytes_used_for_ecd;
2292
0
                pi4_num_bits_used_for_encoding[0] += ps_node->as_cb_data[i].i4_bits;
2293
0
            }
2294
2295
0
            for(i = 0; i < u1_is_422 + 1; i++)
2296
0
            {
2297
0
                ps_final_prms->s_recon_datastore
2298
0
                    .au1_bufId_with_winning_ChromaRecon[V_PLANE][pu2_tu_ctr[0]][i] =
2299
0
                    ps_node->as_cr_data[i].u1_reconBufId;
2300
0
                ps_final_prms->u1_is_cu_coded |= ps_node->as_cr_data[i].u1_cbf;
2301
0
                ps_final_prms->u4_cu_chroma_res_bits += ps_node->as_cr_data[i].i4_bits;
2302
2303
0
                ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].ai4_cr_coeff_offset[i] =
2304
0
                    pi4_num_bytes_used_for_ecd[0];
2305
2306
0
                if(!i)
2307
0
                {
2308
0
                    ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf =
2309
0
                        ps_node->as_cr_data[i].u1_cbf;
2310
0
                }
2311
0
                else
2312
0
                {
2313
0
                    ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf_subtu1 =
2314
0
                        ps_node->as_cr_data[i].u1_cbf;
2315
0
                }
2316
2317
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].ai2_cr_bytes_consumed[i] =
2318
0
                    ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
2319
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cr_zero_col[i] =
2320
0
                    ps_node->as_cr_data[i].i4_zero_col;
2321
0
                ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].au4_cr_zero_row[i] =
2322
0
                    ps_node->as_cr_data[i].i4_zero_row;
2323
2324
0
                pi8_total_cost[0] += ps_node->as_cr_data[i].i8_cost;
2325
0
                pi8_total_non_coded_cost[0] += ps_node->as_cr_data[i].i8_not_coded_cost;
2326
0
                pi4_num_bytes_used_for_ecd[0] += ps_node->as_cr_data[i].i4_num_bytes_used_for_ecd;
2327
0
                pi4_num_bits_used_for_encoding[0] += ps_node->as_cr_data[i].i4_bits;
2328
0
            }
2329
0
        }
2330
2331
0
        pu2_tu_ctr[0]++;
2332
0
    }
2333
0
    else
2334
0
    {
2335
0
        ihevce_tu_selector_debriefer(
2336
0
            ps_node->ps_child_node_tl,
2337
0
            ps_final_prms,
2338
0
            pi8_total_cost,
2339
0
            pi8_total_non_coded_cost,
2340
0
            pi4_num_bytes_used_for_ecd,
2341
0
            pi4_num_bits_used_for_encoding,
2342
0
            pu2_tu_ctr,
2343
0
            i4_cu_qp,
2344
0
            u1_cu_posx,
2345
0
            u1_cu_posy,
2346
0
            u1_chroma_processing_enabled,
2347
0
            u1_is_422,
2348
0
            POS_TL);
2349
2350
0
        ihevce_tu_selector_debriefer(
2351
0
            ps_node->ps_child_node_tr,
2352
0
            ps_final_prms,
2353
0
            pi8_total_cost,
2354
0
            pi8_total_non_coded_cost,
2355
0
            pi4_num_bytes_used_for_ecd,
2356
0
            pi4_num_bits_used_for_encoding,
2357
0
            pu2_tu_ctr,
2358
0
            i4_cu_qp,
2359
0
            u1_cu_posx,
2360
0
            u1_cu_posy,
2361
0
            u1_chroma_processing_enabled,
2362
0
            u1_is_422,
2363
0
            POS_TR);
2364
2365
0
        ihevce_tu_selector_debriefer(
2366
0
            ps_node->ps_child_node_bl,
2367
0
            ps_final_prms,
2368
0
            pi8_total_cost,
2369
0
            pi8_total_non_coded_cost,
2370
0
            pi4_num_bytes_used_for_ecd,
2371
0
            pi4_num_bits_used_for_encoding,
2372
0
            pu2_tu_ctr,
2373
0
            i4_cu_qp,
2374
0
            u1_cu_posx,
2375
0
            u1_cu_posy,
2376
0
            u1_chroma_processing_enabled,
2377
0
            u1_is_422,
2378
0
            POS_BL);
2379
2380
0
        ihevce_tu_selector_debriefer(
2381
0
            ps_node->ps_child_node_br,
2382
0
            ps_final_prms,
2383
0
            pi8_total_cost,
2384
0
            pi8_total_non_coded_cost,
2385
0
            pi4_num_bytes_used_for_ecd,
2386
0
            pi4_num_bits_used_for_encoding,
2387
0
            pu2_tu_ctr,
2388
0
            i4_cu_qp,
2389
0
            u1_cu_posx,
2390
0
            u1_cu_posy,
2391
0
            u1_chroma_processing_enabled,
2392
0
            u1_is_422,
2393
0
            POS_BR);
2394
0
    }
2395
0
}
2396
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
0
{
2400
0
    UWORD8 u1_is_split = 0;
2401
2402
0
    UWORD8 u1_tuSplitArrayIndex = 0;
2403
0
    UWORD8 u1_bit_index = 0;
2404
2405
0
    switch(u1_cu_size)
2406
0
    {
2407
0
    case 8:
2408
0
    {
2409
0
        switch(u1_tu_size)
2410
0
        {
2411
0
        case 8:
2412
0
        {
2413
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2414
2415
0
            break;
2416
0
        }
2417
0
        case 4:
2418
0
        {
2419
0
            u1_is_split = 0;
2420
2421
0
            break;
2422
0
        }
2423
0
        }
2424
2425
0
        break;
2426
0
    }
2427
0
    case 16:
2428
0
    {
2429
0
        switch(u1_tu_size)
2430
0
        {
2431
0
        case 16:
2432
0
        {
2433
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2434
2435
0
            break;
2436
0
        }
2437
0
        case 8:
2438
0
        {
2439
0
            u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2440
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2441
2442
0
            break;
2443
0
        }
2444
0
        case 4:
2445
0
        {
2446
0
            u1_is_split = 0;
2447
2448
0
            break;
2449
0
        }
2450
0
        }
2451
2452
0
        break;
2453
0
    }
2454
0
    case 32:
2455
0
    {
2456
0
        switch(u1_tu_size)
2457
0
        {
2458
0
        case 32:
2459
0
        {
2460
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2461
2462
0
            break;
2463
0
        }
2464
0
        case 16:
2465
0
        {
2466
0
            u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2467
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2468
2469
0
            break;
2470
0
        }
2471
0
        case 8:
2472
0
        {
2473
0
            u1_bit_index = 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2474
0
            u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2475
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2476
2477
0
            break;
2478
0
        }
2479
0
        case 4:
2480
0
        {
2481
0
            u1_is_split = 0;
2482
2483
0
            break;
2484
0
        }
2485
0
        }
2486
2487
0
        break;
2488
0
    }
2489
0
    case 64:
2490
0
    {
2491
0
        switch(u1_tu_size)
2492
0
        {
2493
0
        case 64:
2494
0
        {
2495
0
            u1_is_split = 1;
2496
2497
0
            break;
2498
0
        }
2499
0
        case 32:
2500
0
        {
2501
0
            u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2502
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2503
2504
0
            break;
2505
0
        }
2506
0
        case 16:
2507
0
        {
2508
0
            u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2509
0
            u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2510
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2511
2512
0
            break;
2513
0
        }
2514
0
        case 8:
2515
0
        {
2516
0
            u1_tuSplitArrayIndex = ((u1_posx / 32) % 2) + 2 * ((u1_posy / 32) % 2);
2517
0
            u1_bit_index += 5 * ((u1_posx / 16) % 2) + 10 * ((u1_posy / 16) % 2) + 1;
2518
0
            u1_bit_index += ((u1_posx / 8) % 2) + 2 * ((u1_posy / 8) % 2) + 1;
2519
0
            u1_is_split = !!(ai4_tuSplitArray[u1_tuSplitArrayIndex] & BIT_EN(u1_bit_index));
2520
2521
0
            break;
2522
0
        }
2523
0
        case 4:
2524
0
        {
2525
0
            u1_is_split = 0;
2526
2527
0
            break;
2528
0
        }
2529
0
        }
2530
2531
0
        break;
2532
0
    }
2533
0
    }
2534
2535
0
    return u1_is_split;
2536
0
}
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
*/
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
0
{
2563
0
    UWORD8 u1_is_split;
2564
2565
0
    ASSERT(u1_min_tu_size >= MIN_TU_SIZE);
2566
0
    ASSERT(u1_max_tu_size <= MAX_TU_SIZE);
2567
0
    ASSERT(u1_min_tu_size <= u1_max_tu_size);
2568
2569
0
    ASSERT(!u1_is_skip);
2570
2571
0
    ASSERT(ps_root != NULL);
2572
0
    ASSERT(ps_root->s_luma_data.u1_size == u1_tu_size);
2573
2574
0
    if(u1_tu_size <= u1_max_tu_size)
2575
0
    {
2576
0
        ASSERT(ps_root->u1_is_valid_node);
2577
0
    }
2578
0
    else
2579
0
    {
2580
0
        ASSERT(!ps_root->u1_is_valid_node);
2581
0
    }
2582
2583
0
    if(u1_tu_size > u1_min_tu_size)
2584
0
    {
2585
0
        ASSERT(ps_root->ps_child_node_tl != NULL);
2586
0
        ASSERT(ps_root->ps_child_node_tr != NULL);
2587
0
        ASSERT(ps_root->ps_child_node_bl != NULL);
2588
0
        ASSERT(ps_root->ps_child_node_br != NULL);
2589
0
        ASSERT(ps_root->ps_child_node_tl->s_luma_data.u1_size == (u1_tu_size / 2));
2590
0
        ASSERT(ps_root->ps_child_node_tr->s_luma_data.u1_size == (u1_tu_size / 2));
2591
0
        ASSERT(ps_root->ps_child_node_bl->s_luma_data.u1_size == (u1_tu_size / 2));
2592
0
        ASSERT(ps_root->ps_child_node_br->s_luma_data.u1_size == (u1_tu_size / 2));
2593
0
        ASSERT(ps_root->ps_child_node_tl->u1_is_valid_node);
2594
0
        ASSERT(ps_root->ps_child_node_tr->u1_is_valid_node);
2595
0
        ASSERT(ps_root->ps_child_node_bl->u1_is_valid_node);
2596
0
        ASSERT(ps_root->ps_child_node_br->u1_is_valid_node);
2597
0
    }
2598
0
    else
2599
0
    {
2600
0
        ASSERT(ps_root->ps_child_node_tl == NULL);
2601
0
        ASSERT(ps_root->ps_child_node_tr == NULL);
2602
0
        ASSERT(ps_root->ps_child_node_bl == NULL);
2603
0
        ASSERT(ps_root->ps_child_node_br == NULL);
2604
0
    }
2605
2606
0
    u1_is_split = ihevce_get_curTUSplit_from_TUSplitArray(
2607
0
        ai4_tuSplitArray,
2608
0
        u1_cu_size,
2609
0
        u1_tu_size,
2610
0
        ps_root->s_luma_data.u1_posx,
2611
0
        ps_root->s_luma_data.u1_posy);
2612
2613
0
    if(u1_tu_size == u1_min_tu_size)
2614
0
    {
2615
0
        ASSERT(!u1_is_split);
2616
0
    }
2617
2618
0
    if(u1_is_split)
2619
0
    {
2620
0
        ps_root->u1_is_valid_node = 0;
2621
2622
0
        ihevce_tuSplitArray_to_tuTree_mapper(
2623
0
            ps_root->ps_child_node_tl,
2624
0
            ai4_tuSplitArray,
2625
0
            u1_cu_size,
2626
0
            ps_root->ps_child_node_tl->s_luma_data.u1_size,
2627
0
            u1_min_tu_size,
2628
0
            u1_max_tu_size,
2629
0
            u1_is_skip);
2630
2631
0
        ihevce_tuSplitArray_to_tuTree_mapper(
2632
0
            ps_root->ps_child_node_tr,
2633
0
            ai4_tuSplitArray,
2634
0
            u1_cu_size,
2635
0
            ps_root->ps_child_node_tr->s_luma_data.u1_size,
2636
0
            u1_min_tu_size,
2637
0
            u1_max_tu_size,
2638
0
            u1_is_skip);
2639
2640
0
        ihevce_tuSplitArray_to_tuTree_mapper(
2641
0
            ps_root->ps_child_node_bl,
2642
0
            ai4_tuSplitArray,
2643
0
            u1_cu_size,
2644
0
            ps_root->ps_child_node_bl->s_luma_data.u1_size,
2645
0
            u1_min_tu_size,
2646
0
            u1_max_tu_size,
2647
0
            u1_is_skip);
2648
2649
0
        ihevce_tuSplitArray_to_tuTree_mapper(
2650
0
            ps_root->ps_child_node_br,
2651
0
            ai4_tuSplitArray,
2652
0
            u1_cu_size,
2653
0
            ps_root->ps_child_node_br->s_luma_data.u1_size,
2654
0
            u1_min_tu_size,
2655
0
            u1_max_tu_size,
2656
0
            u1_is_skip);
2657
0
    }
2658
0
    else
2659
0
    {
2660
0
        ps_root->ps_child_node_tl = NULL;
2661
0
        ps_root->ps_child_node_tr = NULL;
2662
0
        ps_root->ps_child_node_bl = NULL;
2663
0
        ps_root->ps_child_node_br = NULL;
2664
0
    }
2665
0
}