Coverage Report

Created: 2026-04-01 06:18

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
2.18M
{
96
2.18M
    WORD32 l0_match = 0, l1_match = 0;
97
2.18M
    pu_mv_t *ps_mv_1, *ps_mv_2;
98
2.18M
    WORD32 pred_mode_1, pred_mode_2;
99
100
2.18M
    ps_mv_1 = &ps_pu_1->mv;
101
2.18M
    ps_mv_2 = &ps_pu_2->mv;
102
103
2.18M
    pred_mode_1 = ps_pu_1->b2_pred_mode;
104
2.18M
    pred_mode_2 = ps_pu_2->b2_pred_mode;
105
106
2.18M
    if(pred_mode_1 == pred_mode_2)
107
1.51M
    {
108
1.51M
        if(pred_mode_1 != PRED_L1)
109
1.36M
        {
110
1.36M
            if(ps_mv_1->i1_l0_ref_idx == ps_mv_2->i1_l0_ref_idx)
111
1.23M
            {
112
1.23M
                if(0 == memcmp(&ps_mv_1->s_l0_mv, &ps_mv_2->s_l0_mv, sizeof(mv_t)))
113
855k
                {
114
855k
                    l0_match = 1;
115
855k
                }
116
1.23M
            }
117
1.36M
        }
118
1.51M
        if(pred_mode_1 != PRED_L0)
119
904k
        {
120
904k
            if(ps_mv_1->i1_l1_ref_idx == ps_mv_2->i1_l1_ref_idx)
121
836k
            {
122
836k
                if(0 == memcmp(&ps_mv_1->s_l1_mv, &ps_mv_2->s_l1_mv, sizeof(mv_t)))
123
665k
                {
124
665k
                    l1_match = 1;
125
665k
                }
126
836k
            }
127
904k
        }
128
1.51M
        if(pred_mode_1 == PRED_BI)
129
753k
            return (l1_match && l0_match);
130
762k
        else if(pred_mode_1 == PRED_L0)
131
616k
            return l0_match;
132
145k
        else
133
145k
            return l1_match;
134
1.51M
    }
135
136
664k
    return 0;
137
2.18M
}
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
3.43M
{
147
3.43M
    sps_t *ps_sps = ps_mv_ctxt->ps_sps;
148
3.43M
    slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
149
3.43M
    ref_list_t *ps_ref_list[2];
150
3.43M
    mv_buf_t *ps_mv_buf_col;
151
3.43M
    WORD32 xp_col, yp_col;
152
3.43M
    WORD32 col_ctb_x, col_ctb_y;
153
3.43M
    mv_t as_mv_col[2];
154
3.43M
    WORD32 log2_ctb_size;
155
3.43M
    WORD32 ctb_size;
156
3.43M
    WORD32 avail_col;
157
3.43M
    WORD32 col_ctb_idx, pu_cnt;
158
3.43M
    WORD32 au4_list_col[2];
159
3.43M
    WORD32 num_minpu_in_ctb;
160
3.43M
    UWORD8 *pu1_pic_pu_map_ctb;
161
3.43M
    pu_t *ps_col_pu;
162
3.43M
    WORD32 part_pos_y;
163
164
165
3.43M
    part_pos_y = ps_pu->b4_pos_y << 2;
166
167
3.43M
    log2_ctb_size = ps_sps->i1_log2_ctb_size;
168
3.43M
    ctb_size = (1 << log2_ctb_size);
169
170
3.43M
    avail_col = 1;
171
172
    /* Initializing reference list */
173
3.43M
    ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
174
3.43M
    ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
175
3.43M
    if(PSLICE == ps_slice_hdr->i1_slice_type)
176
48.5k
        ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
177
178
3.43M
    if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0))
179
971k
    {
180
        /* L1 */
181
971k
        ps_mv_buf_col = (mv_buf_t *)ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
182
183
971k
    }
184
2.46M
    else
185
2.46M
    {
186
        /* L0 */
187
2.46M
        ps_mv_buf_col = (mv_buf_t *)ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
188
189
2.46M
    }
190
3.43M
    num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE);
191
192
3.43M
    if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size))
193
2.88M
                    && ((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples)
194
2.83M
                    && (((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size))
195
2.83M
                                    < ps_sps->i2_pic_height_in_luma_samples)))
196
2.78M
    {
197
2.78M
        xp_col = ((x_col >> 4) << 4);
198
2.78M
        yp_col = ((y_col >> 4) << 4);
199
2.78M
        col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size);
200
2.78M
        col_ctb_y = ps_mv_ctxt->i4_ctb_y + (yp_col >> log2_ctb_size);
201
2.78M
        col_ctb_idx = col_ctb_x + (col_ctb_y)*(ps_sps->i2_pic_wd_in_ctb);
202
2.78M
        pu_cnt = ps_mv_buf_col->pu4_pic_pu_idx[col_ctb_idx];
203
2.78M
        pu1_pic_pu_map_ctb = ps_mv_buf_col->pu1_pic_pu_map
204
2.78M
                        + col_ctb_idx * num_minpu_in_ctb;
205
2.78M
        if(xp_col == ctb_size)
206
410k
            xp_col = 0;
207
2.78M
        pu_cnt += pu1_pic_pu_map_ctb[(yp_col >> 2)
208
2.78M
                        * (ctb_size / MIN_PU_SIZE) + (xp_col >> 2)];
209
2.78M
        ps_col_pu = &ps_mv_buf_col->ps_pic_pu[pu_cnt];
210
2.78M
    }
211
652k
    else
212
652k
        avail_col = 0;
213
214
3.43M
    if((avail_col == 0) || (ps_col_pu->b1_intra_flag == 1)
215
2.52M
                    || (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0))
216
2.40M
    {
217
2.40M
        pu4_avail_col_flag[0] = 0;
218
2.40M
        pu4_avail_col_flag[1] = 0;
219
2.40M
        ps_mv_col[0].i2_mvx = 0;
220
2.40M
        ps_mv_col[0].i2_mvy = 0;
221
2.40M
        ps_mv_col[1].i2_mvx = 0;
222
2.40M
        ps_mv_col[1].i2_mvy = 0;
223
2.40M
    }
224
1.02M
    else
225
1.02M
    {
226
1.02M
        WORD32 au4_ref_idx_col[2];
227
1.02M
        WORD32 pred_flag_l0, pred_flag_l1;
228
1.02M
        pred_flag_l0 = (ps_col_pu->b2_pred_mode != PRED_L1);
229
1.02M
        pred_flag_l1 = (ps_col_pu->b2_pred_mode != PRED_L0);
230
231
1.02M
        if(pred_flag_l0 == 0)
232
69.4k
        {
233
69.4k
            as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
234
69.4k
            au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
235
69.4k
            au4_list_col[0] = 1; /* L1 */
236
237
69.4k
            as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
238
69.4k
            au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
239
69.4k
            au4_list_col[1] = 1; /* L1 */
240
69.4k
        }
241
955k
        else
242
955k
        {
243
955k
            if(pred_flag_l1 == 0)
244
383k
            {
245
383k
                as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
246
383k
                au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
247
383k
                au4_list_col[0] = 0; /* L1 */
248
249
383k
                as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
250
383k
                au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
251
383k
                au4_list_col[1] = 0; /* L1 */
252
383k
            }
253
571k
            else
254
571k
            {
255
571k
                if(1 == ps_slice_hdr->i1_low_delay_flag)
256
239k
                {
257
239k
                    as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
258
239k
                    au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
259
239k
                    au4_list_col[0] = 0; /* L0 */
260
261
239k
                    as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
262
239k
                    au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
263
239k
                    au4_list_col[1] = 1; /* L1 */
264
239k
                }
265
331k
                else
266
331k
                {
267
331k
                    if(0 == ps_slice_hdr->i1_collocated_from_l0_flag)
268
138k
                    {
269
138k
                        as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
270
138k
                        au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
271
272
138k
                        as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
273
138k
                        au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
274
138k
                    }
275
193k
                    else
276
193k
                    {
277
193k
                        as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
278
193k
                        au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
279
280
193k
                        as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
281
193k
                        au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
282
193k
                    }
283
284
331k
                    au4_list_col[0] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
285
331k
                    au4_list_col[1] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
286
331k
                }
287
571k
            }
288
955k
        }
289
1.02M
        avail_col = 1;
290
1.02M
        {
291
1.02M
            WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc;
292
1.02M
            WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt;
293
1.02M
            WORD32 ref_idx_l0, ref_idx_l1;
294
1.02M
            WORD32 slice_idx;
295
1.02M
            pic_buf_t *ps_pic_buf;
296
297
1.02M
            if(use_pu_ref_idx)
298
231k
            {
299
231k
                ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
300
231k
                ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
301
231k
            }
302
793k
            else
303
793k
            {
304
793k
                ref_idx_l0 = 0;
305
793k
                ref_idx_l1 = 0;
306
793k
            }
307
308
1.02M
            col_poc = ps_mv_buf_col->i4_abs_poc;
309
1.02M
            cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
310
311
1.02M
            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.02M
            slice_idx &= (MAX_SLICE_HDR_CNT - 1);
313
1.02M
            if(au4_list_col[0] == 0)
314
760k
            {
315
760k
                col_ref_poc_l0 =
316
760k
                                ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[0]];
317
760k
                col_ref_poc_l0_lt =
318
760k
                                (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
319
760k
            }
320
264k
            else
321
264k
            {
322
264k
                col_ref_poc_l0 =
323
264k
                                ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[0]];
324
264k
                col_ref_poc_l0_lt =
325
264k
                                (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
326
264k
            }
327
            /* L0 collocated mv */
328
1.02M
            ps_pic_buf = (pic_buf_t *)((ps_ref_list[0][ref_idx_l0].pv_pic_buf));
329
1.02M
            cur_ref_poc = ps_pic_buf->i4_abs_poc;
330
1.02M
            cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
331
332
1.02M
            if(cur_ref_poc_lt == col_ref_poc_l0_lt)
333
1.02M
            {
334
1.02M
                pu4_avail_col_flag[0] = 1;
335
336
1.02M
                if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)))
337
107k
                {
338
107k
                    ps_mv_col[0] = as_mv_col[0];
339
107k
                }
340
915k
                else
341
915k
                {
342
915k
                    ps_mv_col[0] = as_mv_col[0];
343
915k
                    if(col_ref_poc_l0 != col_poc)
344
684k
                        ihevcd_scale_collocated_mv((mv_t *)(&ps_mv_col[0]), cur_ref_poc,
345
684k
                                                   col_ref_poc_l0, col_poc, cur_poc);
346
915k
                }
347
1.02M
            }
348
1.68k
            else
349
1.68k
            {
350
1.68k
                pu4_avail_col_flag[0] = 0;
351
1.68k
                ps_mv_col[0].i2_mvx = 0;
352
1.68k
                ps_mv_col[0].i2_mvy = 0;
353
1.68k
            }
354
1.02M
            if((BSLICE == ps_slice_hdr->i1_slice_type))
355
1.01M
            {
356
1.01M
                WORD32 col_ref_poc_l1_lt, col_ref_poc_l1;
357
358
1.01M
                if(au4_list_col[1] == 0)
359
506k
                {
360
506k
                    col_ref_poc_l1 =
361
506k
                                    ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[1]];
362
506k
                    col_ref_poc_l1_lt =
363
506k
                                    (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
364
506k
                }
365
504k
                else
366
504k
                {
367
504k
                    col_ref_poc_l1 =
368
504k
                                    ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[1]];
369
504k
                    col_ref_poc_l1_lt =
370
504k
                                    (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
371
504k
                }
372
373
                /* L1 collocated mv */
374
1.01M
                ps_pic_buf = (pic_buf_t *)((ps_ref_list[1][ref_idx_l1].pv_pic_buf));
375
1.01M
                cur_ref_poc = ps_pic_buf->i4_abs_poc;
376
1.01M
                cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
377
378
1.01M
                if(cur_ref_poc_lt == col_ref_poc_l1_lt)
379
1.00M
                {
380
1.00M
                    pu4_avail_col_flag[1] = 1;
381
382
1.00M
                    if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)))
383
106k
                    {
384
106k
                        ps_mv_col[1] = as_mv_col[1];
385
106k
                    }
386
902k
                    else
387
902k
                    {
388
902k
                        ps_mv_col[1] = as_mv_col[1];
389
902k
                        if(col_ref_poc_l1 != col_poc)
390
680k
                            ihevcd_scale_collocated_mv((mv_t *)&ps_mv_col[1], cur_ref_poc,
391
680k
                                                       col_ref_poc_l1, col_poc, cur_poc);
392
902k
                    }
393
1.00M
                }
394
2.40k
                else
395
2.40k
                {
396
2.40k
                    pu4_avail_col_flag[1] = 0;
397
2.40k
                    ps_mv_col[1].i2_mvx = 0;
398
2.40k
                    ps_mv_col[1].i2_mvy = 0;
399
2.40k
                }
400
1.01M
            }
401
13.8k
            else
402
13.8k
            {
403
13.8k
                pu4_avail_col_flag[1] = 0;
404
13.8k
            }
405
1.02M
        }
406
1.02M
    }
407
3.43M
}
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
38.9M
{
480
    /******************************************************/
481
    /*      Spatial Merge Candidates                      */
482
    /******************************************************/
483
38.9M
    slice_header_t *ps_slice_hdr;
484
38.9M
    pu_t as_pu_merge_list[MAX_NUM_MERGE_CAND];
485
38.9M
    pps_t *ps_pps;
486
38.9M
    ref_list_t *ps_ref_list[2];
487
38.9M
    WORD32 sum_avail_a0_a1_b0_b1 = 0; /*Sum of availability of A0, A1, B0, B1*/
488
38.9M
    WORD32 nbr_x, nbr_y;
489
38.9M
    WORD32 nbr_avail[MAX_NUM_MV_NBR];
490
38.9M
    WORD32 merge_shift;
491
38.9M
    WORD32 nbr_pu_idx;
492
38.9M
    pu_t *ps_nbr_pu[MAX_NUM_MV_NBR];
493
38.9M
    WORD32 max_num_merge_cand;
494
38.9M
    WORD32 candidate_cnt;
495
38.9M
    WORD32 pos_x_merge_shift, pos_y_merge_shift;
496
497
38.9M
    ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
498
38.9M
    ps_pps = ps_mv_ctxt->ps_pps;
499
    /* Initializing reference list */
500
38.9M
    ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
501
38.9M
    ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
502
38.9M
    if(PSLICE == ps_slice_hdr->i1_slice_type)
503
225k
        ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
504
505
38.9M
    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
38.9M
    merge_shift = ps_pps->i1_log2_parallel_merge_level;
522
523
    /* Availability check */
524
    /* A1 */
525
38.9M
    nbr_x = part_pos_x - 1;
526
38.9M
    nbr_y = part_pos_y + part_ht - 1; /* A1 */
527
528
38.9M
    nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
529
38.9M
    ps_nbr_pu[NBR_A1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
530
531
38.9M
    nbr_avail[NBR_A1] = l_avail
532
38.1M
                    && (!ps_nbr_pu[NBR_A1]->b1_intra_flag); /* A1 */
533
534
38.9M
    pos_x_merge_shift = (part_pos_x >> merge_shift);
535
38.9M
    pos_y_merge_shift = (part_pos_y >> merge_shift);
536
38.9M
    max_num_merge_cand = ps_pu->b3_merge_idx + 1;
537
538
38.9M
    {
539
38.9M
        if(nbr_avail[NBR_A1])
540
38.1M
        {
541
            /* if at same merge level */
542
38.1M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
543
2.51M
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
544
2.51M
            {
545
2.51M
                nbr_avail[NBR_A1] = 0;
546
2.51M
            }
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
35.6M
            else if((single_mcl_flag == 0) && (part_idx == 1) &&
555
427k
                            ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) ||
556
200k
                                            (part_mode == PART_nRx2N)))
557
244k
            {
558
244k
                nbr_avail[NBR_A1] = 0;
559
244k
            }
560
38.1M
            sum_avail_a0_a1_b0_b1 += nbr_avail[NBR_A1];
561
38.1M
            if(nbr_avail[NBR_A1])
562
35.4M
            {
563
35.4M
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A1];
564
35.4M
                candidate_cnt++;
565
35.4M
                if(candidate_cnt == max_num_merge_cand)
566
34.4M
                {
567
34.4M
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
568
34.4M
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
569
34.4M
                    return;
570
34.4M
                }
571
35.4M
            }
572
38.1M
        }
573
38.9M
    }
574
575
    /* B1 */
576
4.50M
    nbr_x = part_pos_x + part_wd - 1;
577
4.50M
    nbr_y = part_pos_y - 1;
578
579
4.50M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
580
4.50M
    ps_nbr_pu[NBR_B1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
581
582
4.50M
    nbr_avail[NBR_B1] = t_avail
583
4.65M
                    && (!ps_nbr_pu[NBR_B1]->b1_intra_flag); /* B1 */
584
585
4.50M
    {
586
4.50M
        WORD32 avail_flag;
587
4.50M
        avail_flag = nbr_avail[NBR_B1];
588
589
4.50M
        if(nbr_avail[NBR_B1])
590
4.62M
        {
591
            /* if at same merge level */
592
4.62M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
593
2.90M
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
594
1.60M
            {
595
1.60M
                nbr_avail[NBR_B1] = 0;
596
1.60M
                avail_flag = 0;
597
1.60M
            }
598
599
            /* if single MCL is 0 , second part of 2 part in CU */
600
3.04M
            else if((single_mcl_flag == 0) && (part_idx == 1) &&
601
300k
                            ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) ||
602
225k
                                            (part_mode == PART_2NxnD)))
603
80.6k
            {
604
80.6k
                nbr_avail[NBR_B1] = 0;
605
80.6k
                avail_flag = 0;
606
80.6k
            }
607
608
2.94M
            else if(nbr_avail[NBR_A1])
609
854k
            {
610
854k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B1]);
611
854k
            }
612
613
4.62M
            sum_avail_a0_a1_b0_b1 += avail_flag;
614
4.62M
            if(avail_flag)
615
2.73M
            {
616
2.73M
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B1];
617
2.73M
                candidate_cnt++;
618
2.73M
                if(candidate_cnt == max_num_merge_cand)
619
2.35M
                {
620
2.35M
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
621
2.35M
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
622
2.35M
                    return;
623
2.35M
                }
624
2.73M
            }
625
4.62M
        }
626
4.50M
    }
627
    /* B0 */
628
2.15M
    nbr_x = part_pos_x + part_wd;
629
2.15M
    nbr_y = part_pos_y - 1;
630
631
2.15M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
632
2.15M
    ps_nbr_pu[NBR_B0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
633
634
2.15M
    nbr_avail[NBR_B0] = tr_avail
635
1.52M
                    && (!ps_nbr_pu[NBR_B0]->b1_intra_flag); /* B0 */
636
637
2.15M
    {
638
2.15M
        WORD32 avail_flag;
639
2.15M
        avail_flag = nbr_avail[NBR_B0];
640
641
        /* if at same merge level */
642
2.15M
        if(nbr_avail[NBR_B0])
643
1.50M
        {
644
1.50M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
645
579k
               (pos_y_merge_shift == (nbr_y >> merge_shift)))
646
577k
            {
647
577k
                nbr_avail[NBR_B0] = 0;
648
577k
                avail_flag = 0;
649
577k
            }
650
931k
            else if(nbr_avail[NBR_B1])
651
435k
            {
652
435k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B0]);
653
435k
            }
654
655
1.50M
            sum_avail_a0_a1_b0_b1 += avail_flag;
656
1.50M
            if(avail_flag)
657
701k
            {
658
701k
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B0];
659
701k
                candidate_cnt++;
660
701k
                if(candidate_cnt == max_num_merge_cand)
661
611k
                {
662
611k
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
663
611k
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
664
611k
                    return;
665
611k
                }
666
701k
            }
667
1.50M
        }
668
2.15M
    }
669
    /* A0 */
670
1.53M
    nbr_x = part_pos_x - 1;
671
1.53M
    nbr_y = part_pos_y + part_ht; /* A0 */
672
673
1.53M
    nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
674
1.53M
    ps_nbr_pu[NBR_A0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
675
676
1.53M
    nbr_avail[NBR_A0] = lb_avail
677
195k
                    && (!ps_nbr_pu[NBR_A0]->b1_intra_flag); /* A0 */
678
1.53M
    {
679
1.53M
        WORD32 avail_flag;
680
1.53M
        avail_flag = nbr_avail[NBR_A0];
681
682
1.53M
        if(nbr_avail[NBR_A0])
683
188k
        {
684
            /* if at same merge level */
685
188k
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
686
4.49k
                            (pos_y_merge_shift == (nbr_y >> merge_shift)))
687
4.49k
            {
688
4.49k
                nbr_avail[NBR_A0] = 0;
689
4.49k
                avail_flag = 0;
690
4.49k
            }
691
183k
            else if(nbr_avail[NBR_A1])
692
180k
            {
693
180k
                avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_A0]);
694
180k
            }
695
696
188k
            sum_avail_a0_a1_b0_b1 += avail_flag;
697
188k
            if(avail_flag)
698
75.2k
            {
699
75.2k
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A0];
700
75.2k
                candidate_cnt++;
701
75.2k
                if(candidate_cnt == max_num_merge_cand)
702
39.7k
                {
703
39.7k
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
704
39.7k
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
705
39.7k
                    return;
706
39.7k
                }
707
75.2k
            }
708
188k
        }
709
1.53M
    }
710
    /* B2 */
711
712
1.50M
    nbr_x = part_pos_x - 1;
713
1.50M
    nbr_y = part_pos_y - 1; /* B2 */
714
715
1.50M
    nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
716
1.50M
    ps_nbr_pu[NBR_B2] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
717
718
1.50M
    nbr_avail[NBR_B2] = tl_avail
719
1.57M
                    && (!ps_nbr_pu[NBR_B2]->b1_intra_flag); /* B2 */
720
721
1.50M
    {
722
1.50M
        WORD32 avail_flag;
723
1.50M
        avail_flag = nbr_avail[NBR_B2];
724
725
1.50M
        if(nbr_avail[NBR_B2])
726
1.55M
        {
727
            /* if at same merge level */
728
1.55M
            if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
729
1.02M
                            (pos_y_merge_shift == (nbr_y >> merge_shift)))
730
1.02M
            {
731
1.02M
                nbr_avail[NBR_B2] = 0;
732
1.02M
                avail_flag = 0;
733
1.02M
            }
734
533k
            else if(4 == sum_avail_a0_a1_b0_b1)
735
4.18k
            {
736
4.18k
                avail_flag = 0;
737
4.18k
            }
738
739
529k
            else
740
529k
            {
741
529k
                if(nbr_avail[NBR_A1])
742
455k
                {
743
455k
                    avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B2]);
744
455k
                }
745
746
529k
                if(avail_flag && nbr_avail[NBR_B1])
747
269k
                {
748
269k
                    avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B2]);
749
269k
                }
750
529k
            }
751
752
1.55M
            if(avail_flag)
753
183k
            {
754
183k
                as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B2];
755
183k
                candidate_cnt++;
756
183k
                if(candidate_cnt == max_num_merge_cand)
757
106k
                {
758
106k
                    ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
759
106k
                    ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
760
106k
                    return;
761
106k
                }
762
183k
            }
763
1.55M
        }
764
1.50M
    }
765
766
    /***********************************************************/
767
    /*          Collocated MV prediction                       */
768
    /***********************************************************/
769
1.39M
    {
770
1.39M
        mv_t as_mv_col[2];
771
1.39M
        WORD32 avail_col_flag[2] = { 0 }, x_col, y_col;
772
1.39M
        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.39M
        x_col = part_pos_x + part_wd;
777
1.39M
        y_col = part_pos_y + part_ht;
778
1.39M
        ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
779
780
1.39M
        avail_col_l0 = avail_col_flag[0];
781
1.39M
        avail_col_l1 = avail_col_flag[1];
782
783
1.39M
        if(avail_col_l0 || avail_col_l1)
784
476k
        {
785
476k
            as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
786
476k
            as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
787
476k
        }
788
789
1.39M
        if(avail_col_l0 == 0 || avail_col_l1 == 0)
790
1.27M
        {
791
            /* Checking Collocated MV availability at Center of PU */
792
1.27M
            x_col = part_pos_x + (part_wd >> 1);
793
1.27M
            y_col = part_pos_y + (part_ht >> 1);
794
1.27M
            ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
795
796
1.27M
            if(avail_col_l0 == 0)
797
1.26M
            {
798
1.26M
                as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
799
1.26M
            }
800
1.27M
            if(avail_col_l1 == 0)
801
1.26M
            {
802
1.26M
                as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
803
1.26M
            }
804
805
1.27M
            avail_col_l0 |= avail_col_flag[0];
806
1.27M
            avail_col_l1 |= avail_col_flag[1];
807
1.27M
        }
808
809
1.39M
        as_pu_merge_list[candidate_cnt].mv.i1_l0_ref_idx = 0;
810
1.39M
        as_pu_merge_list[candidate_cnt].mv.i1_l1_ref_idx = 0;
811
1.39M
        as_pu_merge_list[candidate_cnt].b2_pred_mode = avail_col_l0 ? (avail_col_l1 ? PRED_BI : PRED_L0) : PRED_L1;
812
813
1.39M
        candidate_cnt += (avail_col_l0 || avail_col_l1);
814
815
1.39M
        if(candidate_cnt == max_num_merge_cand)
816
629k
        {
817
629k
            ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
818
629k
            ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
819
629k
            return;
820
629k
        }
821
822
1.39M
    }
823
764k
    {
824
764k
        WORD32 slice_type;
825
826
764k
        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
764k
        if(slice_type == BSLICE)
833
1.10M
        {
834
1.10M
            if((candidate_cnt > 1) && (candidate_cnt < MAX_NUM_MERGE_CAND))
835
206k
            {
836
206k
                WORD32 priority_list0[12] =
837
206k
                    { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
838
206k
                WORD32 priority_list1[12] =
839
206k
                    { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
840
206k
                WORD32 l0_cand, l1_cand;
841
206k
                WORD32 bi_pred_idx = 0;
842
206k
                WORD32 total_bi_pred_cand =
843
206k
                                candidate_cnt * (candidate_cnt - 1);
844
845
472k
                while(bi_pred_idx < total_bi_pred_cand)
846
472k
                {
847
472k
                    l0_cand = priority_list0[bi_pred_idx];
848
472k
                    l1_cand = priority_list1[bi_pred_idx];
849
850
472k
                    if((as_pu_merge_list[l0_cand].b2_pred_mode != PRED_L1)
851
437k
                                    && (as_pu_merge_list[l1_cand].b2_pred_mode
852
437k
                                                    != PRED_L0))
853
283k
                    {
854
283k
                        WORD8 i1_l0_ref_idx, i1_l1_ref_idx;
855
283k
                        mv_t s_l0_mv, s_l1_mv;
856
283k
                        pic_buf_t *ps_pic_buf_l0, *ps_pic_buf_l1;
857
858
283k
                        i1_l0_ref_idx = as_pu_merge_list[l0_cand].mv.i1_l0_ref_idx;
859
283k
                        i1_l1_ref_idx = as_pu_merge_list[l1_cand].mv.i1_l1_ref_idx;
860
283k
                        ps_pic_buf_l0 = (pic_buf_t *)((ps_ref_list[0][i1_l0_ref_idx].pv_pic_buf));
861
283k
                        ps_pic_buf_l1 = (pic_buf_t *)((ps_ref_list[1][i1_l1_ref_idx].pv_pic_buf));
862
283k
                        s_l0_mv = as_pu_merge_list[l0_cand].mv.s_l0_mv;
863
283k
                        s_l1_mv = as_pu_merge_list[l1_cand].mv.s_l1_mv;
864
865
283k
                        if((ps_pic_buf_l0->i4_abs_poc != ps_pic_buf_l1->i4_abs_poc)
866
164k
                                        || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx)
867
90.7k
                                        || (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy))
868
210k
                        {
869
210k
                            candidate_cnt++;
870
210k
                            if(candidate_cnt == max_num_merge_cand)
871
130k
                            {
872
130k
                                ps_pu[0].mv.s_l0_mv = s_l0_mv;
873
130k
                                ps_pu[0].mv.s_l1_mv = s_l1_mv;
874
130k
                                ps_pu[0].mv.i1_l0_ref_idx = i1_l0_ref_idx;
875
130k
                                ps_pu[0].mv.i1_l1_ref_idx = i1_l1_ref_idx;
876
130k
                                ps_pu[0].b2_pred_mode = PRED_BI;
877
130k
                                return;
878
130k
                            }
879
210k
                        }
880
283k
                    }
881
882
341k
                    bi_pred_idx++;
883
884
341k
                    if((bi_pred_idx == total_bi_pred_cand)
885
266k
                                    || (candidate_cnt == MAX_NUM_MERGE_CAND))
886
75.9k
                    {
887
75.9k
                        break;
888
75.9k
                    }
889
341k
                }
890
206k
            }
891
1.10M
        }
892
893
        /******************************************************/
894
        /*      Zero merge candidates                         */
895
        /******************************************************/
896
//        if(candidate_cnt < max_num_merge_cand)
897
634k
        {
898
634k
            WORD32 num_ref_idx;
899
634k
            WORD32 zero_idx;
900
901
634k
            zero_idx = max_num_merge_cand - candidate_cnt - 1;
902
903
634k
            if(slice_type == PSLICE)
904
13.7k
                num_ref_idx = ps_slice_hdr->i1_num_ref_idx_l0_active;
905
620k
            else
906
                /* Slice type B */
907
620k
                num_ref_idx = MIN(ps_slice_hdr->i1_num_ref_idx_l0_active, ps_slice_hdr->i1_num_ref_idx_l1_active);
908
909
634k
            if(zero_idx >= num_ref_idx)
910
32.6k
                zero_idx = 0;
911
912
634k
            ps_pu[0].mv.i1_l0_ref_idx = zero_idx;
913
634k
            if(slice_type == PSLICE)
914
13.7k
            {
915
13.7k
                ps_pu[0].mv.i1_l1_ref_idx = 0;
916
13.7k
                ps_pu[0].b2_pred_mode = PRED_L0;
917
13.7k
            }
918
620k
            else /* Slice type B */
919
620k
            {
920
620k
                ps_pu[0].mv.i1_l1_ref_idx = zero_idx;
921
620k
                ps_pu[0].b2_pred_mode = PRED_BI;
922
620k
            }
923
924
634k
            ps_pu[0].mv.s_l0_mv.i2_mvx = 0;
925
634k
            ps_pu[0].mv.s_l0_mv.i2_mvy = 0;
926
634k
            ps_pu[0].mv.s_l1_mv.i2_mvx = 0;
927
634k
            ps_pu[0].mv.s_l1_mv.i2_mvy = 0;
928
929
634k
            candidate_cnt++;
930
634k
        }
931
634k
    }
932
933
0
    return;
934
764k
}
935
936