static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
                                 int ctb_addr_ts)
{
    HEVCLocalContext *lc  = &s->HEVClc;
    int ctb_size          = 1 << s->sps->log2_ctb_size;
    int ctb_addr_rs       = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
    int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr;

    int tile_left_boundary, tile_up_boundary;
    int slice_left_boundary, slice_up_boundary;

    s->tab_slice_address[ctb_addr_rs] = s->sh.slice_addr;

    if (s->pps->entropy_coding_sync_enabled_flag) {
        if (x_ctb == 0 && (y_ctb & (ctb_size - 1)) == 0)
            lc->first_qp_group = 1;
        lc->end_of_tiles_x = s->sps->width;
    } else if (s->pps->tiles_enabled_flag) {
        if (ctb_addr_ts && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
            int idxX = s->pps->col_idxX[x_ctb >> s->sps->log2_ctb_size];
            lc->start_of_tiles_x = x_ctb;
            lc->end_of_tiles_x   = x_ctb + (s->pps->column_width[idxX] << s->sps->log2_ctb_size);
            lc->first_qp_group   = 1;
        }
    } else {
        lc->end_of_tiles_x = s->sps->width;
    }

    lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, s->sps->height);

    if (s->pps->tiles_enabled_flag) {
        tile_left_boundary  = x_ctb > 0 &&
                              s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - 1]];
        slice_left_boundary = x_ctb > 0 &&
                              s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - 1];
        tile_up_boundary  = y_ctb > 0 &&
                            s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
        slice_up_boundary = y_ctb > 0 &&
                            s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - s->sps->ctb_width];
    } else {
        tile_left_boundary  =
        tile_up_boundary    = 1;
        slice_left_boundary = ctb_addr_in_slice > 0;
        slice_up_boundary   = ctb_addr_in_slice >= s->sps->ctb_width;
    }
    lc->slice_or_tiles_left_boundary = (!slice_left_boundary) + (!tile_left_boundary << 1);
    lc->slice_or_tiles_up_boundary   = (!slice_up_boundary + (!tile_up_boundary << 1));
    lc->ctb_left_flag = ((x_ctb > 0) && (ctb_addr_in_slice > 0) && tile_left_boundary);
    lc->ctb_up_flag   = ((y_ctb > 0) && (ctb_addr_in_slice >= s->sps->ctb_width) && tile_up_boundary);
    lc->ctb_up_right_flag = ((y_ctb > 0)  && (ctb_addr_in_slice+1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs+1 - s->sps->ctb_width]]));
    lc->ctb_up_left_flag = ((x_ctb > 0) && (y_ctb > 0)  && (ctb_addr_in_slice-1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1 - s->sps->ctb_width]]));
}
static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
                                 int ctb_addr_ts)
{
    HEVCLocalContext *lc  = &s->HEVClc;
    int ctb_size          = 1 << s->sps->log2_ctb_size;
    int ctb_addr_rs       = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
    int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr;

    int tile_left_boundary, tile_up_boundary;
    int slice_left_boundary, slice_up_boundary;

    s->tab_slice_address[ctb_addr_rs] = s->sh.slice_addr;

    if (s->pps->entropy_coding_sync_enabled_flag) {
        if (x_ctb == 0 && (y_ctb & (ctb_size - 1)) == 0)
            lc->first_qp_group = 1;
        lc->end_of_tiles_x = s->sps->width;
    } else if (s->pps->tiles_enabled_flag) {
        if (ctb_addr_ts && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
            int idxX = s->pps->col_idxX[x_ctb >> s->sps->log2_ctb_size];
            lc->start_of_tiles_x = x_ctb;
            lc->end_of_tiles_x   = x_ctb + (s->pps->column_width[idxX] << s->sps->log2_ctb_size);
            lc->first_qp_group   = 1;
        }
    } else {
        lc->end_of_tiles_x = s->sps->width;
    }

    lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, s->sps->height);

    if (s->pps->tiles_enabled_flag) {
        tile_left_boundary  = x_ctb > 0 &&
                              s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - 1]];
        slice_left_boundary = x_ctb > 0 &&
                              s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - 1];
        tile_up_boundary  = y_ctb > 0 &&
                            s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
        slice_up_boundary = y_ctb > 0 &&
                            s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - s->sps->ctb_width];
    } else {
        tile_left_boundary  =
        tile_up_boundary    = 1;
        slice_left_boundary = ctb_addr_in_slice > 0;
        slice_up_boundary   = ctb_addr_in_slice >= s->sps->ctb_width;
    }
    lc->slice_or_tiles_left_boundary = (!slice_left_boundary) + (!tile_left_boundary << 1);
    lc->slice_or_tiles_up_boundary   = (!slice_up_boundary + (!tile_up_boundary << 1));
    lc->ctb_left_flag = ((x_ctb > 0) && (ctb_addr_in_slice > 0) && tile_left_boundary);
    lc->ctb_up_flag   = ((y_ctb > 0) && (ctb_addr_in_slice >= s->sps->ctb_width) && tile_up_boundary);
    lc->ctb_up_right_flag = ((y_ctb > 0)  && (ctb_addr_in_slice+1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs+1 - s->sps->ctb_width]]));
    lc->ctb_up_left_flag = ((x_ctb > 0) && (y_ctb > 0)  && (ctb_addr_in_slice-1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1 - s->sps->ctb_width]]));
}