Coverage Report

Created: 2026-10-28 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_mv_merge.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at:
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
******************************************************************************/
18
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevcd_mv_merge.c
22
 *
23
 * @brief
24
 *  Contains functions for motion vector merge candidates derivation
25
 *
26
 * @author
27
 *  Ittiam
28
 *
29
 * @par List of Functions:
30
 * - ihevcd_compare_pu_mv_t()
31
 * - ihevcd_mv_pred_merge()
32
 *
33
 * @remarks
34
 *  None
35
 *
36
 *******************************************************************************
37
 */
38
/*****************************************************************************/
39
/* File Includes                                                             */
40
/*****************************************************************************/
41
#include <stdio.h>
42
#include <stddef.h>
43
#include <stdlib.h>
44
#include <string.h>
45
46
#include "ihevc_typedefs.h"
47
#include "iv.h"
48
#include "ivd.h"
49
#include "ihevcd_cxa.h"
50
#include "ithread.h"
51
52
#include "ihevc_defs.h"
53
#include "ihevc_debug.h"
54
#include "ihevc_structs.h"
55
#include "ihevc_macros.h"
56
#include "ihevc_platform_macros.h"
57
#include "ihevc_cabac_tables.h"
58
#include "ihevc_disp_mgr.h"
59
#include "ihevc_buf_mgr.h"
60
#include "ihevc_dpb_mgr.h"
61
62
#include "ihevcd_defs.h"
63
#include "ihevcd_function_selector.h"
64
#include "ihevcd_structs.h"
65
#include "ihevcd_error.h"
66
#include "ihevcd_nal.h"
67
#include "ihevcd_bitstream.h"
68
#include "ihevcd_fmt_conv.h"
69
#include "ihevcd_job_queue.h"
70
#include "ihevcd_debug.h"
71
#include "ihevcd_mv_merge.h"
72
/**
73
 *******************************************************************************
74
 *
75
 * @brief Compare Motion vectors function
76
 *
77
 *
78
 * @par Description:
79
 *   Checks if MVs and Reference idx are excatly matching.
80
 *
81
 * @param[inout] ps_1
82
 *   motion vector 1 to be compared
83
 *
84
 * @param[in] ps_2
85
 *   motion vector 2 to be compared
86
 *
87
 * @returns
88
 *  0 : if not matching 1 : if matching
89
 *
90
 * @remarks
91
 *
92
 *******************************************************************************
93
 */
94
WORD32 ihevcd_compare_pu_t(pu_t *ps_pu_1, pu_t *ps_pu_2)
95
936k
{
96
936k
    WORD32 l0_match = 0, l1_match = 0;
97
936k
    pu_mv_t *ps_mv_1, *ps_mv_2;
98
936k
    WORD32 pred_mode_1, pred_mode_2;
99
100
936k
    ps_mv_1 = &ps_pu_1->mv;
101
936k
    ps_mv_2 = &ps_pu_2->mv;
102
103
936k
    pred_mode_1 = ps_pu_1->b2_pred_mode;
104
936k
    pred_mode_2 = ps_pu_2->b2_pred_mode;
105
106
936k
    if(pred_mode_1 == pred_mode_2)
107
658k
    {
108
658k
        if(pred_mode_1 != PRED_L1)
109
611k
        {
110
611k
            if(ps_mv_1->i1_l0_ref_idx == ps_mv_2->i1_l0_ref_idx)
111
530k
            {
112
530k
                if(0 == memcmp(&ps_mv_1->s_l0_mv, &ps_mv_2->s_l0_mv, sizeof(mv_t)))
113
398k
                {
114
398k
                    l0_match = 1;
115
398k
                }
116
530k
            }
117
611k
        }
118
658k
        if(pred_mode_1 != PRED_L0)
119
399k
        {
120
399k
            if(ps_mv_1->i1_l1_ref_idx == ps_mv_2->i1_l1_ref_idx)
121
355k
            {
122
355k
                if(0 == memcmp(&ps_mv_1->s_l1_mv, &ps_mv_2->s_l1_mv, sizeof(mv_t)))
123
302k
                {
124
302k
                    l1_match = 1;
125
302k
                }
126
355k
            }
127
399k
        }
128
658k
        if(pred_mode_1 == PRED_BI)
129
351k
            return (l1_match && l0_match);
130
306k
        else if(pred_mode_1 == PRED_L0)
131
263k
            return l0_match;
132
43.1k
        else
133
43.1k
            return l1_match;
134
658k
    }
135
136
278k
    return 0;
137
936k
}
138
139
void ihevcd_collocated_mvp(mv_ctxt_t *ps_mv_ctxt,
140
                           pu_t *ps_pu,
141
                           mv_t *ps_mv_col,
142
                           WORD32 *pu4_avail_col_flag,
143
                           WORD32 use_pu_ref_idx,
144
                           WORD32 x_col,
145
                           WORD32 y_col)
146
5.35M
{
147
5.35M
    sps_t *ps_sps = ps_mv_ctxt->ps_sps;
148
5.35M
    slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
149
5.35M
    ref_list_t *ps_ref_list[2];
150
5.35M
    mv_buf_t *ps_mv_buf_col;
151
5.35M
    WORD32 xp_col, yp_col;
152
5.35M
    WORD32 col_ctb_x, col_ctb_y;
153
5.35M
    mv_t as_mv_col[2];
154
5.35M
    WORD32 log2_ctb_size;
155
5.35M
    WORD32 ctb_size;
156
5.35M
    WORD32 avail_col;
157
5.35M
    WORD32 col_ctb_idx, pu_cnt;
158
5.35M
    WORD32 au4_list_col[2];
159
5.35M
    WORD32 num_minpu_in_ctb;
160
5.35M
    UWORD8 *pu1_pic_pu_map_ctb;
161
5.35M
    pu_t *ps_col_pu;
162
5.35M
    WORD32 part_pos_y;
163
164
165
5.35M
    part_pos_y = ps_pu->b4_pos_y << 2;
166
167
5.35M
    log2_ctb_size = ps_sps->i1_log2_ctb_size;
168
5.35M
    ctb_size = (1 << log2_ctb_size);
169
170
5.35M
    avail_col = 1;
171
172
    /* Initializing reference list */
173
5.35M
    ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
174
5.35M
    ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
175
5.35M
    if(PSLICE == ps_slice_hdr->i1_slice_type)
176
115k
        ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
177
178
5.35M
    if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0))
179
881k
    {
180
        /* L1 */
181
881k
        ps_mv_buf_col = (mv_buf_t *)ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
182
183
881k
    }
184
4.47M
    else
185
4.47M
    {
186
        /* L0 */
187
4.47M
        ps_mv_buf_col = (mv_buf_t *)ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
188
189
4.47M
    }
190
5.35M
    num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE);
191
192
5.35M
    if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size))
193
4.20M
                    && ((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples)
194
4.16M
                    && (((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size))
195
4.16M
                                    < ps_sps->i2_pic_height_in_luma_samples)))
196
4.12M
    {
197
4.12M
        xp_col = ((x_col >> 4) << 4);
198
4.12M
        yp_col = ((y_col >> 4) << 4);
199
4.12M
        col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size);
200
4.12M
        col_ctb_y = ps_mv_ctxt->i4_ctb_y + (yp_col >> log2_ctb_size);
201
4.12M
        col_ctb_idx = col_ctb_x + (col_ctb_y)*(ps_sps->i2_pic_wd_in_ctb);
202
4.12M
        pu_cnt = ps_mv_buf_col->pu4_pic_pu_idx[col_ctb_idx];
203
4.12M
        pu1_pic_pu_map_ctb = ps_mv_buf_col->pu1_pic_pu_map
204
4.12M
                        + col_ctb_idx * num_minpu_in_ctb;
205
4.12M
        if(xp_col == ctb_size)
206
830k
            xp_col = 0;
207
4.12M
        pu_cnt += pu1_pic_pu_map_ctb[(yp_col >> 2)
208
4.12M
                        * (ctb_size / MIN_PU_SIZE) + (xp_col >> 2)];
209
4.12M
        ps_col_pu = &ps_mv_buf_col->ps_pic_pu[pu_cnt];
210
4.12M
    }
211
1.23M
    else
212
1.23M
        avail_col = 0;
213
214
5.35M
    if((avail_col == 0) || (ps_col_pu->b1_intra_flag == 1)
215
3.98M
                    || (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0))
216
4.08M
    {
217
4.08M
        pu4_avail_col_flag[0] = 0;
218
4.08M
        pu4_avail_col_flag[1] = 0;
219
4.08M
        ps_mv_col[0].i2_mvx = 0;
220
4.08M
        ps_mv_col[0].i2_mvy = 0;
221
4.08M
        ps_mv_col[1].i2_mvx = 0;
222
4.08M
        ps_mv_col[1].i2_mvy = 0;
223
4.08M
    }
224
1.27M
    else
225
1.27M
    {
226
1.27M
        WORD32 au4_ref_idx_col[2];
227
1.27M
        WORD32 pred_flag_l0, pred_flag_l1;
228
1.27M
        pred_flag_l0 = (ps_col_pu->b2_pred_mode != PRED_L1);
229
1.27M
        pred_flag_l1 = (ps_col_pu->b2_pred_mode != PRED_L0);
230
231
1.27M
        if(pred_flag_l0 == 0)
232
18.5k
        {
233
18.5k
            as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
234
18.5k
            au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
235
18.5k
            au4_list_col[0] = 1; /* L1 */
236
237
18.5k
            as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
238
18.5k
            au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
239
18.5k
            au4_list_col[1] = 1; /* L1 */
240
18.5k
        }
241
1.25M
        else
242
1.25M
        {
243
1.25M
            if(pred_flag_l1 == 0)
244
271k
            {
245
271k
                as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
246
271k
                au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
247
271k
                au4_list_col[0] = 0; /* L1 */
248
249
271k
                as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
250
271k
                au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
251
271k
                au4_list_col[1] = 0; /* L1 */
252
271k
            }
253
983k
            else
254
983k
            {
255
983k
                if(1 == ps_slice_hdr->i1_low_delay_flag)
256
582k
                {
257
582k
                    as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
258
582k
                    au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
259
582k
                    au4_list_col[0] = 0; /* L0 */
260
261
582k
                    as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
262
582k
                    au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
263
582k
                    au4_list_col[1] = 1; /* L1 */
264
582k
                }
265
401k
                else
266
401k
                {
267
401k
                    if(0 == ps_slice_hdr->i1_collocated_from_l0_flag)
268
49.2k
                    {
269
49.2k
                        as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
270
49.2k
                        au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
271
272
49.2k
                        as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
273
49.2k
                        au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
274
49.2k
                    }
275
352k
                    else
276
352k
                    {
277
352k
                        as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
278
352k
                        au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
279
280
352k
                        as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
281
352k
                        au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
282
352k
                    }
283
284
401k
                    au4_list_col[0] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
285
401k
                    au4_list_col[1] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
286
401k
                }
287
983k
            }
288
1.25M
        }
289
1.27M
        avail_col = 1;
290
1.27M
        {
291
1.27M
            WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc;
292
1.27M
            WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt;
293
1.27M
            WORD32 ref_idx_l0, ref_idx_l1;
294
1.27M
            WORD32 slice_idx;
295
1.27M
            pic_buf_t *ps_pic_buf;
296
297
1.27M
            if(use_pu_ref_idx)
298
149k
            {
299
149k
                ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
300
149k
                ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
301
149k
            }
302
1.12M
            else
303
1.12M
            {
304
1.12M
                ref_idx_l0 = 0;
305
1.12M
                ref_idx_l1 = 0;
306
1.12M
            }
307
308
1.27M
            col_poc = ps_mv_buf_col->i4_abs_poc;
309
1.27M
            cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
310
311
1.27M
            slice_idx = *(ps_mv_buf_col->pu1_pic_slice_map + col_ctb_x + col_ctb_y * ps_sps->i2_pic_wd_in_ctb);
312
1.27M
            slice_idx &= (MAX_SLICE_HDR_CNT - 1);
313
1.27M
            if(au4_list_col[0] == 0)
314
899k
            {
315
899k
                col_ref_poc_l0 =
316
899k
                                ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[0]];
317
899k
                col_ref_poc_l0_lt =
318
899k
                                (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
319
899k
            }
320
374k
            else
321
374k
            {
322
374k
                col_ref_poc_l0 =
323
374k
                                ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[0]];
324
374k
                col_ref_poc_l0_lt =
325
374k
                                (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
326
374k
            }
327
            /* L0 collocated mv */
328
1.27M
            ps_pic_buf = (pic_buf_t *)((ps_ref_list[0][ref_idx_l0].pv_pic_buf));
329
1.27M
            cur_ref_poc = ps_pic_buf->i4_abs_poc;
330
1.27M
            cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
331
332
1.27M
            if(cur_ref_poc_lt == col_ref_poc_l0_lt)
333
1.24M
            {
334
1.24M
                pu4_avail_col_flag[0] = 1;
335
336
1.24M
                if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)))
337
317k
                {
338
317k
                    ps_mv_col[0] = as_mv_col[0];
339
317k
                }
340
929k
                else
341
929k
                {
342
929k
                    ps_mv_col[0] = as_mv_col[0];
343
929k
                    if(col_ref_poc_l0 != col_poc)
344
492k
                        ihevcd_scale_collocated_mv((mv_t *)(&ps_mv_col[0]), cur_ref_poc,
345
492k
                                                   col_ref_poc_l0, col_poc, cur_poc);
346
929k
                }
347
1.24M
            }
348
27.0k
            else
349
27.0k
            {
350
27.0k
                pu4_avail_col_flag[0] = 0;
351
27.0k
                ps_mv_col[0].i2_mvx = 0;
352
27.0k
                ps_mv_col[0].i2_mvy = 0;
353
27.0k
            }
354
1.27M
            if((BSLICE == ps_slice_hdr->i1_slice_type))
355
1.26M
            {
356
1.26M
                WORD32 col_ref_poc_l1_lt, col_ref_poc_l1;
357
358
1.26M
                if(au4_list_col[1] == 0)
359
302k
                {
360
302k
                    col_ref_poc_l1 =
361
302k
                                    ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[1]];
362
302k
                    col_ref_poc_l1_lt =
363
302k
                                    (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
364
302k
                }
365
958k
                else
366
958k
                {
367
958k
                    col_ref_poc_l1 =
368
958k
                                    ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[1]];
369
958k
                    col_ref_poc_l1_lt =
370
958k
                                    (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
371
958k
                }
372
373
                /* L1 collocated mv */
374
1.26M
                ps_pic_buf = (pic_buf_t *)((ps_ref_list[1][ref_idx_l1].pv_pic_buf));
375
1.26M
                cur_ref_poc = ps_pic_buf->i4_abs_poc;
376
1.26M
                cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
377
378
1.26M
                if(cur_ref_poc_lt == col_ref_poc_l1_lt)
379
1.24M
                {
380
1.24M
                    pu4_avail_col_flag[1] = 1;
381
382
1.24M
                    if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)))
383
368k
                    {
384
368k
                        ps_mv_col[1] = as_mv_col[1];
385
368k
                    }
386
872k
                    else
387
872k
                    {
388
872k
                        ps_mv_col[1] = as_mv_col[1];
389
872k
                        if(col_ref_poc_l1 != col_poc)
390
494k
                            ihevcd_scale_collocated_mv((mv_t *)&ps_mv_col[1], cur_ref_poc,
391
494k
                                                       col_ref_poc_l1, col_poc, cur_poc);
392
872k
                    }
393
1.24M
                }
394
19.2k
                else
395
19.2k
                {
396
19.2k
                    pu4_avail_col_flag[1] = 0;
397
19.2k
                    ps_mv_col[1].i2_mvx = 0;
398
19.2k
                    ps_mv_col[1].i2_mvy = 0;
399
19.2k
                }
400
1.26M
            }
401
13.2k
            else
402
13.2k
            {
403
13.2k
                pu4_avail_col_flag[1] = 0;
404
13.2k
            }
405
1.27M
        }
406
1.27M
    }
407
5.35M
}
408
409
410
/**
411
 *******************************************************************************
412
 *
413
 * @brief
414
 * This function performs Motion Vector Merge candidates derivation
415
 *
416
 * @par Description:
417
 *  MV merge list is computed using neighbor mvs and colocated mv
418
 *
419
 * @param[in] ps_ctxt
420
 * pointer to mv predictor context
421
 *
422
 * @param[in] ps_top_nbr_4x4
423
 * pointer to top 4x4 nbr structure
424
 *
425
 * @param[in] ps_left_nbr_4x4
426
 * pointer to left 4x4 nbr structure
427
 *
428
 * @param[in] ps_top_left_nbr_4x4
429
 * pointer to top left 4x4 nbr structure
430
 *
431
 * @param[in] left_nbr_4x4_strd
432
 * left nbr buffer stride in terms of 4x4 units
433
 *
434
 * @param[in] ps_avail_flags
435
 * Neighbor availability flags container
436
 *
437
 * @param[in] ps_col_mv
438
 * Colocated MV pointer
439
 *
440
 * @param[in] ps_pu
441
 * Current Partition PU strucrture pointer
442
 *
443
 * @param[in] part_mode
444
 * Partition mode @sa PART_SIZE_E
445
 *
446
 * @param[in] part_idx
447
 * Partition idx of current partition inside CU
448
 *
449
 * @param[in] single_mcl_flag
450
 * Single MCL flag based on 8x8 CU and Parallel merge value
451
 *
452
 * @param[out] ps_merge_cand_list
453
 * pointer to store MV merge candidates list
454
 *
455
 * @returns
456
 * None
457
 * @remarks
458
 *
459
 *
460
 *******************************************************************************
461
 */
462
void ihevcd_mv_merge(mv_ctxt_t *ps_mv_ctxt,
463
                     UWORD32 *pu4_top_pu_idx,
464
                     UWORD32 *pu4_left_pu_idx,
465
                     WORD32 left_nbr_4x4_strd,
466
                     pu_t *ps_pu,
467
                     WORD32 part_mode,
468
                     WORD32 part_idx,
469
                     WORD32 part_wd,
470
                     WORD32 part_ht,
471
                     WORD32 part_pos_x,
472
                     WORD32 part_pos_y,
473
                     WORD32 single_mcl_flag,
474
                     WORD32 lb_avail,
475
                     WORD32 l_avail,
476
                     WORD32 tr_avail,
477
                     WORD32 t_avail,
478
                     WORD32 tl_avail)
479
71.4M
{
480
    /******************************************************/
481
    /*      Spatial Merge Candidates                      */
482
    /******************************************************/
483
71.4M
    slice_header_t *ps_slice_hdr;
484
71.4M
    pu_t as_pu_merge_list[MAX_NUM_MERGE_CAND];
485
71.4M
    pps_t *ps_pps;
486
71.4M
    ref_list_t *ps_ref_list[2];
487
71.4M
    WORD32 sum_avail_a0_a1_b0_b1 = 0; /*Sum of availability of A0, A1, B0, B1*/
488
71.4M
    WORD32 nbr_x, nbr_y;
489
71.4M
    WORD32 nbr_avail[MAX_NUM_MV_NBR];
490
71.4M
    WORD32 merge_shift;
491
71.4M
    WORD32 nbr_pu_idx;
492
71.4M
    pu_t *ps_nbr_pu[MAX_NUM_MV_NBR];
493
71.4M
    WORD32 max_num_merge_cand;
494
71.4M
    WORD32 candidate_cnt;
495
71.4M
    WORD32 pos_x_merge_shift, pos_y_merge_shift;
496
497
71.4M
    ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
498
71.4M
    ps_pps = ps_mv_ctxt->ps_pps;
499
    /* Initializing reference list */
500
71.4M
    ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
501
71.4M
    ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
502
71.4M
    if(PSLICE == ps_slice_hdr->i1_slice_type)
503
441k
        ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
504
505
71.4M
    candidate_cnt = 0;
506
    /*******************************************/
507
    /* Neighbor location: Graphical indication */
508
    /*                                         */
509
    /*          B2 _____________B1 B0          */
510
    /*            |               |            */
511
    /*            |               |            */
512
    /*            |               |            */
513
    /*            |      PU     ht|            */
514
    /*            |               |            */
515
    /*            |               |            */
516
    /*          A1|______wd_______|            */
517
    /*          A0                             */
518
    /*                                         */
519
    /*******************************************/
520
521
71.4M
    merge_shift = ps_pps->i1_log2_parallel_merge_level;
522
523
    /* Availability check */
524
    /* A1 */
525
71.4M
    nbr_x = part_pos_x - 1;
526
71.4M
    nbr_y = part_pos_y + part_ht - 1; /* A1 */
527
528
71.4M
    nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
529
71.4M
    ps_nbr_pu[NBR_A1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
530
531
71.4M
    nbr_avail[NBR_A1] = l_avail
532
70.2M
                    && (!ps_nbr_pu[NBR_A1]->b1_intra_flag); /* A1 */
533
534
71.4M
    pos_x_merge_shift = (part_pos_x >> merge_shift);
535
71.4M
    pos_y_merge_shift = (part_pos_y >> merge_shift);
536
71.4M
    max_num_merge_cand = ps_pu->b3_merge_idx + 1;
537
538
71.4M
    {
539
71.4M
        if(nbr_avail[NBR_A1])
540
70.3M
        {
541
            /* if at same merge level */
542
70.3M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
543
6.54M
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
544
6.56M
            {
545
6.56M
                nbr_avail[NBR_A1] = 0;
546
6.56M
            }
547
548
            /* SPEC JCTVC-K1003_v9 version has a different way using not available       */
549
            /* candidates compared to software. for non square part and seconf part case */
550
            /* ideally nothing from the 1st partition should be used as per spec but     */
551
            /* HM 8.2 dev verison does not adhere to this. currenlty code fllows HM      */
552
553
            /* if single MCL is 0 , second part of 2 part in CU */
554
64.3M
            else if((single_mcl_flag == 0) && (part_idx == 1) &&
555
181k
                            ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) ||
556
83.4k
                                            (part_mode == PART_nRx2N)))
557
104k
            {
558
104k
                nbr_avail[NBR_A1] = 0;
559
104k
            }
560
70.3M
            sum_avail_a0_a1_b0_b1 += nbr_avail[NBR_A1];
561
70.3M
            if(nbr_avail[NBR_A1])
562
64.2M
            {
563
64.2M
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A1];
564
64.2M
                candidate_cnt++;
565
64.2M
                if(candidate_cnt == max_num_merge_cand)
566
63.9M
                {
567
63.9M
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
568
63.9M
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
569
63.9M
                    return;
570
63.9M
                }
571
64.2M
            }
572
70.3M
        }
573
71.4M
    }
574
575
    /* B1 */
576
7.51M
    nbr_x = part_pos_x + part_wd - 1;
577
7.51M
    nbr_y = part_pos_y - 1;
578
579
7.51M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
580
7.51M
    ps_nbr_pu[NBR_B1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
581
582
7.51M
    nbr_avail[NBR_B1] = t_avail
583
8.51M
                    && (!ps_nbr_pu[NBR_B1]->b1_intra_flag); /* B1 */
584
585
7.51M
    {
586
7.51M
        WORD32 avail_flag;
587
7.51M
        avail_flag = nbr_avail[NBR_B1];
588
589
7.51M
        if(nbr_avail[NBR_B1])
590
8.52M
        {
591
            /* if at same merge level */
592
8.52M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
593
7.03M
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
594
3.88M
            {
595
3.88M
                nbr_avail[NBR_B1] = 0;
596
3.88M
                avail_flag = 0;
597
3.88M
            }
598
599
            /* if single MCL is 0 , second part of 2 part in CU */
600
4.73M
            else if((single_mcl_flag == 0) && (part_idx == 1) &&
601
128k
                            ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) ||
602
94.1k
                                            (part_mode == PART_2NxnD)))
603
37.0k
            {
604
37.0k
                nbr_avail[NBR_B1] = 0;
605
37.0k
                avail_flag = 0;
606
37.0k
            }
607
608
4.60M
            else if(nbr_avail[NBR_A1])
609
359k
            {
610
359k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B1]);
611
359k
            }
612
613
8.52M
            sum_avail_a0_a1_b0_b1 += avail_flag;
614
8.52M
            if(avail_flag)
615
4.59M
            {
616
4.59M
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B1];
617
4.59M
                candidate_cnt++;
618
4.59M
                if(candidate_cnt == max_num_merge_cand)
619
4.43M
                {
620
4.43M
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
621
4.43M
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
622
4.43M
                    return;
623
4.43M
                }
624
4.59M
            }
625
8.52M
        }
626
7.51M
    }
627
    /* B0 */
628
3.08M
    nbr_x = part_pos_x + part_wd;
629
3.08M
    nbr_y = part_pos_y - 1;
630
631
3.08M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
632
3.08M
    ps_nbr_pu[NBR_B0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
633
634
3.08M
    nbr_avail[NBR_B0] = tr_avail
635
2.58M
                    && (!ps_nbr_pu[NBR_B0]->b1_intra_flag); /* B0 */
636
637
3.08M
    {
638
3.08M
        WORD32 avail_flag;
639
3.08M
        avail_flag = nbr_avail[NBR_B0];
640
641
        /* if at same merge level */
642
3.08M
        if(nbr_avail[NBR_B0])
643
2.57M
        {
644
2.57M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
645
914k
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
646
910k
            {
647
910k
                nbr_avail[NBR_B0] = 0;
648
910k
                avail_flag = 0;
649
910k
            }
650
1.66M
            else if(nbr_avail[NBR_B1])
651
189k
            {
652
189k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B0]);
653
189k
            }
654
655
2.57M
            sum_avail_a0_a1_b0_b1 += avail_flag;
656
2.57M
            if(avail_flag)
657
1.58M
            {
658
1.58M
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B0];
659
1.58M
                candidate_cnt++;
660
1.58M
                if(candidate_cnt == max_num_merge_cand)
661
1.53M
                {
662
1.53M
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
663
1.53M
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
664
1.53M
                    return;
665
1.53M
                }
666
1.58M
            }
667
2.57M
        }
668
3.08M
    }
669
    /* A0 */
670
1.54M
    nbr_x = part_pos_x - 1;
671
1.54M
    nbr_y = part_pos_y + part_ht; /* A0 */
672
673
1.54M
    nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
674
1.54M
    ps_nbr_pu[NBR_A0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
675
676
1.54M
    nbr_avail[NBR_A0] = lb_avail
677
89.5k
                    && (!ps_nbr_pu[NBR_A0]->b1_intra_flag); /* A0 */
678
1.54M
    {
679
1.54M
        WORD32 avail_flag;
680
1.54M
        avail_flag = nbr_avail[NBR_A0];
681
682
1.54M
        if(nbr_avail[NBR_A0])
683
85.6k
        {
684
            /* if at same merge level */
685
85.6k
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
686
517
                            (pos_y_merge_shift == (nbr_y >> merge_shift)))
687
517
            {
688
517
                nbr_avail[NBR_A0] = 0;
689
517
                avail_flag = 0;
690
517
            }
691
85.1k
            else if(nbr_avail[NBR_A1])
692
83.4k
            {
693
83.4k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_A0]);
694
83.4k
            }
695
696
85.6k
            sum_avail_a0_a1_b0_b1 += avail_flag;
697
85.6k
            if(avail_flag)
698
34.1k
            {
699
34.1k
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A0];
700
34.1k
                candidate_cnt++;
701
34.1k
                if(candidate_cnt == max_num_merge_cand)
702
19.2k
                {
703
19.2k
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
704
19.2k
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
705
19.2k
                    return;
706
19.2k
                }
707
34.1k
            }
708
85.6k
        }
709
1.54M
    }
710
    /* B2 */
711
712
1.52M
    nbr_x = part_pos_x - 1;
713
1.52M
    nbr_y = part_pos_y - 1; /* B2 */
714
715
1.52M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
716
1.52M
    ps_nbr_pu[NBR_B2] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
717
718
1.52M
    nbr_avail[NBR_B2] = tl_avail
719
2.41M
                    && (!ps_nbr_pu[NBR_B2]->b1_intra_flag); /* B2 */
720
721
1.52M
    {
722
1.52M
        WORD32 avail_flag;
723
1.52M
        avail_flag = nbr_avail[NBR_B2];
724
725
1.52M
        if(nbr_avail[NBR_B2])
726
2.40M
        {
727
            /* if at same merge level */
728
2.40M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
729
2.17M
                            (pos_y_merge_shift == (nbr_y >> merge_shift)))
730
2.17M
            {
731
2.17M
                nbr_avail[NBR_B2] = 0;
732
2.17M
                avail_flag = 0;
733
2.17M
            }
734
238k
            else if(4 == sum_avail_a0_a1_b0_b1)
735
2.13k
            {
736
2.13k
                avail_flag = 0;
737
2.13k
            }
738
739
236k
            else
740
236k
            {
741
236k
                if(nbr_avail[NBR_A1])
742
203k
                {
743
203k
                    avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B2]);
744
203k
                }
745
746
236k
                if(avail_flag && nbr_avail[NBR_B1])
747
113k
                {
748
113k
                    avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B2]);
749
113k
                }
750
236k
            }
751
752
2.40M
            if(avail_flag)
753
81.1k
            {
754
81.1k
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B2];
755
81.1k
                candidate_cnt++;
756
81.1k
                if(candidate_cnt == max_num_merge_cand)
757
46.8k
                {
758
46.8k
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
759
46.8k
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
760
46.8k
                    return;
761
46.8k
                }
762
81.1k
            }
763
2.40M
        }
764
1.52M
    }
765
766
    /***********************************************************/
767
    /*          Collocated MV prediction                       */
768
    /***********************************************************/
769
1.48M
    {
770
1.48M
        mv_t as_mv_col[2];
771
1.48M
        WORD32 avail_col_flag[2] = { 0 }, x_col, y_col;
772
1.48M
        WORD32 avail_col_l0, avail_col_l1;
773
//        ihevcd_collocated_mvp(ps_mv_ctxt,ps_pu,part_pos_x,part_pos_y,part_wd,part_ht,as_mv_col,avail_col_flag,0);
774
775
        /* Checking Collocated MV availability at Bottom right of PU*/
776
1.48M
        x_col = part_pos_x + part_wd;
777
1.48M
        y_col = part_pos_y + part_ht;
778
1.48M
        ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
779
780
1.48M
        avail_col_l0 = avail_col_flag[0];
781
1.48M
        avail_col_l1 = avail_col_flag[1];
782
783
2.24M
        if(avail_col_l0 || avail_col_l1)
784
595k
        {
785
595k
            as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
786
595k
            as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
787
595k
        }
788
789
1.48M
        if(avail_col_l0 == 0 || avail_col_l1 == 0)
790
2.24M
        {
791
            /* Checking Collocated MV availability at Center of PU */
792
2.24M
            x_col = part_pos_x + (part_wd >> 1);
793
2.24M
            y_col = part_pos_y + (part_ht >> 1);
794
2.24M
            ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
795
796
2.24M
            if(avail_col_l0 == 0)
797
2.23M
            {
798
2.23M
                as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
799
2.23M
            }
800
2.24M
            if(avail_col_l1 == 0)
801
2.24M
            {
802
2.24M
                as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
803
2.24M
            }
804
805
2.24M
            avail_col_l0 |= avail_col_flag[0];
806
2.24M
            avail_col_l1 |= avail_col_flag[1];
807
2.24M
        }
808
809
1.48M
        as_pu_merge_list[candidate_cnt].mv.i1_l0_ref_idx = 0;
810
1.48M
        as_pu_merge_list[candidate_cnt].mv.i1_l1_ref_idx = 0;
811
1.48M
        as_pu_merge_list[candidate_cnt].b2_pred_mode = avail_col_l0 ? (avail_col_l1 ? PRED_BI : PRED_L0) : PRED_L1;
812
813
1.73M
        candidate_cnt += (avail_col_l0 || avail_col_l1);
814
815
1.48M
        if(candidate_cnt == max_num_merge_cand)
816
1.04M
        {
817
1.04M
            ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
818
1.04M
            ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
819
1.04M
            return;
820
1.04M
        }
821
822
1.48M
    }
823
434k
    {
824
434k
        WORD32 slice_type;
825
826
434k
        slice_type = ps_slice_hdr->i1_slice_type;
827
        /* Colocated mv has to be added to list, if available */
828
829
        /******************************************************/
830
        /*      Bi pred merge candidates                      */
831
        /******************************************************/
832
434k
        if(slice_type == BSLICE)
833
1.74M
        {
834
1.74M
            if((candidate_cnt > 1) && (candidate_cnt < MAX_NUM_MERGE_CAND))
835
94.8k
            {
836
94.8k
                WORD32 priority_list0[12] =
837
94.8k
                    { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
838
94.8k
                WORD32 priority_list1[12] =
839
94.8k
                    { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
840
94.8k
                WORD32 l0_cand, l1_cand;
841
94.8k
                WORD32 bi_pred_idx = 0;
842
94.8k
                WORD32 total_bi_pred_cand =
843
94.8k
                                candidate_cnt * (candidate_cnt - 1);
844
845
228k
                while(bi_pred_idx < total_bi_pred_cand)
846
228k
                {
847
228k
                    l0_cand = priority_list0[bi_pred_idx];
848
228k
                    l1_cand = priority_list1[bi_pred_idx];
849
850
228k
                    if((as_pu_merge_list[l0_cand].b2_pred_mode != PRED_L1)
851
214k
                                    && (as_pu_merge_list[l1_cand].b2_pred_mode
852
214k
                                                    != PRED_L0))
853
136k
                    {
854
136k
                        WORD8 i1_l0_ref_idx, i1_l1_ref_idx;
855
136k
                        mv_t s_l0_mv, s_l1_mv;
856
136k
                        pic_buf_t *ps_pic_buf_l0, *ps_pic_buf_l1;
857
858
136k
                        i1_l0_ref_idx = as_pu_merge_list[l0_cand].mv.i1_l0_ref_idx;
859
136k
                        i1_l1_ref_idx = as_pu_merge_list[l1_cand].mv.i1_l1_ref_idx;
860
136k
                        ps_pic_buf_l0 = (pic_buf_t *)((ps_ref_list[0][i1_l0_ref_idx].pv_pic_buf));
861
136k
                        ps_pic_buf_l1 = (pic_buf_t *)((ps_ref_list[1][i1_l1_ref_idx].pv_pic_buf));
862
136k
                        s_l0_mv = as_pu_merge_list[l0_cand].mv.s_l0_mv;
863
136k
                        s_l1_mv = as_pu_merge_list[l1_cand].mv.s_l1_mv;
864
865
136k
                        if((ps_pic_buf_l0->i4_abs_poc != ps_pic_buf_l1->i4_abs_poc)
866
102k
                                        || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx)
867
61.7k
                                        || (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy))
868
85.7k
                        {
869
85.7k
                            candidate_cnt++;
870
85.7k
                            if(candidate_cnt == max_num_merge_cand)
871
54.5k
                            {
872
54.5k
                                ps_pu[0].mv.s_l0_mv = s_l0_mv;
873
54.5k
                                ps_pu[0].mv.s_l1_mv = s_l1_mv;
874
54.5k
                                ps_pu[0].mv.i1_l0_ref_idx = i1_l0_ref_idx;
875
54.5k
                                ps_pu[0].mv.i1_l1_ref_idx = i1_l1_ref_idx;
876
54.5k
                                ps_pu[0].b2_pred_mode = PRED_BI;
877
54.5k
                                return;
878
54.5k
                            }
879
85.7k
                        }
880
136k
                    }
881
882
174k
                    bi_pred_idx++;
883
884
174k
                    if((bi_pred_idx == total_bi_pred_cand)
885
134k
                                    || (candidate_cnt == MAX_NUM_MERGE_CAND))
886
40.6k
                    {
887
40.6k
                        break;
888
40.6k
                    }
889
174k
                }
890
94.8k
            }
891
1.74M
        }
892
893
        /******************************************************/
894
        /*      Zero merge candidates                         */
895
        /******************************************************/
896
//        if(candidate_cnt < max_num_merge_cand)
897
380k
        {
898
380k
            WORD32 num_ref_idx;
899
380k
            WORD32 zero_idx;
900
901
380k
            zero_idx = max_num_merge_cand - candidate_cnt - 1;
902
903
380k
            if(slice_type == PSLICE)
904
52.0k
                num_ref_idx = ps_slice_hdr->i1_num_ref_idx_l0_active;
905
328k
            else
906
                /* Slice type B */
907
328k
                num_ref_idx = MIN(ps_slice_hdr->i1_num_ref_idx_l0_active, ps_slice_hdr->i1_num_ref_idx_l1_active);
908
909
380k
            if(zero_idx >= num_ref_idx)
910
25.3k
                zero_idx = 0;
911
912
380k
            ps_pu[0].mv.i1_l0_ref_idx = zero_idx;
913
380k
            if(slice_type == PSLICE)
914
52.0k
            {
915
52.0k
                ps_pu[0].mv.i1_l1_ref_idx = 0;
916
52.0k
                ps_pu[0].b2_pred_mode = PRED_L0;
917
52.0k
            }
918
328k
            else /* Slice type B */
919
328k
            {
920
328k
                ps_pu[0].mv.i1_l1_ref_idx = zero_idx;
921
328k
                ps_pu[0].b2_pred_mode = PRED_BI;
922
328k
            }
923
924
380k
            ps_pu[0].mv.s_l0_mv.i2_mvx = 0;
925
380k
            ps_pu[0].mv.s_l0_mv.i2_mvy = 0;
926
380k
            ps_pu[0].mv.s_l1_mv.i2_mvx = 0;
927
380k
            ps_pu[0].mv.s_l1_mv.i2_mvy = 0;
928
929
380k
            candidate_cnt++;
930
380k
        }
931
380k
    }
932
933
0
    return;
934
434k
}
935
936