int ff_hevc_decode_nal_vps(HEVCContext *s)

{

    int i,j;

    GetBitContext *gb = &s->HEVClc->gb;

    int vps_id = 0;

    HEVCVPS *vps;

    AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));



    if (!vps_buf)

        return AVERROR(ENOMEM);

    vps = (HEVCVPS*)vps_buf->data;



    av_log(s->avctx, AV_LOG_DEBUG, "Decoding VPS\n");



    vps_id = get_bits(gb, 4);

    if (vps_id >= MAX_VPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);

        goto err;

    }



    if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits

        av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");

        goto err;

    }



    vps->vps_max_layers               = get_bits(gb, 6) + 1;

    vps->vps_max_sub_layers           = get_bits(gb, 3) + 1;

    vps->vps_temporal_id_nesting_flag = get_bits1(gb);



    if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits

        av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");

        goto err;

    }



    if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {

        av_log(s->avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",

               vps->vps_max_sub_layers);

        goto err;

    }



    if (parse_ptl(s, &vps->ptl, vps->vps_max_sub_layers) < 0)

        goto err;



    vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);



    i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;

    for (; i < vps->vps_max_sub_layers; i++) {

        vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;

        vps->vps_num_reorder_pics[i]      = get_ue_golomb_long(gb);

        vps->vps_max_latency_increase[i]  = get_ue_golomb_long(gb) - 1;



        if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE || !vps->vps_max_dec_pic_buffering[i]) {

            av_log(s->avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n",

                   vps->vps_max_dec_pic_buffering[i] - 1);

            goto err;

        }

        if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {

            av_log(s->avctx, AV_LOG_WARNING, "vps_max_num_reorder_pics out of range: %d\n",

                   vps->vps_num_reorder_pics[i]);

            if (s->avctx->err_recognition & AV_EF_EXPLODE)

                goto err;

        }

    }



    vps->vps_max_layer_id   = get_bits(gb, 6);

    vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1;

    if (vps->vps_num_layer_sets < 1 || vps->vps_num_layer_sets > 1024 ||

        (vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "too many layer_id_included_flags\n");

        goto err;

    }



    for (i = 1; i < vps->vps_num_layer_sets; i++)

        for (j = 0; j <= vps->vps_max_layer_id; j++)

            skip_bits(gb, 1);  // layer_id_included_flag[i][j]



    vps->vps_timing_info_present_flag = get_bits1(gb);

    if (vps->vps_timing_info_present_flag) {

        vps->vps_num_units_in_tick               = get_bits_long(gb, 32);

        vps->vps_time_scale                      = get_bits_long(gb, 32);

        vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);

        if (vps->vps_poc_proportional_to_timing_flag)

            vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;

        vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);

        if (vps->vps_num_hrd_parameters > (unsigned)vps->vps_num_layer_sets) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters);

            goto err;

        }

        for (i = 0; i < vps->vps_num_hrd_parameters; i++) {

            int common_inf_present = 1;



            get_ue_golomb_long(gb); // hrd_layer_set_idx

            if (i)

                common_inf_present = get_bits1(gb);

            decode_hrd(s, common_inf_present, vps->vps_max_sub_layers);

        }

    }

    get_bits1(gb); /* vps_extension_flag */



    if (get_bits_left(gb) < 0) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Overread VPS by %d bits\n", -get_bits_left(gb));

        goto err;

    }



    if (s->vps_list[vps_id] &&

        !memcmp(s->vps_list[vps_id]->data, vps_buf->data, vps_buf->size)) {

        av_buffer_unref(&vps_buf);

    } else {

        remove_vps(s, vps_id);

        s->vps_list[vps_id] = vps_buf;

    }



    return 0;



err:

    av_buffer_unref(&vps_buf);

    return AVERROR_INVALIDDATA;

}
