Coverage Report

Created: 2025-12-08 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_mv_pred.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_pred.c
22
 *
23
 * @brief
24
 *  Contains functions for motion vector prediction
25
 *
26
 * @author
27
 *  Ittiam
28
 *
29
 * @par List of Functions:
30
 * - ihevcd_scale_mv()
31
 * - ihevcd_mv_pred()
32
 *
33
 * @remarks
34
 *  None
35
 *
36
 *******************************************************************************
37
 */
38
/*****************************************************************************/
39
/* File Includes                                                             */
40
/*****************************************************************************/
41
42
#include <stdio.h>
43
#include <stddef.h>
44
#include <stdlib.h>
45
#include <string.h>
46
47
#include "ihevc_typedefs.h"
48
#include "iv.h"
49
#include "ivd.h"
50
#include "ihevcd_cxa.h"
51
#include "ithread.h"
52
53
#include "ihevc_defs.h"
54
#include "ihevc_debug.h"
55
#include "ihevc_structs.h"
56
#include "ihevc_macros.h"
57
#include "ihevc_platform_macros.h"
58
#include "ihevc_cabac_tables.h"
59
#include "ihevc_disp_mgr.h"
60
#include "ihevc_buf_mgr.h"
61
#include "ihevc_dpb_mgr.h"
62
63
#include "ihevcd_defs.h"
64
#include "ihevcd_function_selector.h"
65
#include "ihevcd_structs.h"
66
#include "ihevcd_error.h"
67
#include "ihevcd_nal.h"
68
#include "ihevcd_bitstream.h"
69
#include "ihevcd_fmt_conv.h"
70
#include "ihevcd_job_queue.h"
71
#include "ihevcd_debug.h"
72
#include "ihevcd_mv_merge.h"
73
74
/**
75
 *******************************************************************************
76
 *
77
 * @brief Function scaling motion vector
78
 *
79
 *
80
 * @par Description:
81
 *   Scales mv based on difference between current POC and current
82
 *   reference POC and neighbour reference poc
83
 *
84
 * @param[inout] mv
85
 *   motion vector to be scaled
86
 *
87
 * @param[in] cur_ref_poc
88
 *   Current PU refernce pic poc
89
 *
90
 * @param[in] nbr_ref_poc
91
 *   Neighbor PU reference pic poc
92
 *
93
 * @param[in] cur_poc
94
 *   Picture order count of current pic
95
 *
96
 * @returns
97
 *  None
98
 *
99
 * @remarks
100
 *
101
 *******************************************************************************
102
 */
103
void ihevcd_scale_mv(mv_t *ps_mv,
104
                     WORD32 cur_ref_poc,
105
                     WORD32 nbr_ref_poc,
106
                     WORD32 cur_poc)
107
302k
{
108
302k
    WORD32 td, tb, tx;
109
302k
    WORD32 dist_scale_factor;
110
302k
    WORD32 mvx, mvy;
111
112
302k
    td = CLIP_S8(cur_poc - nbr_ref_poc);
113
302k
    tb = CLIP_S8(cur_poc - cur_ref_poc);
114
115
302k
    if(0 != td)
116
299k
    {
117
299k
        tx = (16384 + (abs(td) >> 1)) / td;
118
119
299k
        dist_scale_factor = (tb * tx + 32) >> 6;
120
299k
        dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095);
121
122
299k
        mvx = ps_mv->i2_mvx;
123
299k
        mvy = ps_mv->i2_mvy;
124
125
299k
        mvx = SIGN(dist_scale_factor * mvx)
126
299k
                        * ((abs(dist_scale_factor * mvx) + 127) >> 8);
127
299k
        mvy = SIGN(dist_scale_factor * mvy)
128
299k
                        * ((abs(dist_scale_factor * mvy) + 127) >> 8);
129
130
299k
        ps_mv->i2_mvx = CLIP_S16(mvx);
131
299k
        ps_mv->i2_mvy = CLIP_S16(mvy);
132
299k
    }
133
302k
}
134
135
/**
136
 *******************************************************************************
137
 *
138
 * @brief Function scaling temporal motion vector
139
 *
140
 *
141
 * @par Description:
142
 *   Scales mv based on difference between current POC and current
143
 *   reference POC and neighbour reference poc
144
 *
145
 * @param[inout] mv
146
 *   motion vector to be scaled
147
 *
148
 * @param[in] cur_ref_poc
149
 *   Current PU refernce pic poc
150
 *
151
 * @param[in] nbr_ref_poc
152
 *   Neighbor PU reference pic poc
153
 *
154
 * @param[in] cur_poc
155
 *   Picture order count of current pic
156
 *
157
 * @returns
158
 *  None
159
 *
160
 * @remarks
161
 *
162
 *******************************************************************************
163
 */
164
void ihevcd_scale_collocated_mv(mv_t *ps_mv,
165
                                WORD32 cur_ref_poc,
166
                                WORD32 col_ref_poc,
167
                                WORD32 col_poc,
168
                                WORD32 cur_poc)
169
775k
{
170
775k
    WORD32 td, tb, tx;
171
775k
    WORD32 dist_scale_factor;
172
775k
    WORD32 mvx, mvy;
173
174
775k
    td = CLIP_S8(col_poc - col_ref_poc);
175
775k
    tb = CLIP_S8(cur_poc - cur_ref_poc);
176
177
775k
    tx = (16384 + (abs(td) >> 1)) / td;
178
179
775k
    dist_scale_factor = (tb * tx + 32) >> 6;
180
775k
    dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095);
181
182
775k
    mvx = ps_mv->i2_mvx;
183
775k
    mvy = ps_mv->i2_mvy;
184
185
775k
    mvx = SIGN(dist_scale_factor * mvx)
186
775k
                    * ((abs(dist_scale_factor * mvx) + 127) >> 8);
187
775k
    mvy = SIGN(dist_scale_factor * mvy)
188
775k
                    * ((abs(dist_scale_factor * mvy) + 127) >> 8);
189
190
775k
    ps_mv->i2_mvx = CLIP_S16(mvx);
191
775k
    ps_mv->i2_mvy = CLIP_S16(mvy);
192
775k
}
193
194
#define CHECK_NBR_MV_ST(pi4_avail_flag, cur_ref_poc, u1_nbr_pred_flag, nbr_ref_poc,         \
195
2.65M
                        ps_mv, ps_nbr_mv )                                                  \
196
2.65M
{                                                                                           \
197
2.65M
    if((u1_nbr_pred_flag) && (cur_ref_poc == nbr_ref_poc))                                  \
198
2.65M
    {                                                                                       \
199
1.31M
        *pi4_avail_flag = 1;                                                                \
200
1.31M
        *ps_mv = *ps_nbr_mv;                                                                \
201
1.31M
        break ;                                                                             \
202
1.31M
    }                                                                                       \
203
2.65M
}
204
#define CHECK_NBR_MV_LT(pi4_avail_flag, u1_cur_ref_lt, cur_poc, cur_ref_poc,                 \
205
                      u1_nbr_pred_flag, u1_nbr_ref_lt, nbr_ref_poc,                          \
206
452k
                      ps_mv, ps_nbr_mv )                                                     \
207
452k
{                                                                                            \
208
452k
    WORD32 cur_lt, nbr_lt;                                                                   \
209
452k
    cur_lt = (LONG_TERM_REF == (u1_cur_ref_lt));                                             \
210
452k
    nbr_lt = (LONG_TERM_REF == (u1_nbr_ref_lt));                                             \
211
452k
    if((u1_nbr_pred_flag) && (cur_lt == nbr_lt))                                             \
212
452k
    {                                                                                        \
213
304k
        *pi4_avail_flag = 1;                                                                 \
214
304k
        *ps_mv = *ps_nbr_mv;                                                                 \
215
304k
        if(SHORT_TERM_REF == u1_nbr_ref_lt)                                                  \
216
304k
        {                                                                                    \
217
302k
            ihevcd_scale_mv(ps_mv, cur_ref_poc, nbr_ref_poc,                                 \
218
302k
                                                cur_poc);                                    \
219
302k
        }                                                                                    \
220
304k
        break ;                                                                              \
221
304k
    }                                                                                        \
222
452k
}
223
224
225
void GET_MV_NBR_ST(ref_list_t **ps_ref_pic_list, WORD32 *pi4_avail_flag, pic_buf_t *ps_cur_pic_buf_lx, pu_t **aps_nbr_pu, mv_t *ps_mv, WORD32 num_nbrs, WORD32 lx)
226
1.85M
{
227
1.85M
    WORD32 i, nbr_pred_lx;
228
1.85M
    pic_buf_t *ps_nbr_pic_buf_lx;
229
    /* Short Term */
230
    /* L0 */
231
1.85M
    if(0 == lx)
232
1.33M
    {
233
1.73M
        for(i = 0; i < num_nbrs; i++)
234
1.35M
        {
235
1.35M
            nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode);
236
1.35M
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf));
237
1.35M
            CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx,
238
1.35M
                            ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv);
239
483k
            nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode);
240
241
483k
            nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode);
242
483k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf));
243
483k
            CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx,
244
483k
                            ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv);
245
403k
        }
246
1.33M
    }
247
    /* L1 */
248
517k
    else
249
517k
    {
250
699k
        for(i = 0; i < num_nbrs; i++)
251
542k
        {
252
542k
            nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode);
253
542k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf));
254
542k
            CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx,
255
542k
                            ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv);
256
257
269k
            nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode);
258
269k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf));
259
269k
            CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx,
260
269k
                            ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv);
261
181k
        }
262
517k
    }
263
1.85M
}
264
265
void GET_MV_NBR_LT(ref_list_t **ps_ref_pic_list, slice_header_t *ps_slice_hdr, WORD32 *pi4_avail_flag, pic_buf_t *ps_cur_pic_buf_lx, pu_t **aps_nbr_pu, mv_t *ps_mv, WORD32 num_nbrs, WORD32 lx)
266
435k
{
267
435k
    WORD32 i, nbr_pred_lx;
268
435k
    pic_buf_t *ps_nbr_pic_buf_lx;
269
    /* Long Term*/
270
    /* L0 */
271
435k
    if(0 == lx)
272
311k
    {
273
311k
        for(i = 0; i < num_nbrs; i++)
274
212k
        {
275
212k
            nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode);
276
212k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf));
277
212k
            CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc,
278
212k
                            nbr_pred_lx,
279
212k
                            ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc,
280
212k
                            ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv);
281
282
85.2k
            nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode);
283
85.2k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf));
284
85.2k
            CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc,
285
85.2k
                            nbr_pred_lx,
286
85.2k
                            ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc,
287
85.2k
                            ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv);
288
639
        }
289
311k
    }
290
    /* L1 */
291
124k
    else
292
124k
    {
293
124k
        for(i = 0; i < num_nbrs; i++)
294
92.6k
        {
295
92.6k
            nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode);
296
92.6k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf));
297
92.6k
            CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc,
298
92.6k
                            nbr_pred_lx,
299
92.6k
                            ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc,
300
92.6k
                            ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv);
301
302
62.8k
            nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode);
303
62.8k
            ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf));
304
62.8k
            CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc,
305
62.8k
                            nbr_pred_lx,
306
62.8k
                            ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc,
307
62.8k
                            ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv);
308
142
        }
309
124k
    }
310
435k
}
311
/**
312
 *******************************************************************************
313
 *
314
 * @brief
315
 * This function performs Motion Vector prediction and return a list of mv
316
 *
317
 * @par Description:
318
 *  MV predictor list is computed using neighbor mvs and colocated mv
319
 *
320
 * @param[in] ps_ctxt
321
 * pointer to mv predictor context
322
 *
323
 * @param[in] ps_top_nbr_4x4
324
 * pointer to top 4x4 nbr structure
325
 *
326
 * @param[in] ps_left_nbr_4x4
327
 * pointer to left 4x4 nbr structure
328
 *
329
 * @param[in] ps_top_left_nbr_4x4
330
 * pointer to top left 4x4 nbr structure
331
 *
332
 * @param[in] left_nbr_4x4_strd
333
 * left nbr buffer stride in terms of 4x4 units
334
 *
335
 * @param[in] ps_avail_flags
336
 * Neighbor availability flags container
337
 *
338
 * @param[in] ps_col_mv
339
 * Colocated MV pointer
340
 *
341
 * @param[in] ps_pu
342
 * Current Partition PU strucrture pointer
343
 *
344
 * @param[inout] ps_pred_mv
345
 * pointer to store predicted MV list
346
 *
347
 * @returns
348
 * None
349
 * @remarks
350
 *
351
 *
352
 *******************************************************************************
353
 */
354
void ihevcd_mv_pred(mv_ctxt_t *ps_mv_ctxt,
355
                    UWORD32 *pu4_top_pu_idx,
356
                    UWORD32 *pu4_left_pu_idx,
357
                    UWORD32 *pu4_top_left_pu_idx,
358
                    WORD32 left_nbr_4x4_strd,
359
                    pu_t *ps_pu,
360
                    WORD32 lb_avail,
361
                    WORD32 l_avail,
362
                    WORD32 tr_avail,
363
                    WORD32 t_avail,
364
                    WORD32 tl_avail,
365
                    pu_mv_t *ps_pred_mv)
366
896k
{
367
896k
    slice_header_t *ps_slice_hdr;
368
896k
    ref_list_t *ps_ref_pic_list[2];
369
896k
    pu_t *ps_pic_pu;
370
896k
    WORD32 max_l0_mvp_cand, max_l1_mvp_cand;
371
896k
    WORD32 l0_done_flag, l1_done_flag;
372
896k
    WORD32 num_l0_mvp_cand, num_l1_mvp_cand;
373
896k
    WORD32 is_scaled_flag_list /* Indicates whether A0 or A1 is available */;
374
896k
    WORD32 avail_a_flag[2];
375
896k
    mv_t as_mv_a[2];
376
896k
    WORD32 part_pos_x;
377
896k
    WORD32 part_pos_y;
378
896k
    WORD32 part_wd;
379
896k
    WORD32 part_ht;
380
896k
    pic_buf_t *ps_cur_pic_buf_l0, *ps_cur_pic_buf_l1;
381
896k
    WORD32 nbr_avail[3]; /*[A0/A1] */ /* [B0/B1/B2] */
382
896k
    pu_t *aps_nbr_pu[3];  /*[A0/A1] */ /* [B0/B1/B2] */
383
896k
    WORD32 num_nbrs = 0;
384
385
    /*******************************************/
386
    /* Neighbor location: Graphical indication */
387
    /*                                         */
388
    /*          B2 _____________B1 B0          */
389
    /*            |               |            */
390
    /*            |               |            */
391
    /*            |               |            */
392
    /*            |      PU     ht|            */
393
    /*            |               |            */
394
    /*            |               |            */
395
    /*          A1|______wd_______|            */
396
    /*          A0                             */
397
    /*                                         */
398
    /*******************************************/
399
400
896k
    ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
401
896k
    ps_pic_pu = ps_mv_ctxt->ps_pic_pu;
402
896k
    max_l0_mvp_cand = ps_pu->b1_l0_mvp_idx + 1;
403
896k
    max_l1_mvp_cand = ps_pu->b1_l1_mvp_idx + 1;
404
896k
    num_l0_mvp_cand = 0;
405
896k
    num_l1_mvp_cand = 0;
406
407
    /* Initializing reference list */
408
896k
    ps_ref_pic_list[0] = ps_slice_hdr->as_ref_pic_list0;
409
896k
    ps_ref_pic_list[1] = ps_slice_hdr->as_ref_pic_list1;
410
896k
    if(PSLICE == ps_slice_hdr->i1_slice_type)
411
32.6k
        ps_ref_pic_list[1] = ps_slice_hdr->as_ref_pic_list0;
412
413
896k
    ps_cur_pic_buf_l0 = (pic_buf_t *)((ps_ref_pic_list[0][ps_pu->mv.i1_l0_ref_idx].pv_pic_buf));
414
896k
    ps_cur_pic_buf_l1 = (pic_buf_t *)((ps_ref_pic_list[1][ps_pu->mv.i1_l1_ref_idx].pv_pic_buf));
415
416
896k
    is_scaled_flag_list = 0;
417
418
896k
    part_pos_x = ps_pu->b4_pos_x << 2;
419
896k
    part_pos_y = ps_pu->b4_pos_y << 2;
420
896k
    part_wd = (ps_pu->b4_wd + 1) << 2;
421
896k
    part_ht = (ps_pu->b4_ht + 1) << 2;
422
423
    /************************************************************/
424
    /* Calculating of motion vector A from neighbors A0 and A1  */
425
    /************************************************************/
426
896k
    {
427
896k
        nbr_avail[0] = 0;
428
896k
        nbr_avail[1] = 0;
429
430
        /* Pointers to A0 and A1 */
431
896k
        {
432
896k
            WORD32 y_a0, y_a1;
433
896k
            WORD32 pu_idx_a0, pu_idx_a1;
434
435
            /* TODO: y_a0, y_a1 is coded assuming left nbr pointer starts at PU */
436
896k
            y_a0 = (part_ht >> 2);
437
896k
            y_a1 = ((part_ht - 1) >> 2);
438
439
896k
            pu_idx_a0 = *(pu4_left_pu_idx + (y_a0 * left_nbr_4x4_strd));
440
896k
            pu_idx_a1 = *(pu4_left_pu_idx + (y_a1 * left_nbr_4x4_strd));
441
442
896k
            if(lb_avail && (!ps_pic_pu[pu_idx_a0].b1_intra_flag))
443
278k
            {
444
278k
                aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_a0];
445
278k
                num_nbrs++;
446
278k
                nbr_avail[0] = 1;
447
278k
            }
448
896k
            if(l_avail && (!ps_pic_pu[pu_idx_a1].b1_intra_flag))
449
810k
            {
450
810k
                aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_a1];
451
810k
                num_nbrs++;
452
810k
                nbr_avail[1] = 1;
453
810k
            }
454
896k
        }
455
        /* Setting is scaled flag based on availability of A0 and A1 */
456
896k
        if((nbr_avail[0] == 1) || (nbr_avail[1]))
457
816k
        {
458
816k
            is_scaled_flag_list = 1;
459
816k
        }
460
461
896k
        avail_a_flag[0] = 0;
462
896k
        avail_a_flag[1] = 0;
463
464
        /* L0 */
465
896k
        GET_MV_NBR_ST(ps_ref_pic_list, &avail_a_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_a[0], num_nbrs, 0);
466
896k
        if(0 == avail_a_flag[0])
467
261k
        {
468
261k
            GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_a_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_a[0], num_nbrs, 0);
469
261k
        }
470
471
        /* L1 */
472
896k
        if(PRED_L0 != ps_pu->b2_pred_mode)
473
342k
        {
474
342k
            GET_MV_NBR_ST(ps_ref_pic_list, &avail_a_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_a[1], num_nbrs, 1);
475
342k
            if(0 == avail_a_flag[1])
476
107k
            {
477
107k
                GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_a_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_a[1], num_nbrs, 1);
478
107k
            }
479
342k
        }
480
481
896k
        l0_done_flag = (PRED_L1 == ps_pu->b2_pred_mode);
482
896k
        l1_done_flag = (PRED_L0 == ps_pu->b2_pred_mode);
483
484
896k
        if(avail_a_flag[0])
485
815k
        {
486
815k
            num_l0_mvp_cand++;
487
815k
            if(max_l0_mvp_cand == num_l0_mvp_cand)
488
551k
            {
489
551k
                ps_pred_mv->s_l0_mv = as_mv_a[0];
490
551k
                l0_done_flag = 1;
491
551k
            }
492
815k
        }
493
896k
        if(avail_a_flag[1])
494
315k
        {
495
315k
            num_l1_mvp_cand++;
496
315k
            if(max_l1_mvp_cand == num_l1_mvp_cand)
497
188k
            {
498
188k
                ps_pred_mv->s_l1_mv = as_mv_a[1];
499
188k
                l1_done_flag = 1;
500
188k
            }
501
315k
        }
502
896k
        if(l0_done_flag && l1_done_flag)
503
458k
            return;
504
896k
    }
505
506
    /************************************************************/
507
    /* Calculating of motion vector B from neighbors B0 and B1  */
508
    /************************************************************/
509
438k
    {
510
438k
        WORD32 avail_b_flag[2];
511
438k
        mv_t as_mv_b[2];
512
513
        /* Pointers to B0, B1 and B2 */
514
438k
        {
515
438k
            WORD32 x_b0, x_b1, x_b2;
516
438k
            WORD32 pu_idx_b0, pu_idx_b1, pu_idx_b2;
517
518
            /* Relative co-ordiante of Xp,Yp w.r.t CTB start will work */
519
            /* as long as minCTB = 16                                  */
520
438k
            x_b0 = (part_pos_x + part_wd);
521
438k
            x_b1 = (part_pos_x + part_wd - 1);
522
438k
            x_b2 = (part_pos_x - 1);
523
            /* Getting offset back to given pointer */
524
438k
            x_b0 = x_b0 - part_pos_x;
525
438k
            x_b1 = x_b1 - part_pos_x;
526
438k
            x_b2 = x_b2 - part_pos_x;
527
528
            /* Below derivation are based on top pointer */
529
            /* is pointing first pixel of PU             */
530
438k
            pu_idx_b0 = *(pu4_top_pu_idx + (x_b0 >> 2));
531
438k
            pu_idx_b0 = pu_idx_b0 * tr_avail;
532
438k
            pu_idx_b1 = *(pu4_top_pu_idx + (x_b1 >> 2));
533
438k
            pu_idx_b1 = pu_idx_b1 * t_avail;
534
            /* At CTB boundary, use top-left passed in */
535
438k
            if(part_pos_y)
536
345k
            {
537
345k
                pu_idx_b2 = *pu4_top_left_pu_idx;
538
345k
            }
539
92.9k
            else
540
92.9k
            {
541
                /* Not at CTB boundary, use top and  */
542
                /* add correction to go to top-left */
543
92.9k
                pu_idx_b2 = *((pu4_top_pu_idx)+(x_b2 >> 2));
544
92.9k
            }
545
438k
            pu_idx_b2 = pu_idx_b2 * tl_avail;
546
547
438k
            num_nbrs = 0;
548
438k
            nbr_avail[0] = 0;
549
438k
            nbr_avail[1] = 0;
550
438k
            nbr_avail[2] = 0;
551
552
438k
            if(tr_avail && (!ps_pic_pu[pu_idx_b0].b1_intra_flag))
553
209k
            {
554
209k
                aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b0];
555
209k
                num_nbrs++;
556
209k
                nbr_avail[0] = 1;
557
209k
            }
558
438k
            if(t_avail && (!ps_pic_pu[pu_idx_b1].b1_intra_flag))
559
361k
            {
560
361k
                aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b1];
561
361k
                num_nbrs++;
562
361k
                nbr_avail[1] = 1;
563
361k
            }
564
438k
            if(tl_avail && (!ps_pic_pu[pu_idx_b2].b1_intra_flag))
565
323k
            {
566
323k
                aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b2];
567
323k
                num_nbrs++;
568
323k
                nbr_avail[2] = 1;
569
323k
            }
570
438k
        }
571
572
        /* L0 */
573
438k
        avail_b_flag[0] = 0;
574
438k
        avail_b_flag[1] = 0;
575
576
438k
        GET_MV_NBR_ST(ps_ref_pic_list, &avail_b_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_b[0], num_nbrs, 0);
577
578
        /* L1 */
579
438k
        if(PRED_L0 != ps_pu->b2_pred_mode)
580
176k
        {
581
            /* B0 Short Term */
582
176k
            GET_MV_NBR_ST(ps_ref_pic_list, &avail_b_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_b[1], num_nbrs, 1);
583
176k
        }
584
585
438k
        if(avail_b_flag[0])
586
319k
        {
587
319k
            if(((0 == num_l0_mvp_cand)
588
270k
                            || (as_mv_a[0].i2_mvx != as_mv_b[0].i2_mvx)
589
93.2k
                            || (as_mv_a[0].i2_mvy != as_mv_b[0].i2_mvy)))
590
256k
            {
591
256k
                num_l0_mvp_cand++;
592
256k
                if(max_l0_mvp_cand == num_l0_mvp_cand)
593
196k
                {
594
196k
                    ps_pred_mv->s_l0_mv = as_mv_b[0];
595
196k
                    l0_done_flag = 1;
596
196k
                }
597
256k
            }
598
319k
        }
599
438k
        if(avail_b_flag[1])
600
126k
        {
601
126k
            if(((0 == num_l1_mvp_cand)
602
109k
                            || (as_mv_a[1].i2_mvx != as_mv_b[1].i2_mvx)
603
42.7k
                            || (as_mv_a[1].i2_mvy != as_mv_b[1].i2_mvy)))
604
95.2k
            {
605
95.2k
                num_l1_mvp_cand++;
606
95.2k
                if(max_l1_mvp_cand == num_l1_mvp_cand)
607
79.1k
                {
608
79.1k
                    ps_pred_mv->s_l1_mv = as_mv_b[1];
609
79.1k
                    l1_done_flag = 1;
610
79.1k
                }
611
95.2k
            }
612
126k
        }
613
438k
        if(l0_done_flag && l1_done_flag)
614
238k
            return;
615
616
200k
        if((is_scaled_flag_list == 0) && (avail_b_flag[0] == 1))
617
18.6k
        {
618
18.6k
            avail_a_flag[0] = 1;
619
18.6k
            as_mv_a[0] = as_mv_b[0];
620
18.6k
        }
621
200k
        if((is_scaled_flag_list == 0) && (avail_b_flag[1] == 1))
622
7.31k
        {
623
7.31k
            avail_a_flag[1] = 1;
624
7.31k
            as_mv_a[1] = as_mv_b[1];
625
7.31k
        }
626
627
200k
        if(0 == is_scaled_flag_list)
628
49.6k
        {
629
49.6k
            avail_b_flag[0] = avail_b_flag[1] = 0;
630
631
49.6k
            GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_b_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_b[0], num_nbrs, 0);
632
633
49.6k
            if(PRED_L0 != ps_pu->b2_pred_mode)
634
16.8k
            {
635
16.8k
                GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_b_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_b[1], num_nbrs, 1);
636
16.8k
            }
637
638
49.6k
            if(avail_b_flag[0])
639
31.1k
            {
640
31.1k
                if(((0 == num_l0_mvp_cand)
641
18.6k
                                || (as_mv_a[0].i2_mvx != as_mv_b[0].i2_mvx)
642
17.4k
                                || (as_mv_a[0].i2_mvy != as_mv_b[0].i2_mvy)))
643
13.8k
                {
644
13.8k
                    num_l0_mvp_cand++;
645
13.8k
                    if(max_l0_mvp_cand == num_l0_mvp_cand)
646
9.46k
                    {
647
9.46k
                        ps_pred_mv->s_l0_mv = as_mv_b[0];
648
9.46k
                        l0_done_flag = 1;
649
9.46k
                    }
650
13.8k
                }
651
31.1k
            }
652
49.6k
            if(avail_b_flag[1])
653
11.5k
            {
654
11.5k
                if(((0 == num_l1_mvp_cand)
655
7.31k
                                || (as_mv_a[1].i2_mvx != as_mv_b[1].i2_mvx)
656
6.69k
                                || (as_mv_a[1].i2_mvy != as_mv_b[1].i2_mvy)))
657
4.98k
                {
658
4.98k
                    num_l1_mvp_cand++;
659
4.98k
                    if(max_l1_mvp_cand == num_l1_mvp_cand)
660
3.05k
                    {
661
3.05k
                        ps_pred_mv->s_l1_mv = as_mv_b[1];
662
3.05k
                        l1_done_flag = 1;
663
3.05k
                    }
664
4.98k
                }
665
11.5k
            }
666
49.6k
            if(l0_done_flag && l1_done_flag)
667
10.0k
                return;
668
49.6k
        }
669
        /***********************************************************/
670
        /*          Collocated MV prediction                       */
671
        /***********************************************************/
672
190k
        if((2 != num_l0_mvp_cand) || (2 != num_l1_mvp_cand))
673
190k
        {
674
190k
            mv_t as_mv_col[2], s_mv_col_l0, s_mv_col_l1;
675
190k
            WORD32 avail_col_flag[2] = { 0 };
676
190k
            WORD32 x_col, y_col, avail_col_l0, avail_col_l1;
677
//            ihevcd_collocated_mvp((mv_ctxt_t *)ps_mv_ctxt,ps_pu,part_pos_x,part_pos_y,part_wd,part_ht,as_mv_col,avail_col_flag,1);
678
190k
            x_col = part_pos_x + part_wd;
679
190k
            y_col = part_pos_y + part_ht;
680
190k
            ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 1, x_col, y_col);
681
682
190k
            avail_col_l0 = avail_col_flag[0];
683
190k
            avail_col_l1 = avail_col_flag[1];
684
190k
            if(avail_col_l0 || avail_col_l1)
685
109k
            {
686
109k
                s_mv_col_l0 = as_mv_col[0];
687
109k
                s_mv_col_l1 = as_mv_col[1];
688
109k
            }
689
690
190k
            if(avail_col_l0 == 0 || avail_col_l1 == 0)
691
81.9k
            {
692
                /* Checking Collocated MV availability at Center of PU */
693
81.9k
                x_col = part_pos_x + (part_wd >> 1);
694
81.9k
                y_col = part_pos_y + (part_ht >> 1);
695
81.9k
                ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 1, x_col, y_col);
696
697
81.9k
                if(avail_col_l0 == 0)
698
81.0k
                {
699
81.0k
                    s_mv_col_l0 = as_mv_col[0];
700
81.0k
                }
701
81.9k
                if(avail_col_l1 == 0)
702
81.7k
                {
703
81.7k
                    s_mv_col_l1 = as_mv_col[1];
704
81.7k
                }
705
706
81.9k
                avail_col_l0 |= avail_col_flag[0];
707
81.9k
                avail_col_l1 |= avail_col_flag[1];
708
81.9k
            }
709
710
            /* Checking if mvp index matches collocated mv */
711
190k
            if(avail_col_l0)
712
146k
            {
713
146k
                if(2 != num_l0_mvp_cand)
714
133k
                {
715
133k
                    num_l0_mvp_cand++;
716
133k
                    if(max_l0_mvp_cand == num_l0_mvp_cand)
717
100k
                    {
718
100k
                        ps_pred_mv->s_l0_mv = s_mv_col_l0;
719
100k
                        l0_done_flag = 1;
720
100k
                    }
721
133k
                }
722
146k
            }
723
190k
            if(avail_col_l1)
724
144k
            {
725
144k
                if(2 != num_l1_mvp_cand)
726
141k
                {
727
141k
                    num_l1_mvp_cand++;
728
141k
                    if(max_l1_mvp_cand == num_l1_mvp_cand)
729
134k
                    {
730
134k
                        ps_pred_mv->s_l1_mv = s_mv_col_l1;
731
134k
                        l1_done_flag = 1;
732
134k
                    }
733
141k
                }
734
144k
            }
735
190k
            if(l0_done_flag && l1_done_flag)
736
143k
                return;
737
190k
        }
738
739
46.4k
        if(0 == l0_done_flag)
740
36.7k
        {
741
36.7k
            ps_pred_mv->s_l0_mv.i2_mvx = 0;
742
36.7k
            ps_pred_mv->s_l0_mv.i2_mvy = 0;
743
36.7k
        }
744
46.4k
        if(0 == l1_done_flag)
745
16.4k
        {
746
16.4k
            ps_pred_mv->s_l1_mv.i2_mvx = 0;
747
16.4k
            ps_pred_mv->s_l1_mv.i2_mvy = 0;
748
16.4k
        }
749
46.4k
    }
750
46.4k
}