static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,

                             AVPacket *avpkt)

{

    int ret;

    int new_extradata_size;

    uint8_t *new_extradata;

    HEVCContext *s = avctx->priv_data;



    if (!avpkt->size) {

        ret = ff_hevc_output_frame(s, data, 1);

        if (ret < 0)

            return ret;



        *got_output = ret;

        return 0;

    }



    new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,

                                            &new_extradata_size);

    if (new_extradata && new_extradata_size > 0) {

        ret = hevc_decode_extradata(s, new_extradata, new_extradata_size);

        if (ret < 0)

            return ret;

    }



    s->ref = NULL;

    ret    = decode_nal_units(s, avpkt->data, avpkt->size);

    if (ret < 0)

        return ret;



    if (avctx->hwaccel) {

        if (s->ref && (ret = avctx->hwaccel->end_frame(avctx)) < 0) {

            av_log(avctx, AV_LOG_ERROR,

                   "hardware accelerator failed to decode picture\n");

            ff_hevc_unref_frame(s, s->ref, ~0);

            return ret;

        }

    } else {

        /* verify the SEI checksum */

        if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&

            s->sei.picture_hash.is_md5) {

            ret = verify_md5(s, s->ref->frame);

            if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {

                ff_hevc_unref_frame(s, s->ref, ~0);

                return ret;

            }

        }

    }

    s->sei.picture_hash.is_md5 = 0;



    if (s->is_decoded) {

        av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);

        s->is_decoded = 0;

    }



    if (s->output_frame->buf[0]) {

        av_frame_move_ref(data, s->output_frame);

        *got_output = 1;

    }



    return avpkt->size;

}
