void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,

                              int nPbH, int log2_cb_size, int part_idx,

                              int merge_idx, MvField *mv,

                              int mvp_lx_flag, int LX)

{

    HEVCLocalContext *lc = s->HEVClc;

    MvField *tab_mvf = s->ref->tab_mvf;

    int isScaledFlag_L0 = 0;

    int availableFlagLXA0 = 1;

    int availableFlagLXB0 = 1;

    int numMVPCandLX = 0;

    int min_pu_width = s->sps->min_pu_width;



    int xA0, yA0;

    int is_available_a0;

    int xA1, yA1;

    int is_available_a1;

    int xB0, yB0;

    int is_available_b0;

    int xB1, yB1;

    int is_available_b1;

    int xB2, yB2;

    int is_available_b2;



    Mv mvpcand_list[2] = { { 0 } };

    Mv mxA;

    Mv mxB;

    int ref_idx_curr = 0;

    int ref_idx = 0;

    int pred_flag_index_l0;

    int pred_flag_index_l1;



    const int cand_bottom_left = lc->na.cand_bottom_left;

    const int cand_left        = lc->na.cand_left;

    const int cand_up_left     = lc->na.cand_up_left;

    const int cand_up          = lc->na.cand_up;

    const int cand_up_right    = lc->na.cand_up_right_sap;

    ref_idx_curr       = LX;

    ref_idx            = mv->ref_idx[LX];

    pred_flag_index_l0 = LX;

    pred_flag_index_l1 = !LX;



    // left bottom spatial candidate

    xA0 = x0 - 1;

    yA0 = y0 + nPbH;



    is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&

                      yA0 < s->sps->height &&

                      PRED_BLOCK_AVAILABLE(A0);



    //left spatial merge candidate

    xA1    = x0 - 1;

    yA1    = y0 + nPbH - 1;



    is_available_a1 = AVAILABLE(cand_left, A1);

    if (is_available_a0 || is_available_a1)

        isScaledFlag_L0 = 1;



    if (is_available_a0) {

        if (MP_MX(A0, pred_flag_index_l0, mxA)) {

            goto b_candidates;

        }

        if (MP_MX(A0, pred_flag_index_l1, mxA)) {

            goto b_candidates;

        }

    }



    if (is_available_a1) {

        if (MP_MX(A1, pred_flag_index_l0, mxA)) {

            goto b_candidates;

        }

        if (MP_MX(A1, pred_flag_index_l1, mxA)) {

            goto b_candidates;

        }

    }



    if (is_available_a0) {

        if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) {

            goto b_candidates;

        }

        if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) {

            goto b_candidates;

        }

    }



    if (is_available_a1) {

        if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) {

            goto b_candidates;

        }

        if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) {

            goto b_candidates;

        }

    }

    availableFlagLXA0 = 0;



b_candidates:

    // B candidates

    // above right spatial merge candidate

    xB0    = x0 + nPbW;

    yB0    = y0 - 1;



    is_available_b0 =  AVAILABLE(cand_up_right, B0) &&

                       xB0 < s->sps->width &&

                       PRED_BLOCK_AVAILABLE(B0);



    // above spatial merge candidate

    xB1    = x0 + nPbW - 1;

    yB1    = y0 - 1;

    is_available_b1 = AVAILABLE(cand_up, B1);



    // above left spatial merge candidate

    xB2 = x0 - 1;

    yB2 = y0 - 1;

    is_available_b2 = AVAILABLE(cand_up_left, B2);



    // above right spatial merge candidate

    if (is_available_b0) {

        if (MP_MX(B0, pred_flag_index_l0, mxB)) {

            goto scalef;

        }

        if (MP_MX(B0, pred_flag_index_l1, mxB)) {

            goto scalef;

        }

    }



    // above spatial merge candidate

    if (is_available_b1) {

        if (MP_MX(B1, pred_flag_index_l0, mxB)) {

            goto scalef;

        }

        if (MP_MX(B1, pred_flag_index_l1, mxB)) {

            goto scalef;

        }

    }



    // above left spatial merge candidate

    if (is_available_b2) {

        if (MP_MX(B2, pred_flag_index_l0, mxB)) {

            goto scalef;

        }

        if (MP_MX(B2, pred_flag_index_l1, mxB)) {

            goto scalef;

        }

    }

    availableFlagLXB0 = 0;



scalef:

    if (!isScaledFlag_L0) {

        if (availableFlagLXB0) {

            availableFlagLXA0 = 1;

            mxA = mxB;

        }

        availableFlagLXB0 = 0;



        // XB0 and L1

        if (is_available_b0) {

            availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);

            if (!availableFlagLXB0)

                availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);

        }



        if (is_available_b1 && !availableFlagLXB0) {

            availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);

            if (!availableFlagLXB0)

                availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);

        }



        if (is_available_b2 && !availableFlagLXB0) {

            availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);

            if (!availableFlagLXB0)

                availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);

        }

    }



    if (availableFlagLXA0)

        mvpcand_list[numMVPCandLX++] = mxA;



    if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))

        mvpcand_list[numMVPCandLX++] = mxB;



    //temporal motion vector prediction candidate

    if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&

        mvp_lx_flag == numMVPCandLX) {

        Mv mv_col;

        int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,

                                                        nPbH, ref_idx,

                                                        &mv_col, LX);

        if (available_col)

            mvpcand_list[numMVPCandLX++] = mv_col;

    }



    mv->mv[LX] = mvpcand_list[mvp_lx_flag];

}
