Coverage Report

Created: 2026-05-30 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/encoder/ihevce_tu_tree_selector.c
Line
Count
Source
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
185k
{
109
185k
    WORD32 i4_tu_tree_area = 0;
110
111
185k
    if(ps_node->u1_is_valid_node)
112
184k
    {
113
184k
        i4_tu_tree_area += ps_node->s_luma_data.u1_size * ps_node->s_luma_data.u1_size;
114
184k
    }
115
987
    else
116
987
    {
117
987
        if(NULL != ps_node->ps_child_node_tl)
118
987
        {
119
987
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tl);
120
987
        }
121
122
987
        if(NULL != ps_node->ps_child_node_tr)
123
987
        {
124
987
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_tr);
125
987
        }
126
127
987
        if(NULL != ps_node->ps_child_node_bl)
128
987
        {
129
987
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_bl);
130
987
        }
131
132
987
        if(NULL != ps_node->ps_child_node_br)
133
987
        {
134
987
            i4_tu_tree_area += ihevce_tu_tree_coverage_in_cu(ps_node->ps_child_node_br);
135
987
        }
136
987
    }
137
138
185k
    return i4_tu_tree_area;
139
185k
}
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
1.45M
{
144
1.45M
    ps_tu_data->u1_size = u1_size;
145
1.45M
    ps_tu_data->i8_ssd = 0;
146
1.45M
    ps_tu_data->i8_cost = 0;
147
1.45M
#if ENABLE_INTER_ZCU_COST
148
1.45M
    ps_tu_data->i8_not_coded_cost = 0;
149
1.45M
#endif
150
1.45M
    ps_tu_data->u4_sad = 0;
151
1.45M
    ps_tu_data->i4_bits = 0;
152
1.45M
    ps_tu_data->i4_num_bytes_used_for_ecd = 0;
153
1.45M
    ps_tu_data->u1_cbf = 0;
154
1.45M
    ps_tu_data->u1_reconBufId = UCHAR_MAX;
155
1.45M
    ps_tu_data->u1_posx = u1_posx;
156
1.45M
    ps_tu_data->u1_posy = u1_posy;
157
1.45M
}
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
1.45M
{
187
1.45M
    tu_tree_node_t *ps_node;
188
1.45M
    tu_tree_node_t *ps_childNodeTL;
189
1.45M
    tu_tree_node_t *ps_childNodeTR;
190
1.45M
    tu_tree_node_t *ps_childNodeBL;
191
1.45M
    tu_tree_node_t *ps_childNodeBR;
192
193
1.45M
    UWORD8 u1_start_index_for_parent = 0;
194
1.45M
    UWORD8 u1_start_index_for_child = 0;
195
1.45M
    UWORD16 u2_parent_offset = 0;
196
1.45M
    UWORD16 u2_child_offset = 0;
197
1.45M
    UWORD8 u1_posx = 0;
198
1.45M
    UWORD8 u1_posy = 0;
199
200
1.45M
    const UWORD8 u1_nxn_tu_node_start_index = 0;
201
1.45M
    const UWORD8 u1_nBye2xnBye2_tu_node_start_index = 1;
202
1.45M
    const UWORD8 u1_nBye4xnBye4_tu_node_start_index = 1 + 4;
203
1.45M
    const UWORD8 u1_nBye8xnBye8_tu_node_start_index = 1 + 4 + 16;
204
1.45M
    const UWORD8 u1_nBye16xnBye16_tu_node_start_index = 1 + 4 + 16 + 64;
205
1.45M
    UWORD16 u2_num_nodes_initialised = 0;
206
207
1.45M
    ASSERT(u1_cur_depth <= u1_max_tree_depth);
208
1.45M
    ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
209
210
1.45M
    switch(e_tu_pos)
211
1.45M
    {
212
499k
    case POS_TL:
213
499k
    {
214
499k
        u1_posx = u1_parent_posx;
215
499k
        u1_posy = u1_parent_posy;
216
217
499k
        break;
218
0
    }
219
317k
    case POS_TR:
220
317k
    {
221
317k
        u1_posx = u1_parent_posx + u1_size;
222
317k
        u1_posy = u1_parent_posy;
223
224
317k
        break;
225
0
    }
226
317k
    case POS_BL:
227
317k
    {
228
317k
        u1_posx = u1_parent_posx;
229
317k
        u1_posy = u1_parent_posy + u1_size;
230
231
317k
        break;
232
0
    }
233
317k
    case POS_BR:
234
317k
    {
235
317k
        u1_posx = u1_parent_posx + u1_size;
236
317k
        u1_posy = u1_parent_posy + u1_size;
237
238
317k
        break;
239
0
    }
240
0
    default:
241
0
    {
242
        /* Here be dragons */
243
0
        ASSERT(0);
244
0
    }
245
1.45M
    }
246
247
1.45M
    switch(u1_cur_depth)
248
1.45M
    {
249
181k
    case 0:
250
181k
    {
251
181k
        u1_start_index_for_parent = u1_nxn_tu_node_start_index;
252
181k
        u1_start_index_for_child = u1_nBye2xnBye2_tu_node_start_index;
253
254
181k
        u2_parent_offset = 0;
255
181k
        u2_child_offset = 0;
256
257
181k
        break;
258
0
    }
259
504k
    case 1:
260
504k
    {
261
504k
        u1_start_index_for_parent = u1_nBye2xnBye2_tu_node_start_index;
262
504k
        u1_start_index_for_child = u1_nBye4xnBye4_tu_node_start_index;
263
264
504k
        u2_parent_offset = e_tu_pos;
265
504k
        u2_child_offset = 4 * u1_posx / u1_size + 8 * u1_posy / u1_size;
266
267
504k
        break;
268
0
    }
269
469k
    case 2:
270
469k
    {
271
469k
        u1_start_index_for_parent = u1_nBye4xnBye4_tu_node_start_index;
272
469k
        u1_start_index_for_child = u1_nBye8xnBye8_tu_node_start_index;
273
274
469k
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 4 * u1_parent_posy / u1_size + e_tu_pos;
275
469k
        u2_child_offset = 4 * u1_posx / u1_size + 16 * u1_posy / u1_size;
276
277
469k
        break;
278
0
    }
279
250k
    case 3:
280
250k
    {
281
250k
        u1_start_index_for_parent = u1_nBye8xnBye8_tu_node_start_index;
282
250k
        u1_start_index_for_child = u1_nBye16xnBye16_tu_node_start_index;
283
284
250k
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 8 * u1_parent_posy / u1_size + e_tu_pos;
285
250k
        u2_child_offset = 4 * u1_posx / u1_size + 32 * u1_posy / u1_size;
286
287
250k
        break;
288
0
    }
289
45.5k
    case 4:
290
45.5k
    {
291
45.5k
        u1_start_index_for_parent = u1_nBye16xnBye16_tu_node_start_index;
292
45.5k
        u1_start_index_for_child = 0;
293
294
45.5k
        u2_parent_offset = 2 * u1_parent_posx / u1_size + 16 * u1_parent_posy / u1_size + e_tu_pos;
295
45.5k
        u2_child_offset = 0;
296
297
45.5k
        break;
298
0
    }
299
0
    default:
300
0
    {
301
        /* Here be dragons */
302
0
        ASSERT(0);
303
0
    }
304
1.45M
    }
305
306
1.45M
    ASSERT((u1_start_index_for_parent + u2_parent_offset) < (256 + 64 + 16 + 4 + 1));
307
1.45M
    ASSERT((u1_start_index_for_child + u2_child_offset + POS_BR) < (256 + 64 + 16 + 4 + 1));
308
309
1.45M
    ps_node = ps_root + u1_start_index_for_parent + u2_parent_offset;
310
1.45M
    ps_childNodeTL = ps_root + u1_start_index_for_child + u2_child_offset + POS_TL;
311
1.45M
    ps_childNodeTR = ps_root + u1_start_index_for_child + u2_child_offset + POS_TR;
312
1.45M
    ps_childNodeBL = ps_root + u1_start_index_for_child + u2_child_offset + POS_BL;
313
1.45M
    ps_childNodeBR = ps_root + u1_start_index_for_child + u2_child_offset + POS_BR;
314
315
1.45M
    ihevce_tu_node_data_init(&ps_node->s_luma_data, u1_size, u1_posx, u1_posy);
316
317
1.45M
    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
1.45M
    if((u1_cur_depth >= u1_min_tree_depth) && (u1_cur_depth <= u1_max_tree_depth))
375
1.45M
    {
376
1.45M
        ps_node->u1_is_valid_node = 1;
377
1.45M
    }
378
987
    else
379
987
    {
380
987
        ps_node->u1_is_valid_node = 0;
381
987
    }
382
383
1.45M
    u2_num_nodes_initialised++;
384
385
1.45M
    if((u1_cur_depth < u1_max_tree_depth) && (u1_size > MIN_TU_SIZE))
386
317k
    {
387
317k
        ps_node->ps_child_node_tl = ps_childNodeTL;
388
317k
        ps_node->ps_child_node_tr = ps_childNodeTR;
389
317k
        ps_node->ps_child_node_bl = ps_childNodeBL;
390
317k
        ps_node->ps_child_node_br = ps_childNodeBR;
391
392
317k
        u2_num_nodes_initialised += ihevce_tu_node_init(
393
317k
            ps_root,
394
317k
            u1_size / 2,
395
317k
            ps_node->s_luma_data.u1_posx,
396
317k
            ps_node->s_luma_data.u1_posy,
397
317k
            u1_cur_depth + 1,
398
317k
            u1_min_tree_depth,
399
317k
            u1_max_tree_depth,
400
317k
            u1_chroma_processing_enabled,
401
317k
            u1_is_422,
402
317k
            POS_TL);
403
404
317k
        u2_num_nodes_initialised += ihevce_tu_node_init(
405
317k
            ps_root,
406
317k
            u1_size / 2,
407
317k
            ps_node->s_luma_data.u1_posx,
408
317k
            ps_node->s_luma_data.u1_posy,
409
317k
            u1_cur_depth + 1,
410
317k
            u1_min_tree_depth,
411
317k
            u1_max_tree_depth,
412
317k
            u1_chroma_processing_enabled,
413
317k
            u1_is_422,
414
317k
            POS_TR);
415
416
317k
        u2_num_nodes_initialised += ihevce_tu_node_init(
417
317k
            ps_root,
418
317k
            u1_size / 2,
419
317k
            ps_node->s_luma_data.u1_posx,
420
317k
            ps_node->s_luma_data.u1_posy,
421
317k
            u1_cur_depth + 1,
422
317k
            u1_min_tree_depth,
423
317k
            u1_max_tree_depth,
424
317k
            u1_chroma_processing_enabled,
425
317k
            u1_is_422,
426
317k
            POS_BL);
427
428
317k
        u2_num_nodes_initialised += ihevce_tu_node_init(
429
317k
            ps_root,
430
317k
            u1_size / 2,
431
317k
            ps_node->s_luma_data.u1_posx,
432
317k
            ps_node->s_luma_data.u1_posy,
433
317k
            u1_cur_depth + 1,
434
317k
            u1_min_tree_depth,
435
317k
            u1_max_tree_depth,
436
317k
            u1_chroma_processing_enabled,
437
317k
            u1_is_422,
438
317k
            POS_BR);
439
317k
    }
440
1.13M
    else
441
1.13M
    {
442
1.13M
        ps_node->ps_child_node_tl = NULL;
443
1.13M
        ps_node->ps_child_node_tr = NULL;
444
1.13M
        ps_node->ps_child_node_bl = NULL;
445
1.13M
        ps_node->ps_child_node_br = NULL;
446
1.13M
    }
447
448
1.45M
    return u2_num_nodes_initialised;
449
1.45M
}
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
181k
{
470
181k
    UWORD16 u2_num_nodes = 0;
471
472
181k
    ASSERT(u1_max_tree_depth >= u1_min_tree_depth);
473
474
181k
    u2_num_nodes += ihevce_tu_node_init(
475
181k
        ps_root,
476
181k
        u1_cu_size,
477
181k
        0,
478
181k
        0,
479
181k
        0,
480
181k
        u1_min_tree_depth,
481
181k
        u1_max_tree_depth,
482
181k
        u1_chroma_processing_enabled,
483
181k
        u1_is_422,
484
181k
        POS_TL);
485
486
181k
    return u2_num_nodes;
487
181k
}
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
384k
{
505
384k
    UWORD32 u4_bits = 0;
506
507
384k
    u4_bits += gau2_ihevce_cabac_bin_to_bits[pu1_cabac_ctxt[u1_cabac_state_idx] ^ u1_bin_value];
508
384k
    pu1_cabac_ctxt[u1_cabac_state_idx] =
509
384k
        gau1_ihevc_next_state[(pu1_cabac_ctxt[u1_cabac_state_idx] << 1) | u1_bin_value];
510
511
384k
    return u4_bits;
512
384k
}
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
949k
{
600
949k
    UWORD8 u1_cabac_state_idx;
601
949k
    UWORD8 u1_log2_tu_size;
602
603
949k
    UWORD32 u4_num_bits = 0;
604
949k
    UWORD8 u1_tu_size = ps_leaf->s_luma_data.u1_size;
605
606
949k
    ASSERT(u1_min_tu_size >= MIN_TU_SIZE);
607
949k
    ASSERT(u1_min_tu_size <= u1_max_tu_size);
608
949k
    ASSERT(u1_max_tu_size <= MAX_TU_SIZE);
609
949k
    ASSERT(u1_tu_size >= MIN_TU_SIZE);
610
949k
    ASSERT(u1_tu_size <= MAX_TU_SIZE);
611
949k
    ASSERT(u1_cur_depth <= u1_max_depth);
612
613
949k
    GETRANGE(u1_log2_tu_size, u1_tu_size);
614
615
949k
    if((ps_root->s_luma_data.u1_size >> u1_cur_depth) == u1_tu_size)
616
780k
    {
617
780k
        if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
618
330k
           (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
619
330k
        {
620
330k
            u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
621
330k
            u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
622
330k
                pu1_cabac_ctxt, u1_cabac_state_idx, 0);
623
330k
        }
624
625
780k
        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
780k
        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
780k
    }
673
168k
    else
674
168k
    {
675
168k
        if((u1_tu_size <= u1_max_tu_size) && (u1_tu_size > u1_min_tu_size) &&
676
54.5k
           (u1_cur_depth < u1_max_depth) && !(u1_is_intra_nxn_pu && !u1_cur_depth))
677
54.5k
        {
678
54.5k
            u1_cabac_state_idx = IHEVC_CAB_SPLIT_TFM + (5 - u1_log2_tu_size);
679
54.5k
            u4_num_bits += ihevce_cabac_bins2Bits_converter_and_state_updater(
680
54.5k
                pu1_cabac_ctxt, u1_cabac_state_idx, 1);
681
54.5k
        }
682
683
168k
        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
168k
    }
728
729
949k
    return u4_num_bits;
730
949k
}
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
836k
{
769
836k
    UWORD8 u1_is_recon_available;
770
771
836k
    void *pv_src = ps_buffer_data->s_src_pred_rec_buf_luma.pv_src;
772
836k
    void *pv_pred = ps_buffer_data->s_src_pred_rec_buf_luma.pv_pred;
773
836k
    void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
774
836k
    WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
775
836k
    UWORD8 *pu1_ecd = ps_buffer_data->ppu1_ecd[0];
776
836k
    WORD32 i4_src_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_src_stride;
777
836k
    WORD32 i4_pred_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_pred_stride;
778
836k
    WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
779
836k
    WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
780
836k
    UWORD8 u1_size = ps_node->s_luma_data.u1_size;
781
836k
    UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
782
836k
    UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
783
836k
    WORD32 trans_size = (64 == u1_size) ? 32 : u1_size;
784
836k
    UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
785
786
836k
    (void)pu1_cabac_ctxt;
787
836k
    {
788
836k
        pv_src = ((UWORD8 *)pv_src) + u1_posx + u1_posy * i4_src_stride;
789
836k
        pv_pred = ((UWORD8 *)pv_pred) + u1_posx + u1_posy * i4_pred_stride;
790
836k
        pv_recon = ((UWORD8 *)pv_recon) + u1_posx + u1_posy * i4_recon_stride;
791
836k
    }
792
793
836k
    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
836k
    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
836k
    else
851
836k
    {
852
836k
        ps_ctxt->pi4_quant_round_factor_tu_0_1[trans_size >> 3] =
853
836k
            ps_ctxt->pi4_quant_round_factor_cu_ctb_0_1[trans_size >> 3];
854
836k
        ps_ctxt->pi4_quant_round_factor_tu_1_2[trans_size >> 3] =
855
836k
            ps_ctxt->pi4_quant_round_factor_cu_ctb_1_2[trans_size >> 3];
856
836k
    }
857
858
836k
#if ENABLE_INTER_ZCU_COST
859
836k
    ps_ctxt->i8_cu_not_coded_cost = 0;
860
836k
#endif
861
862
836k
    {
863
836k
        ps_node->s_luma_data.u1_cbf = ihevce_t_q_iq_ssd_scan_fxn(
864
836k
            ps_ctxt,
865
836k
            (UWORD8 *)pv_pred,
866
836k
            i4_pred_stride,
867
836k
            (UWORD8 *)pv_src,
868
836k
            i4_src_stride,
869
836k
            pi2_deq_data,
870
836k
            i4_deq_data_stride,
871
836k
            (UWORD8 *)pv_recon,
872
836k
            i4_recon_stride,
873
836k
            pu1_ecd,
874
836k
            ps_ctxt->au1_cu_csbf,
875
836k
            ps_ctxt->i4_cu_csbf_strd,
876
836k
            u1_size,
877
836k
            i4_pred_mode,
878
836k
            &ps_node->s_luma_data.i8_ssd,
879
836k
            &ps_node->s_luma_data.i4_num_bytes_used_for_ecd,
880
836k
            &ps_node->s_luma_data.i4_bits,
881
836k
            &ps_node->s_luma_data.u4_sad,
882
836k
            &ps_node->s_luma_data.i4_zero_col,
883
836k
            &ps_node->s_luma_data.i4_zero_row,
884
836k
            &u1_is_recon_available,
885
836k
            ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_rdoq,
886
836k
            ps_ctxt->s_rdoq_sbh_ctxt.i4_perform_all_cand_sbh,
887
836k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
888
836k
            i4_alpha_stim_multiplier,
889
836k
            u1_is_cu_noisy,
890
836k
#endif
891
836k
            u1_compute_spatial_ssd ? SPATIAL_DOMAIN_SSD : FREQUENCY_DOMAIN_SSD,
892
836k
            1);
893
836k
    }
894
895
836k
#if ENABLE_INTER_ZCU_COST
896
836k
    ps_node->s_luma_data.i8_not_coded_cost = ps_ctxt->i8_cu_not_coded_cost;
897
836k
#endif
898
899
836k
    if(u1_compute_spatial_ssd && u1_is_recon_available)
900
176k
    {
901
176k
        ps_node->s_luma_data.u1_reconBufId = 0;
902
176k
    }
903
660k
    else
904
660k
    {
905
660k
        ps_node->s_luma_data.u1_reconBufId = UCHAR_MAX;
906
660k
    }
907
908
836k
    ps_node->s_luma_data.i8_cost =
909
836k
        ps_node->s_luma_data.i8_ssd +
910
836k
        COMPUTE_RATE_COST_CLIP30(
911
836k
            ps_node->s_luma_data.i4_bits, ps_ctxt->i8_cl_ssd_lambda_qf, LAMBDA_Q_SHIFT);
912
913
836k
    pu1_ecd += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
914
915
836k
    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
836k
}
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
726k
{
1107
726k
    WORD32 i, j;
1108
1109
726k
    UWORD8 u1_num_4x4_in_tu = u1_size / 4;
1110
1111
726k
    ps_nbr_data_buf += ((u1_posx) / 4) + (u1_posy / 4) * i4_nbr_data_buf_stride;
1112
1113
1.98M
    for(i = 0; i < u1_num_4x4_in_tu; i++)
1114
1.26M
    {
1115
4.82M
        for(j = 0; j < u1_num_4x4_in_tu; j++)
1116
3.55M
        {
1117
3.55M
            ps_nbr_data_buf[j].b8_qp = i4_cu_qp;
1118
3.55M
            ps_nbr_data_buf[j].b1_y_cbf = u1_cbf;
1119
3.55M
        }
1120
1121
1.26M
        ps_nbr_data_buf += i4_nbr_data_buf_stride;
1122
1.26M
    }
1123
726k
}
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
130k
{
1157
130k
    UWORD8 i;
1158
1159
130k
    UWORD32 u4_num_ecd_bytes = 0;
1160
1161
    /* Y */
1162
130k
    {
1163
130k
        UWORD8 u1_posx = ps_node->s_luma_data.u1_posx;
1164
130k
        UWORD8 u1_posy = ps_node->s_luma_data.u1_posy;
1165
130k
        UWORD8 *pu1_deq_data_dst =
1166
130k
            (UWORD8 *)(pi2_deq_data_dst + u1_posx + u1_posy * i4_deq_data_dst_stride);
1167
130k
        UWORD8 *pu1_deq_data_src =
1168
130k
            (UWORD8 *)(pi2_deq_data_src + u1_posx + u1_posy * i4_deq_data_src_stride);
1169
130k
        UWORD8 *pu1_recon_dst;
1170
130k
        UWORD8 *pu1_recon_src;
1171
1172
130k
        {
1173
130k
            pu1_recon_dst = (((UWORD8 *)pv_recon_dst) + u1_posx + u1_posy * i4_recon_dst_stride);
1174
130k
            pu1_recon_src = (((UWORD8 *)pv_recon_src) + u1_posx + u1_posy * i4_recon_src_stride);
1175
130k
        }
1176
130k
        u4_num_ecd_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1177
1178
130k
        if(ps_node->s_luma_data.u1_reconBufId != UCHAR_MAX)
1179
52.7k
        {
1180
52.7k
            pf_copy_2d(
1181
52.7k
                pu1_recon_dst,
1182
52.7k
                i4_recon_dst_stride * (u1_is_hbd + 1),
1183
52.7k
                pu1_recon_src,
1184
52.7k
                i4_recon_src_stride * (u1_is_hbd + 1),
1185
52.7k
                ps_node->s_luma_data.u1_size * (u1_is_hbd + 1),
1186
52.7k
                ps_node->s_luma_data.u1_size);
1187
52.7k
        }
1188
77.8k
        else if(ps_node->s_luma_data.u1_cbf)
1189
49.9k
        {
1190
49.9k
            pf_copy_2d(
1191
49.9k
                pu1_deq_data_dst,
1192
49.9k
                i4_deq_data_dst_stride * 2,
1193
49.9k
                pu1_deq_data_src,
1194
49.9k
                i4_deq_data_src_stride * 2,
1195
49.9k
                ps_node->s_luma_data.u1_size * 2,
1196
49.9k
                ps_node->s_luma_data.u1_size);
1197
49.9k
        }
1198
130k
    }
1199
1200
    /* Cb */
1201
130k
    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
130k
    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
130k
    memcpy(pu1_cabac_ctxt_dst, pu1_cabac_ctxt_src, i4_cabac_state_table_size);
1307
1308
130k
    ihevce_nbr_data_copier(
1309
130k
        ps_nbr_data_buf,
1310
130k
        i4_nbr_data_buf_stride,
1311
130k
        i4_cu_qp,
1312
130k
        ps_node->s_luma_data.u1_cbf,
1313
130k
        ps_node->s_luma_data.u1_posx,
1314
130k
        ps_node->s_luma_data.u1_posy,
1315
130k
        ps_node->s_luma_data.u1_size);
1316
1317
130k
    ps_node->ps_child_node_tl = NULL;
1318
130k
    ps_node->ps_child_node_tr = NULL;
1319
130k
    ps_node->ps_child_node_bl = NULL;
1320
130k
    ps_node->ps_child_node_br = NULL;
1321
130k
}
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
1.07M
{
1341
1.07M
    UWORD8 i;
1342
1343
1.07M
    UWORD32 u4_num_bytes = 0;
1344
1345
1.07M
    if(u1_parent_has_won)
1346
967k
    {
1347
967k
        u4_num_bytes += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
1348
1349
967k
        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
967k
    }
1358
111k
    else
1359
111k
    {
1360
111k
        u4_num_bytes += ps_node->ps_child_node_tl->s_luma_data.i4_num_bytes_used_for_ecd;
1361
111k
        u4_num_bytes += ps_node->ps_child_node_tr->s_luma_data.i4_num_bytes_used_for_ecd;
1362
111k
        u4_num_bytes += ps_node->ps_child_node_bl->s_luma_data.i4_num_bytes_used_for_ecd;
1363
111k
        u4_num_bytes += ps_node->ps_child_node_br->s_luma_data.i4_num_bytes_used_for_ecd;
1364
1365
111k
        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
111k
    }
1380
1381
1.07M
    ppu1_ecd[0] = pu1_ecd_buf_ptr_at_t0 + u4_num_bytes;
1382
1383
1.07M
    return u4_num_bytes;
1384
1.07M
}
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
836k
{
1389
836k
    UWORD8 i;
1390
1391
836k
    LWORD64 i8_cost = 0;
1392
1393
836k
    i8_cost += ps_node->s_luma_data.i8_cost;
1394
1395
836k
    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
836k
    return i8_cost;
1405
836k
}
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
837k
{
1759
837k
    UWORD8 au1_cabac_ctxt_backup[IHEVC_CAB_CTXT_END];
1760
837k
    UWORD8 u1_are_children_available;
1761
837k
    UWORD32 u4_tuSplitFlag_and_cbf_coding_bits;
1762
1763
837k
    nbr_4x4_t *ps_nbr_data_buf = ps_buffer_data->ps_nbr_data_buf;
1764
1765
837k
    void *pv_recon = ps_buffer_data->s_src_pred_rec_buf_luma.pv_recon;
1766
837k
    void *pv_recon_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.pv_recon;
1767
837k
    WORD16 *pi2_deq_data = ps_buffer_data->pi2_deq_data;
1768
837k
    WORD16 *pi2_deq_data_chroma = ps_buffer_data->pi2_deq_data_chroma;
1769
837k
    UWORD8 **ppu1_ecd = ps_buffer_data->ppu1_ecd;
1770
837k
    WORD32 i4_nbr_data_buf_stride = ps_buffer_data->i4_nbr_data_buf_stride;
1771
837k
    WORD32 i4_recon_stride = ps_buffer_data->s_src_pred_rec_buf_luma.i4_recon_stride;
1772
837k
    WORD32 i4_recon_stride_chroma = ps_buffer_data->s_src_pred_rec_buf_chroma.i4_recon_stride;
1773
837k
    WORD32 i4_deq_data_stride = ps_buffer_data->i4_deq_data_stride;
1774
837k
    WORD32 i4_deq_data_stride_chroma = ps_buffer_data->i4_deq_data_stride_chroma;
1775
837k
    UWORD8 *pu1_ecd_bPtr_backup_t1 = ppu1_ecd[0];
1776
837k
    UWORD8 *pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1777
837k
    LWORD64 i8_parent_cost = 0;
1778
837k
    LWORD64 i8_child_cost = 0;
1779
837k
    LWORD64 i8_winning_cost = 0;
1780
837k
    UWORD8 u1_is_422 = (ps_ctxt->u1_chroma_array_type == 2);
1781
1782
837k
    ASSERT(ps_node != NULL);
1783
837k
    ASSERT(
1784
837k
        !(!ps_node->u1_is_valid_node &&
1785
837k
          ((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
1786
837k
           (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br))));
1787
1788
837k
    u1_are_children_available =
1789
837k
        !((NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
1790
595k
          (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br)) &&
1791
241k
        (ps_node->s_luma_data.u1_size > MIN_TU_SIZE);
1792
1793
837k
    if(u1_are_children_available)
1794
241k
    {
1795
241k
        WORD16 ai2_deq_data_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1796
241k
        UWORD16 au2_recon_backup[MAX_CU_SIZE * MAX_CU_SIZE * 2];
1797
1798
241k
        UWORD8 u1_is_tu_coded = 0;
1799
1800
241k
        if(ps_node->u1_is_valid_node)
1801
240k
        {
1802
240k
            buffer_data_for_tu_t s_buffer_data = ps_buffer_data[0];
1803
1804
240k
            memcpy(au1_cabac_ctxt_backup, pu1_cabac_ctxt, sizeof(au1_cabac_ctxt_backup));
1805
1806
240k
            s_buffer_data.pi2_deq_data = ai2_deq_data_backup;
1807
240k
            s_buffer_data.i4_deq_data_stride = MAX_CU_SIZE;
1808
240k
            s_buffer_data.pi2_deq_data_chroma = ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1809
240k
            s_buffer_data.i4_deq_data_stride_chroma = MAX_CU_SIZE;
1810
240k
            s_buffer_data.s_src_pred_rec_buf_luma.pv_recon = au2_recon_backup;
1811
240k
            s_buffer_data.s_src_pred_rec_buf_luma.i4_recon_stride = MAX_CU_SIZE;
1812
240k
            s_buffer_data.s_src_pred_rec_buf_chroma.pv_recon =
1813
240k
                au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE;
1814
240k
            s_buffer_data.s_src_pred_rec_buf_chroma.i4_recon_stride = MAX_CU_SIZE;
1815
1816
240k
            ihevce_tu_processor(
1817
240k
                ps_ctxt,
1818
240k
                ps_node,
1819
240k
                &s_buffer_data,
1820
240k
                au1_cabac_ctxt_backup,
1821
240k
                i4_pred_mode,
1822
240k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1823
240k
                i4_alpha_stim_multiplier,
1824
240k
                u1_is_cu_noisy,
1825
240k
#endif
1826
240k
                u1_chroma_processing_enabled,
1827
240k
                u1_compute_spatial_ssd);
1828
1829
240k
            if(i4_pred_mode != PRED_MODE_SKIP)
1830
240k
            {
1831
240k
                u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1832
240k
                    ps_node,
1833
240k
                    ps_node,
1834
240k
                    au1_cabac_ctxt_backup,
1835
240k
                    MAX_TU_SIZE,
1836
240k
                    MIN_TU_SIZE,
1837
240k
                    0,
1838
240k
                    (u1_cur_depth == u1_max_depth) ? 0 : 1,
1839
240k
                    i4_pred_mode == PRED_MODE_INTRA,
1840
240k
                    (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1841
240k
                    u1_chroma_processing_enabled,
1842
240k
                    u1_is_422);
1843
1844
240k
                ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
1845
240k
                    u4_tuSplitFlag_and_cbf_coding_bits,
1846
240k
                    ps_ctxt->i8_cl_ssd_lambda_qf,
1847
240k
                    (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1848
240k
            }
1849
1850
240k
            i8_parent_cost +=
1851
240k
                ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
1852
1853
240k
            ihevce_ecd_buffer_pointer_updater(
1854
240k
                ps_node,
1855
240k
                ppu1_ecd,
1856
240k
                pu1_ecd_bPtr_backup_t1,
1857
240k
                1,
1858
240k
                u1_chroma_processing_enabled,
1859
240k
                u1_is_422);
1860
240k
        }
1861
987
        else
1862
987
        {
1863
987
            ps_node->s_luma_data.i8_cost = i8_parent_cost = LLONG_MAX;
1864
987
            ps_node->s_luma_data.i4_num_bytes_used_for_ecd = 0;
1865
987
        }
1866
1867
241k
        u1_is_tu_coded |= ps_node->s_luma_data.u1_cbf;
1868
1869
241k
        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
241k
        if(!ps_node->u1_is_valid_node || u1_is_tu_coded)
1881
168k
        {
1882
168k
            pu1_ecd_bPtr_backup_t2 = ppu1_ecd[0];
1883
1884
168k
            if(i4_pred_mode != PRED_MODE_SKIP)
1885
168k
            {
1886
168k
                u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
1887
168k
                    ps_node,
1888
168k
                    ps_node->ps_child_node_tl,
1889
168k
                    pu1_cabac_ctxt,
1890
168k
                    MAX_TU_SIZE,
1891
168k
                    MIN_TU_SIZE,
1892
168k
                    0,
1893
168k
                    1,
1894
168k
                    i4_pred_mode == PRED_MODE_INTRA,
1895
168k
                    (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
1896
168k
                    u1_chroma_processing_enabled,
1897
168k
                    u1_is_422);
1898
1899
168k
                i8_child_cost += COMPUTE_RATE_COST_CLIP30(
1900
168k
                    u4_tuSplitFlag_and_cbf_coding_bits,
1901
168k
                    ps_ctxt->i8_cl_ssd_lambda_qf,
1902
168k
                    (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
1903
168k
            }
1904
1905
168k
            if(i8_child_cost < i8_parent_cost)
1906
168k
            {
1907
168k
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1908
168k
                    ps_ctxt,
1909
168k
                    ps_node->ps_child_node_tl,
1910
168k
                    ps_buffer_data,
1911
168k
                    pu1_cabac_ctxt,
1912
168k
                    i4_pred_mode,
1913
168k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1914
168k
                    i4_alpha_stim_multiplier,
1915
168k
                    u1_is_cu_noisy,
1916
168k
#endif
1917
168k
                    u1_cur_depth,
1918
168k
                    u1_max_depth,
1919
168k
                    u1_part_type,
1920
168k
                    u1_chroma_processing_enabled,
1921
168k
                    u1_compute_spatial_ssd);
1922
1923
168k
                ps_node->ps_child_node_tl->s_luma_data.i8_cost +=
1924
168k
                    i8_child_cost - ps_node->ps_child_node_tl->s_luma_data.i8_cost;
1925
168k
            }
1926
1927
168k
            if(i8_child_cost < i8_parent_cost)
1928
165k
            {
1929
165k
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1930
165k
                    ps_ctxt,
1931
165k
                    ps_node->ps_child_node_tr,
1932
165k
                    ps_buffer_data,
1933
165k
                    pu1_cabac_ctxt,
1934
165k
                    i4_pred_mode,
1935
165k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1936
165k
                    i4_alpha_stim_multiplier,
1937
165k
                    u1_is_cu_noisy,
1938
165k
#endif
1939
165k
                    u1_cur_depth,
1940
165k
                    u1_max_depth,
1941
165k
                    u1_part_type,
1942
165k
                    u1_chroma_processing_enabled,
1943
165k
                    u1_compute_spatial_ssd);
1944
165k
            }
1945
1946
168k
            if(i8_child_cost < i8_parent_cost)
1947
162k
            {
1948
162k
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1949
162k
                    ps_ctxt,
1950
162k
                    ps_node->ps_child_node_bl,
1951
162k
                    ps_buffer_data,
1952
162k
                    pu1_cabac_ctxt,
1953
162k
                    i4_pred_mode,
1954
162k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1955
162k
                    i4_alpha_stim_multiplier,
1956
162k
                    u1_is_cu_noisy,
1957
162k
#endif
1958
162k
                    u1_cur_depth,
1959
162k
                    u1_max_depth,
1960
162k
                    u1_part_type,
1961
162k
                    u1_chroma_processing_enabled,
1962
162k
                    u1_compute_spatial_ssd);
1963
162k
            }
1964
1965
168k
            if(i8_child_cost < i8_parent_cost)
1966
159k
            {
1967
159k
                i8_child_cost += ihevce_topDown_tu_tree_selector(
1968
159k
                    ps_ctxt,
1969
159k
                    ps_node->ps_child_node_br,
1970
159k
                    ps_buffer_data,
1971
159k
                    pu1_cabac_ctxt,
1972
159k
                    i4_pred_mode,
1973
159k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
1974
159k
                    i4_alpha_stim_multiplier,
1975
159k
                    u1_is_cu_noisy,
1976
159k
#endif
1977
159k
                    u1_cur_depth,
1978
159k
                    u1_max_depth,
1979
159k
                    u1_part_type,
1980
159k
                    u1_chroma_processing_enabled,
1981
159k
                    u1_compute_spatial_ssd);
1982
159k
            }
1983
1984
168k
            if(i8_parent_cost > i8_child_cost)
1985
111k
            {
1986
111k
                UWORD32 u4_num_bytes = ihevce_ecd_buffer_pointer_updater(
1987
111k
                    ps_node,
1988
111k
                    ppu1_ecd,
1989
111k
                    pu1_ecd_bPtr_backup_t1,
1990
111k
                    0,
1991
111k
                    u1_chroma_processing_enabled,
1992
111k
                    u1_is_422);
1993
1994
111k
                if(pu1_ecd_bPtr_backup_t2 != pu1_ecd_bPtr_backup_t1)
1995
110k
                {
1996
110k
                    memmove(pu1_ecd_bPtr_backup_t1, pu1_ecd_bPtr_backup_t2, u4_num_bytes);
1997
110k
                }
1998
1999
111k
                ps_node->s_luma_data.i4_num_bytes_used_for_ecd = u4_num_bytes;
2000
111k
                ps_node->as_cb_data[0].i4_num_bytes_used_for_ecd = 0;
2001
111k
                ps_node->as_cb_data[1].i4_num_bytes_used_for_ecd = 0;
2002
111k
                ps_node->as_cr_data[0].i4_num_bytes_used_for_ecd = 0;
2003
111k
                ps_node->as_cr_data[1].i4_num_bytes_used_for_ecd = 0;
2004
2005
111k
                ps_node->u1_is_valid_node = 0;
2006
2007
111k
                i8_winning_cost = i8_child_cost;
2008
111k
            }
2009
57.4k
            else
2010
57.4k
            {
2011
57.4k
                ihevce_debriefer_when_parent_wins(
2012
57.4k
                    ps_node,
2013
57.4k
                    ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2014
57.4k
                    ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2015
57.4k
                    ps_nbr_data_buf,
2016
57.4k
                    ai2_deq_data_backup,
2017
57.4k
                    pi2_deq_data,
2018
57.4k
                    ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2019
57.4k
                    pi2_deq_data_chroma,
2020
57.4k
                    au2_recon_backup,
2021
57.4k
                    pv_recon,
2022
57.4k
                    au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2023
57.4k
                    pv_recon_chroma,
2024
57.4k
                    au1_cabac_ctxt_backup,
2025
57.4k
                    pu1_cabac_ctxt,
2026
57.4k
                    NULL,
2027
57.4k
                    NULL,
2028
57.4k
                    i4_nbr_data_buf_stride,
2029
57.4k
                    MAX_CU_SIZE,
2030
57.4k
                    i4_deq_data_stride,
2031
57.4k
                    MAX_CU_SIZE,
2032
57.4k
                    i4_deq_data_stride_chroma,
2033
57.4k
                    MAX_CU_SIZE,
2034
57.4k
                    i4_recon_stride,
2035
57.4k
                    MAX_CU_SIZE,
2036
57.4k
                    i4_recon_stride_chroma,
2037
57.4k
                    sizeof(au1_cabac_ctxt_backup),
2038
57.4k
                    ps_ctxt->i4_cu_qp,
2039
57.4k
                    u1_chroma_processing_enabled,
2040
57.4k
                    u1_is_422,
2041
57.4k
                    ps_ctxt->u1_bit_depth > 8);
2042
2043
57.4k
                ihevce_ecd_buffer_pointer_updater(
2044
57.4k
                    ps_node,
2045
57.4k
                    ppu1_ecd,
2046
57.4k
                    pu1_ecd_bPtr_backup_t1,
2047
57.4k
                    1,
2048
57.4k
                    u1_chroma_processing_enabled,
2049
57.4k
                    u1_is_422);
2050
2051
57.4k
                i8_winning_cost = i8_parent_cost;
2052
57.4k
            }
2053
168k
        }
2054
73.0k
        else
2055
73.0k
        {
2056
73.0k
            ihevce_debriefer_when_parent_wins(
2057
73.0k
                ps_node,
2058
73.0k
                ps_ctxt->s_cmn_opt_func.pf_copy_2d,
2059
73.0k
                ps_ctxt->s_cmn_opt_func.pf_chroma_interleave_2d_copy,
2060
73.0k
                ps_nbr_data_buf,
2061
73.0k
                ai2_deq_data_backup,
2062
73.0k
                pi2_deq_data,
2063
73.0k
                ai2_deq_data_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2064
73.0k
                pi2_deq_data_chroma,
2065
73.0k
                au2_recon_backup,
2066
73.0k
                pv_recon,
2067
73.0k
                au2_recon_backup + MAX_CU_SIZE * MAX_CU_SIZE,
2068
73.0k
                pv_recon_chroma,
2069
73.0k
                au1_cabac_ctxt_backup,
2070
73.0k
                pu1_cabac_ctxt,
2071
73.0k
                NULL,
2072
73.0k
                NULL,
2073
73.0k
                i4_nbr_data_buf_stride,
2074
73.0k
                MAX_CU_SIZE,
2075
73.0k
                i4_deq_data_stride,
2076
73.0k
                MAX_CU_SIZE,
2077
73.0k
                i4_deq_data_stride_chroma,
2078
73.0k
                MAX_CU_SIZE,
2079
73.0k
                i4_recon_stride,
2080
73.0k
                MAX_CU_SIZE,
2081
73.0k
                i4_recon_stride_chroma,
2082
73.0k
                sizeof(au1_cabac_ctxt_backup),
2083
73.0k
                ps_ctxt->i4_cu_qp,
2084
73.0k
                u1_chroma_processing_enabled,
2085
73.0k
                u1_is_422,
2086
73.0k
                ps_ctxt->u1_bit_depth > 8);
2087
2088
73.0k
            ihevce_ecd_buffer_pointer_updater(
2089
73.0k
                ps_node,
2090
73.0k
                ppu1_ecd,
2091
73.0k
                pu1_ecd_bPtr_backup_t1,
2092
73.0k
                1,
2093
73.0k
                u1_chroma_processing_enabled,
2094
73.0k
                u1_is_422);
2095
2096
73.0k
            i8_winning_cost = i8_parent_cost;
2097
73.0k
        }
2098
241k
    }
2099
595k
    else
2100
595k
    {
2101
595k
        ASSERT(ps_node->u1_is_valid_node);
2102
2103
595k
        ihevce_tu_processor(
2104
595k
            ps_ctxt,
2105
595k
            ps_node,
2106
595k
            ps_buffer_data,
2107
595k
            pu1_cabac_ctxt,
2108
595k
            i4_pred_mode,
2109
595k
#if USE_NOISE_TERM_IN_ZERO_CODING_DECISION_ALGORITHMS
2110
595k
            i4_alpha_stim_multiplier,
2111
595k
            u1_is_cu_noisy,
2112
595k
#endif
2113
595k
            u1_chroma_processing_enabled,
2114
595k
            u1_compute_spatial_ssd);
2115
2116
595k
        if(i4_pred_mode != PRED_MODE_SKIP)
2117
540k
        {
2118
540k
            u4_tuSplitFlag_and_cbf_coding_bits = ihevce_compute_bits_for_TUSplit_and_cbf(
2119
540k
                ps_node,
2120
540k
                ps_node,
2121
540k
                pu1_cabac_ctxt,
2122
540k
                MAX_TU_SIZE,
2123
540k
                MIN_TU_SIZE,
2124
540k
                0,
2125
540k
                (u1_cur_depth == u1_max_depth) ? 0 : 1,
2126
540k
                i4_pred_mode == PRED_MODE_INTRA,
2127
540k
                (u1_part_type == PART_NxN) && (i4_pred_mode == PRED_MODE_INTRA),
2128
540k
                u1_chroma_processing_enabled,
2129
540k
                u1_is_422);
2130
2131
540k
            ps_node->s_luma_data.i8_cost += COMPUTE_RATE_COST_CLIP30(
2132
540k
                u4_tuSplitFlag_and_cbf_coding_bits,
2133
540k
                ps_ctxt->i8_cl_ssd_lambda_qf,
2134
540k
                (LAMBDA_Q_SHIFT + CABAC_FRAC_BITS_Q));
2135
540k
        }
2136
2137
595k
        i8_winning_cost +=
2138
595k
            ihevce_tu_node_cost_collator(ps_node, u1_chroma_processing_enabled, u1_is_422);
2139
2140
595k
        ihevce_ecd_buffer_pointer_updater(
2141
595k
            ps_node, ppu1_ecd, pu1_ecd_bPtr_backup_t1, 1, u1_chroma_processing_enabled, u1_is_422);
2142
2143
595k
        ihevce_nbr_data_copier(
2144
595k
            ps_nbr_data_buf,
2145
595k
            i4_nbr_data_buf_stride,
2146
595k
            ps_ctxt->i4_cu_qp,
2147
595k
            ps_node->s_luma_data.u1_cbf,
2148
595k
            ps_node->s_luma_data.u1_posx,
2149
595k
            ps_node->s_luma_data.u1_posy,
2150
595k
            ps_node->s_luma_data.u1_size);
2151
595k
    }
2152
2153
837k
    return i8_winning_cost;
2154
837k
}
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
588k
{
2192
588k
    UWORD8 u1_is_chroma_tu_valid = 1;
2193
588k
    WORD32 i4_log2_size;
2194
2195
588k
    ASSERT(ps_node != NULL);
2196
2197
588k
    if(ps_node->u1_is_valid_node)
2198
486k
    {
2199
486k
        ASSERT(
2200
486k
            (NULL == ps_node->ps_child_node_tl) && (NULL == ps_node->ps_child_node_tr) &&
2201
486k
            (NULL == ps_node->ps_child_node_bl) && (NULL == ps_node->ps_child_node_br));
2202
486k
    }
2203
101k
    else
2204
101k
    {
2205
101k
        ASSERT(
2206
101k
            !((NULL == ps_node->ps_child_node_tl) || (NULL == ps_node->ps_child_node_tr) ||
2207
101k
              (NULL == ps_node->ps_child_node_bl) || (NULL == ps_node->ps_child_node_br)));
2208
101k
    }
2209
2210
588k
    if(ps_node->u1_is_valid_node)
2211
486k
    {
2212
486k
        if((4 == ps_node->s_luma_data.u1_size) && (POS_TL != e_tu_pos))
2213
198k
        {
2214
198k
            u1_is_chroma_tu_valid = INTRA_PRED_CHROMA_IDX_NONE;
2215
198k
        }
2216
2217
486k
        GETRANGE(i4_log2_size, ps_node->s_luma_data.u1_size);
2218
2219
486k
        ps_final_prms->s_recon_datastore.au1_bufId_with_winning_LumaRecon[pu2_tu_ctr[0]] =
2220
486k
            ps_node->s_luma_data.u1_reconBufId;
2221
486k
        ps_final_prms->u4_cu_sad += ps_node->s_luma_data.u4_sad;
2222
486k
        ps_final_prms->u1_is_cu_coded |= ps_node->s_luma_data.u1_cbf;
2223
486k
        ps_final_prms->u4_cu_luma_res_bits += ps_node->s_luma_data.i4_bits;
2224
2225
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].i4_luma_coeff_offset =
2226
486k
            pi4_num_bytes_used_for_ecd[0];
2227
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_y_cbf = ps_node->s_luma_data.u1_cbf;
2228
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf = 0;
2229
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf = 0;
2230
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cb_cbf_subtu1 = 0;
2231
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_cr_cbf_subtu1 = 0;
2232
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_chroma_intra_mode_idx =
2233
486k
            u1_is_chroma_tu_valid;
2234
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b7_qp = i4_cu_qp;
2235
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_first_tu_in_cu =
2236
486k
            (!ps_node->s_luma_data.u1_posx && !ps_node->s_luma_data.u1_posx);
2237
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b1_transquant_bypass = 0;
2238
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b3_size = i4_log2_size - 3;
2239
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_x =
2240
486k
            (u1_cu_posx + ps_node->s_luma_data.u1_posx) / 4;
2241
486k
        ps_final_prms->as_tu_enc_loop[pu2_tu_ctr[0]].s_tu.b4_pos_y =
2242
486k
            (u1_cu_posy + ps_node->s_luma_data.u1_posy) / 4;
2243
2244
486k
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].i2_luma_bytes_consumed =
2245
486k
            ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2246
486k
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_col =
2247
486k
            ps_node->s_luma_data.i4_zero_col;
2248
486k
        ps_final_prms->as_tu_enc_loop_temp_prms[pu2_tu_ctr[0]].u4_luma_zero_row =
2249
486k
            ps_node->s_luma_data.i4_zero_row;
2250
2251
486k
        pi8_total_cost[0] += ps_node->s_luma_data.i8_cost;
2252
486k
        pi8_total_non_coded_cost[0] += ps_node->s_luma_data.i8_not_coded_cost;
2253
486k
        pi4_num_bytes_used_for_ecd[0] += ps_node->s_luma_data.i4_num_bytes_used_for_ecd;
2254
486k
        pi4_num_bits_used_for_encoding[0] += ps_node->s_luma_data.i4_bits;
2255
2256
486k
        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
486k
        pu2_tu_ctr[0]++;
2332
486k
    }
2333
101k
    else
2334
101k
    {
2335
101k
        ihevce_tu_selector_debriefer(
2336
101k
            ps_node->ps_child_node_tl,
2337
101k
            ps_final_prms,
2338
101k
            pi8_total_cost,
2339
101k
            pi8_total_non_coded_cost,
2340
101k
            pi4_num_bytes_used_for_ecd,
2341
101k
            pi4_num_bits_used_for_encoding,
2342
101k
            pu2_tu_ctr,
2343
101k
            i4_cu_qp,
2344
101k
            u1_cu_posx,
2345
101k
            u1_cu_posy,
2346
101k
            u1_chroma_processing_enabled,
2347
101k
            u1_is_422,
2348
101k
            POS_TL);
2349
2350
101k
        ihevce_tu_selector_debriefer(
2351
101k
            ps_node->ps_child_node_tr,
2352
101k
            ps_final_prms,
2353
101k
            pi8_total_cost,
2354
101k
            pi8_total_non_coded_cost,
2355
101k
            pi4_num_bytes_used_for_ecd,
2356
101k
            pi4_num_bits_used_for_encoding,
2357
101k
            pu2_tu_ctr,
2358
101k
            i4_cu_qp,
2359
101k
            u1_cu_posx,
2360
101k
            u1_cu_posy,
2361
101k
            u1_chroma_processing_enabled,
2362
101k
            u1_is_422,
2363
101k
            POS_TR);
2364
2365
101k
        ihevce_tu_selector_debriefer(
2366
101k
            ps_node->ps_child_node_bl,
2367
101k
            ps_final_prms,
2368
101k
            pi8_total_cost,
2369
101k
            pi8_total_non_coded_cost,
2370
101k
            pi4_num_bytes_used_for_ecd,
2371
101k
            pi4_num_bits_used_for_encoding,
2372
101k
            pu2_tu_ctr,
2373
101k
            i4_cu_qp,
2374
101k
            u1_cu_posx,
2375
101k
            u1_cu_posy,
2376
101k
            u1_chroma_processing_enabled,
2377
101k
            u1_is_422,
2378
101k
            POS_BL);
2379
2380
101k
        ihevce_tu_selector_debriefer(
2381
101k
            ps_node->ps_child_node_br,
2382
101k
            ps_final_prms,
2383
101k
            pi8_total_cost,
2384
101k
            pi8_total_non_coded_cost,
2385
101k
            pi4_num_bytes_used_for_ecd,
2386
101k
            pi4_num_bits_used_for_encoding,
2387
101k
            pu2_tu_ctr,
2388
101k
            i4_cu_qp,
2389
101k
            u1_cu_posx,
2390
101k
            u1_cu_posy,
2391
101k
            u1_chroma_processing_enabled,
2392
101k
            u1_is_422,
2393
101k
            POS_BR);
2394
101k
    }
2395
588k
}
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
        ps_root->ps_child_node_br = NULL;
2664
0
    }
2665
0
}