static int get_qPy_pred(HEVCContext *s, int xC, int yC,

                        int xBase, int yBase, int log2_cb_size)

{

    HEVCLocalContext *lc     = s->HEVClc;

    int ctb_size_mask        = (1 << s->sps->log2_ctb_size) - 1;

    int MinCuQpDeltaSizeMask = (1 << (s->sps->log2_ctb_size -

                                      s->pps->diff_cu_qp_delta_depth)) - 1;

    int xQgBase              = xBase - (xBase & MinCuQpDeltaSizeMask);

    int yQgBase              = yBase - (yBase & MinCuQpDeltaSizeMask);

    int min_cb_width         = s->sps->min_cb_width;

    int min_cb_height        = s->sps->min_cb_height;

    int x_cb                 = xQgBase >> s->sps->log2_min_cb_size;

    int y_cb                 = yQgBase >> s->sps->log2_min_cb_size;

    int availableA           = (xBase   & ctb_size_mask) &&

                               (xQgBase & ctb_size_mask);

    int availableB           = (yBase   & ctb_size_mask) &&

                               (yQgBase & ctb_size_mask);

    int qPy_pred, qPy_a, qPy_b;



    // qPy_pred

    if (lc->first_qp_group || (!xQgBase && !yQgBase)) {

        lc->first_qp_group = !lc->tu.is_cu_qp_delta_coded;

        qPy_pred = s->sh.slice_qp;

    } else {

        qPy_pred = lc->qp_y;

        if (log2_cb_size < s->sps->log2_ctb_size -

                           s->pps->diff_cu_qp_delta_depth) {

            static const int offsetX[8][8] = {

                { -1, 1, 3, 1, 7, 1, 3, 1 },

                {  0, 0, 0, 0, 0, 0, 0, 0 },

                {  1, 3, 1, 3, 1, 3, 1, 3 },

                {  2, 2, 2, 2, 2, 2, 2, 2 },

                {  3, 5, 7, 5, 3, 5, 7, 5 },

                {  4, 4, 4, 4, 4, 4, 4, 4 },

                {  5, 7, 5, 7, 5, 7, 5, 7 },

                {  6, 6, 6, 6, 6, 6, 6, 6 }

            };

            static const int offsetY[8][8] = {

                { 7, 0, 1, 2, 3, 4, 5, 6 },

                { 0, 1, 2, 3, 4, 5, 6, 7 },

                { 1, 0, 3, 2, 5, 4, 7, 6 },

                { 0, 1, 2, 3, 4, 5, 6, 7 },

                { 3, 0, 1, 2, 7, 4, 5, 6 },

                { 0, 1, 2, 3, 4, 5, 6, 7 },

                { 1, 0, 3, 2, 5, 4, 7, 6 },

                { 0, 1, 2, 3, 4, 5, 6, 7 }

            };

            int xC0b = (xC - (xC & ctb_size_mask)) >> s->sps->log2_min_cb_size;

            int yC0b = (yC - (yC & ctb_size_mask)) >> s->sps->log2_min_cb_size;

            int idxX = (xQgBase  & ctb_size_mask)  >> s->sps->log2_min_cb_size;

            int idxY = (yQgBase  & ctb_size_mask)  >> s->sps->log2_min_cb_size;

            int idx_mask = ctb_size_mask >> s->sps->log2_min_cb_size;

            int x, y;



            x = FFMIN(xC0b +  offsetX[idxX][idxY],             min_cb_width  - 1);

            y = FFMIN(yC0b + (offsetY[idxX][idxY] & idx_mask), min_cb_height - 1);



            if (xC0b == (lc->start_of_tiles_x >> s->sps->log2_min_cb_size) &&

                offsetX[idxX][idxY] == -1) {

                x = (lc->end_of_tiles_x >> s->sps->log2_min_cb_size) - 1;

                y = yC0b - 1;

            }

            qPy_pred = s->qp_y_tab[y * min_cb_width + x];

        }

    }



    // qPy_a

    if (availableA == 0)

        qPy_a = qPy_pred;

    else

        qPy_a = s->qp_y_tab[(x_cb - 1) + y_cb * min_cb_width];



    // qPy_b

    if (availableB == 0)

        qPy_b = qPy_pred;

    else

        qPy_b = s->qp_y_tab[x_cb + (y_cb - 1) * min_cb_width];



    av_assert2(qPy_a >= -s->sps->qp_bd_offset && qPy_a < 52);

    av_assert2(qPy_b >= -s->sps->qp_bd_offset && qPy_b < 52);



    return (qPy_a + qPy_b + 1) >> 1;

}
