/*
 * libxeve encoder
 * EVC (MPEG-5 Essential Video Coding) encoding using XEVE MPEG-5 EVC encoder library
 *
 * Copyright (C) 2021 Dawid Kozinski <d.kozinski@samsung.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <float.h>
#include <stdlib.h>

#include <xeve.h>

#include "libavutil/internal.h"
#include "libavutil/common.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/pixfmt.h"
#include "libavutil/time.h"
#include "libavutil/cpu.h"
#include "libavutil/avstring.h"

#include "avcodec.h"
#include "internal.h"
#include "packet_internal.h"
#include "codec_internal.h"
#include "profiles.h"
#include "encode.h"

#define MAX_BS_BUF (16*1024*1024)

/**
 * Error codes
 */
#define XEVE_PARAM_BAD_NAME -100
#define XEVE_PARAM_BAD_VALUE -200

/**
 * Encoder states
 *
 * STATE_ENCODING - the encoder receives and processes input frames
 * STATE_BUMPING  - there are no more input frames, however the encoder still processes previously received data
 */
typedef enum State {
    STATE_ENCODING,
    STATE_BUMPING,
} State;

/**
 * The structure stores all the states associated with the instance of Xeve MPEG-5 EVC encoder
 */
typedef struct XeveContext {
    const AVClass *class;

    XEVE id;            // XEVE instance identifier
    XEVE_CDSC cdsc;     // coding parameters i.e profile, width & height of input frame, num of therads, frame rate ...
    XEVE_BITB bitb;     // bitstream buffer (output)
    XEVE_STAT stat;     // encoding status (output)
    XEVE_IMGB imgb;     // image buffer (input)

    State state;        // encoder state (skipping, encoding, bumping)

    int profile_id;     // encoder profile (main, baseline)
    int preset_id;      // preset of xeve ( fast, medium, slow, placebo)
    int tune_id;        // tune of xeve (psnr, zerolatency)

    // variables for rate control modes
    int rc_mode;        // Rate control mode [ 0(CQP) / 1(ABR) / 2(CRF) ]
    int qp;             // quantization parameter (QP) [0,51]
    int crf;            // constant rate factor (CRF) [10,49]

    int hash;           // embed picture signature (HASH) for conformance checking in decoding
    int sei_info;       // embed Supplemental enhancement information while encoding

    int color_format;   // input data color format: currently only XEVE_CF_YCBCR420 is supported

    AVDictionary *xeve_params;
} XeveContext;

/**
 * Convert FFmpeg pixel format (AVPixelFormat) to XEVE pre-defined color format
 *
 * @param[in]  av_pix_fmt pixel format (@see https://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5)
 * @param[out] xeve_col_fmt XEVE pre-defined color format (@see xeve.h)
 *
 * @return 0 on success, negative value on failure
 */
static int libxeve_color_fmt(enum AVPixelFormat av_pix_fmt, int *xeve_col_fmt)
{
    switch (av_pix_fmt) {
    case AV_PIX_FMT_YUV420P:
        *xeve_col_fmt = XEVE_CF_YCBCR420;
        break;
    case AV_PIX_FMT_YUV420P10:
        *xeve_col_fmt = XEVE_CF_YCBCR420;
        break;
    default:
        *xeve_col_fmt = XEVE_CF_UNKNOWN;
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

/**
 * Convert FFmpeg pixel format (AVPixelFormat) into XEVE pre-defined color space
 *
 * @param[in] px_fmt pixel format (@see https://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5)
 *
 * @return XEVE pre-defined color space (@see xeve.h) on success, XEVE_CF_UNKNOWN on failure
 */
static int libxeve_color_space(enum AVPixelFormat av_pix_fmt)
{
    /* color space of input image */
    int cs = XEVE_CF_UNKNOWN;

    switch (av_pix_fmt) {
    case AV_PIX_FMT_YUV420P:
        cs = XEVE_CS_YCBCR420;
        break;
    case AV_PIX_FMT_YUV420P10:
#if AV_HAVE_BIGENDIAN
        cs = XEVE_CS_SET(XEVE_CF_YCBCR420, 10, 1);
#else
        cs = XEVE_CS_YCBCR420_10LE;
#endif

        break;
    default:
        cs = XEVE_CF_UNKNOWN;
        break;
    }

    return cs;
}

/**
 * The function returns a pointer to the object of the XEVE_CDSC type.
 * XEVE_CDSC contains all encoder parameters that should be initialized before the encoder is used.
 *
 * The field values of the XEVE_CDSC structure are populated based on:
 * - the corresponding field values of the AvCodecConetxt structure,
 * - the xeve encoder specific option values,
 *   (the full list of options available for xeve encoder is displayed after executing the command ./ffmpeg --help encoder = libxeve)
 *
 * The order of processing input data and populating the XEVE_CDSC structure
 * 1) first, the fields of the AVCodecContext structure corresponding to the provided input options are processed,
 *    (i.e -pix_fmt yuv420p -s:v 1920x1080 -r 30 -profile:v 0)
 * 2) then xeve-specific options added as AVOption to the xeve AVCodec implementation
 *    (i.e -preset 0)
 *
 * Keep in mind that, there are options that can be set in different ways.
 * In this case, please follow the above-mentioned order of processing.
 * The most recent assignments overwrite the previous values.
 *
 * @param[in] avctx codec context (AVCodecContext)
 * @param[out] cdsc contains all Xeve MPEG-5 EVC encoder encoder parameters that should be initialized before the encoder is use
 *
 * @return 0 on success, negative error code on failure
 */
static int get_conf(AVCodecContext *avctx, XEVE_CDSC *cdsc)
{
    XeveContext *xectx = NULL;
    int ret;

    xectx = avctx->priv_data;

    /* initialize xeve_param struct with default values */
    ret = xeve_param_default(&cdsc->param);
    if (XEVE_FAILED(ret)) {
        av_log(avctx, AV_LOG_ERROR, "Cannot set_default parameter\n");
        return AVERROR_EXTERNAL;
    }

    /* read options from AVCodecContext */
    if (avctx->width > 0)
        cdsc->param.w = avctx->width;

    if (avctx->height > 0)
        cdsc->param.h = avctx->height;

    if (avctx->framerate.num > 0) {
        // fps can be float number, but xeve API doesn't support it
        cdsc->param.fps = lrintf(av_q2d(avctx->framerate));
    }

    // GOP size (key-frame interval, I-picture period)
    cdsc->param.keyint = avctx->gop_size; // 0: only one I-frame at the first time; 1: every frame is coded in I-frame

    if (avctx->max_b_frames == 0 || avctx->max_b_frames == 1 || avctx->max_b_frames == 3 ||
        avctx->max_b_frames == 7 || avctx->max_b_frames == 15)   // number of b-frames
        cdsc->param.bframes = avctx->max_b_frames;
    else {
        av_log(avctx, AV_LOG_ERROR, "Incorrect value for maximum number of B frames: (%d) \n"
               "Acceptable values for bf option (maximum number of B frames) are 0,1,3,7 or 15\n", avctx->max_b_frames);
        return AVERROR_INVALIDDATA;
    }

    cdsc->param.level_idc = avctx->level;

    if (avctx->rc_buffer_size)   // VBV buf size
        cdsc->param.vbv_bufsize = (int)(avctx->rc_buffer_size / 1000);

    cdsc->param.rc_type = xectx->rc_mode;

    if (xectx->rc_mode == XEVE_RC_CQP)
        cdsc->param.qp = xectx->qp;
    else if (xectx->rc_mode == XEVE_RC_ABR) {
        if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > INT_MAX) {
            av_log(avctx, AV_LOG_ERROR, "Not supported bitrate bit_rate and rc_max_rate > %d000\n", INT_MAX);
            return AVERROR_INVALIDDATA;
        }
        cdsc->param.bitrate = (int)(avctx->bit_rate / 1000);
    } else if (xectx->rc_mode == XEVE_RC_CRF)
        cdsc->param.crf = xectx->crf;
    else {
        av_log(avctx, AV_LOG_ERROR, "Not supported rate control type: %d\n", xectx->rc_mode);
        return AVERROR_INVALIDDATA;
    }

    if (avctx->thread_count <= 0) {
        int cpu_count = av_cpu_count();
        cdsc->param.threads = (cpu_count < XEVE_MAX_THREADS) ? cpu_count : XEVE_MAX_THREADS;
    } else if (avctx->thread_count > XEVE_MAX_THREADS)
        cdsc->param.threads = XEVE_MAX_THREADS;
    else
        cdsc->param.threads = avctx->thread_count;


    libxeve_color_fmt(avctx->pix_fmt, &xectx->color_format);

    cdsc->param.cs = XEVE_CS_SET(xectx->color_format, cdsc->param.codec_bit_depth, AV_HAVE_BIGENDIAN);

    cdsc->max_bs_buf_size = MAX_BS_BUF;

    ret = xeve_param_ppt(&cdsc->param, xectx->profile_id, xectx->preset_id, xectx->tune_id);
    if (XEVE_FAILED(ret)) {
        av_log(avctx, AV_LOG_ERROR, "Cannot set profile(%d), preset(%d), tune(%d)\n", xectx->profile_id, xectx->preset_id, xectx->tune_id);
        return AVERROR_EXTERNAL;
    }

    return 0;
}

/**
 * Set XEVE_CFG_SET_USE_PIC_SIGNATURE for encoder
 *
 * @param[in] logger context
 * @param[in] id XEVE encodec instance identifier
 * @param[in] ctx the structure stores all the states associated with the instance of Xeve MPEG-5 EVC encoder
 *
 * @return 0 on success, negative error code on failure
 */
static int set_extra_config(AVCodecContext *avctx, XEVE id, XeveContext *ctx)
{
    int ret, size;
    size = 4;

    // embed SEI messages identifying encoder parameters and command line arguments
    // - 0: off\n"
    // - 1: emit sei info"
    //
    // SEI - Supplemental enhancement information contains information
    // that is not necessary to decode the samples of coded pictures from VCL NAL units.
    // Some SEI message information is required to check bitstream conformance
    // and for output timing decoder conformance.
    // @see ISO_IEC_23094-1_2020 7.4.3.5
    // @see ISO_IEC_23094-1_2020 Annex D
    ret = xeve_config(id, XEVE_CFG_SET_SEI_CMD, &ctx->sei_info, &size); // sei_cmd_info
    if (XEVE_FAILED(ret)) {
        av_log(avctx, AV_LOG_ERROR, "Failed to set config for sei command info messages\n");
        return AVERROR_EXTERNAL;
    }

    ret = xeve_config(id, XEVE_CFG_SET_USE_PIC_SIGNATURE, &ctx->hash, &size);
    if (XEVE_FAILED(ret)) {
        av_log(avctx, AV_LOG_ERROR, "Failed to set config for picture signature\n");
        return AVERROR_EXTERNAL;
    }

    return 0;
}

/**
 * @brief Switch encoder to bumping mode
 *
 * @param id XEVE encodec instance identifier
 * @return 0 on success, negative error code on failure
 */
static int setup_bumping(XEVE id)
{
    int val = 1;
    int size = sizeof(int);
    if (XEVE_FAILED(xeve_config(id, XEVE_CFG_SET_FORCE_OUT, (void *)(&val), &size)))
        return AVERROR_EXTERNAL;

    return 0;
}

/**
 * @brief Initialize eXtra-fast Essential Video Encoder codec
 * Create an encoder instance and allocate all the needed resources
 *
 * @param avctx codec context
 * @return 0 on success, negative error code on failure
 */
static av_cold int libxeve_init(AVCodecContext *avctx)
{
    XeveContext *xectx = avctx->priv_data;
    unsigned char *bs_buf = NULL;
    int i;
    int shift_h = 0;
    int shift_v = 0;
    int width_chroma = 0;
    int height_chroma = 0;
    XEVE_IMGB *imgb = NULL;
    int ret = 0;

    XEVE_CDSC *cdsc = &(xectx->cdsc);

    /* allocate bitstream buffer */
    bs_buf = av_malloc(MAX_BS_BUF);
    if (bs_buf == NULL) {
        av_log(avctx, AV_LOG_ERROR, "Cannot allocate bitstream buffer\n");
        return AVERROR(ENOMEM);
    }
    xectx->bitb.addr = bs_buf;
    xectx->bitb.bsize = MAX_BS_BUF;

    /* read configurations and set values for created descriptor (XEVE_CDSC) */
    if ((ret = get_conf(avctx, cdsc)) != 0) {
        av_log(avctx, AV_LOG_ERROR, "Cannot get configuration\n");
        return AVERROR(EINVAL);
    }

    if ((ret = xeve_param_check(&cdsc->param)) != 0) {
        av_log(avctx, AV_LOG_ERROR, "Invalid configuration\n");
        return AVERROR(EINVAL);
    }

    {
        const AVDictionaryEntry *en = NULL;
        while (en = av_dict_iterate(xectx->xeve_params, en)) {
            if ((ret = xeve_param_parse(&cdsc->param, en->key, en->value)) < 0) {
                av_log(avctx, AV_LOG_WARNING,
                       "Error parsing option '%s = %s'.\n",
                       en->key, en->value);
            }
        }
    }

    /* create encoder */
    xectx->id = xeve_create(cdsc, NULL);
    if (xectx->id == NULL) {
        av_log(avctx, AV_LOG_ERROR, "Cannot create XEVE encoder\n");
        return AVERROR_EXTERNAL;
    }

    if ((ret = set_extra_config(avctx, xectx->id, xectx)) != 0) {
        av_log(avctx, AV_LOG_ERROR, "Cannot set extra configuration\n");
        return AVERROR(EINVAL);
    }

    if ((ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v)) != 0) {
        av_log(avctx, AV_LOG_ERROR, "Failed to get  chroma shift\n");
        return AVERROR(EINVAL);
    }

    // Chroma subsampling
    //
    // YUV format explanation
    // shift_h == 1 && shift_v == 1 : YUV420
    // shift_h == 1 && shift_v == 0 : YUV422
    // shift_h == 0 && shift_v == 0 : YUV444
    //
    width_chroma = AV_CEIL_RSHIFT(avctx->width, shift_h);
    height_chroma = AV_CEIL_RSHIFT(avctx->height, shift_v);

    /* set default values for input image buffer */
    imgb = &xectx->imgb;
    imgb->cs = libxeve_color_space(avctx->pix_fmt);
    imgb->np = 3; /* only for yuv420p, yuv420ple */

    for (i = 0; i < imgb->np; i++)
        imgb->x[i] = imgb->y[i] = 0;

    imgb->w[0] = imgb->aw[0] = avctx->width; // width luma
    imgb->w[1] = imgb->w[2] = imgb->aw[1] = imgb->aw[2] = width_chroma;
    imgb->h[0] = imgb->ah[0] = avctx->height; // height luma
    imgb->h[1] = imgb->h[2] = imgb->ah[1] = imgb->ah[2] = height_chroma;

    xectx->state = STATE_ENCODING;

    return 0;
}

/**
  * Encode raw data frame into EVC packet
  *
  * @param[in]  avctx codec context
  * @param[out] avpkt output AVPacket containing encoded data
  * @param[in]  frame AVFrame containing the raw data to be encoded
  * @param[out] got_packet encoder sets to 0 or 1 to indicate that a
  *                         non-empty packet was returned in pkt
  *
  * @return 0 on success, negative error code on failure
  */
static int libxeve_encode(AVCodecContext *avctx, AVPacket *avpkt,
                          const AVFrame *frame, int *got_packet)
{
    XeveContext *xectx =  avctx->priv_data;
    int  ret = -1;

    // No more input frames are available but encoder still can have some data in its internal buffer to process
    // and some frames to dump.
    if (xectx->state == STATE_ENCODING && frame == NULL) {
        if (setup_bumping(xectx->id) == 0)
            xectx->state = STATE_BUMPING;  // Entering bumping process
        else {
            av_log(avctx, AV_LOG_ERROR, "Failed to setup bumping\n");
            return 0;
        }
    }

    if (xectx->state == STATE_ENCODING) {
        int i;
        XEVE_IMGB *imgb = NULL;

        imgb = &xectx->imgb;

        for (i = 0; i < imgb->np; i++) {
            imgb->a[i] = frame->data[i];
            imgb->s[i] = frame->linesize[i];
        }

        imgb->ts[XEVE_TS_PTS] = frame->pts;

        /* push image to encoder */
        ret = xeve_push(xectx->id, imgb);
        if (XEVE_FAILED(ret)) {
            av_log(avctx, AV_LOG_ERROR, "xeve_push() failed\n");
            return AVERROR_EXTERNAL;
        }
    }
    if (xectx->state == STATE_ENCODING || xectx->state == STATE_BUMPING) {
        /* encoding */
        ret = xeve_encode(xectx->id, &(xectx->bitb), &(xectx->stat));
        if (XEVE_FAILED(ret)) {
            av_log(avctx, AV_LOG_ERROR, "xeve_encode() failed\n");
            return AVERROR_EXTERNAL;
        }

        /* store bitstream */
        if (ret == XEVE_OK_OUT_NOT_AVAILABLE) { // Return OK but picture is not available yet
            *got_packet = 0;
            return 0;
        } else if (ret == XEVE_OK) {
            int av_pic_type;

            if (xectx->stat.write > 0) {

                ret = ff_get_encode_buffer(avctx, avpkt, xectx->stat.write, 0);
                if (ret < 0)
                    return ret;

                memcpy(avpkt->data, xectx->bitb.addr, xectx->stat.write);

                avpkt->time_base.num = 1;
                avpkt->time_base.den = xectx->cdsc.param.fps;

                avpkt->pts = xectx->bitb.ts[XEVE_TS_PTS];
                avpkt->dts = xectx->bitb.ts[XEVE_TS_DTS];

                switch(xectx->stat.stype) {
                case XEVE_ST_I:
                    av_pic_type = AV_PICTURE_TYPE_I;
                    avpkt->flags |= AV_PKT_FLAG_KEY;
                    break;
                case XEVE_ST_P:
                    av_pic_type = AV_PICTURE_TYPE_P;
                    break;
                case XEVE_ST_B:
                    av_pic_type = AV_PICTURE_TYPE_B;
                    break;
                case XEVE_ST_UNKNOWN:
                    av_log(avctx, AV_LOG_ERROR, "Unknown slice type\n");
                    return AVERROR_INVALIDDATA;
                }

                ff_side_data_set_encoder_stats(avpkt, xectx->stat.qp * FF_QP2LAMBDA, NULL, 0, av_pic_type);

                *got_packet = 1;
            }
        } else if (ret == XEVE_OK_NO_MORE_FRM) {
            // Return OK but no more frames
            return 0;
        } else {
            av_log(avctx, AV_LOG_ERROR, "Invalid return value: %d\n", ret);
            return AVERROR_EXTERNAL;
        }
    } else {
        av_log(avctx, AV_LOG_ERROR, "Udefined encoder state\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

/**
 * Destroy the encoder and release all the allocated resources
 *
 * @param avctx codec context
 * @return 0 on success, negative error code on failure
 */
static av_cold int libxeve_close(AVCodecContext *avctx)
{
    XeveContext *xectx = avctx->priv_data;

    if (xectx->id) {
        xeve_delete(xectx->id);
        xectx->id = NULL;
    }

    av_free(xectx->bitb.addr); /* release bitstream buffer */

    return 0;
}

#define OFFSET(x) offsetof(XeveContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM

static const enum AVPixelFormat supported_pixel_formats[] = {
    AV_PIX_FMT_YUV420P,
    AV_PIX_FMT_YUV420P10,
    AV_PIX_FMT_NONE
};

// Consider using following options (./ffmpeg --help encoder=libxeve)
//
static const AVOption libxeve_options[] = {
    { "preset", "Encoding preset for setting encoding speed", OFFSET(preset_id), AV_OPT_TYPE_INT, { .i64 = XEVE_PRESET_MEDIUM }, XEVE_PRESET_DEFAULT,  XEVE_PRESET_PLACEBO, VE, .unit = "preset" },
    { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "preset" },
    { "fast",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_FAST },    INT_MIN, INT_MAX, VE, .unit = "preset" },
    { "medium",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_MEDIUM },  INT_MIN, INT_MAX, VE, .unit = "preset" },
    { "slow",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_SLOW },    INT_MIN, INT_MAX, VE, .unit = "preset" },
    { "placebo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_PLACEBO }, INT_MIN, INT_MAX, VE, .unit = "preset" },
    { "tune", "Tuning parameter for special purpose operation", OFFSET(tune_id), AV_OPT_TYPE_INT, { .i64 = XEVE_TUNE_NONE }, XEVE_TUNE_NONE, XEVE_TUNE_PSNR, VE, .unit = "tune"},
    { "none",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_NONE },        INT_MIN, INT_MAX, VE, .unit = "tune" },
    { "zerolatency", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_ZEROLATENCY }, INT_MIN, INT_MAX, VE, .unit = "tune" },
    { "psnr",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_PSNR },        INT_MIN, INT_MAX, VE, .unit = "tune" },
    { "profile", "Encoding profile", OFFSET(profile_id), AV_OPT_TYPE_INT, { .i64 = XEVE_PROFILE_BASELINE }, XEVE_PROFILE_BASELINE,  XEVE_PROFILE_MAIN, VE, .unit = "profile" },
    { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PROFILE_BASELINE }, INT_MIN, INT_MAX, VE, .unit = "profile" },
    { "main",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PROFILE_MAIN },     INT_MIN, INT_MAX, VE, .unit = "profile" },
    { "rc_mode", "Rate control mode", OFFSET(rc_mode), AV_OPT_TYPE_INT, { .i64 = XEVE_RC_CQP }, XEVE_RC_CQP,  XEVE_RC_CRF, VE, .unit = "rc_mode" },
    { "CQP", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_CQP }, INT_MIN, INT_MAX, VE, .unit = "rc_mode" },
    { "ABR", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_ABR }, INT_MIN, INT_MAX, VE, .unit = "rc_mode" },
    { "CRF", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_CRF }, INT_MIN, INT_MAX, VE, .unit = "rc_mode" },
    { "qp", "Quantization parameter value for CQP rate control mode", OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE },
    { "crf", "Constant rate factor value for CRF rate control mode", OFFSET(crf), AV_OPT_TYPE_INT, { .i64 = 32 }, 10, 49, VE },
    { "hash", "Embed picture signature (HASH) for conformance checking in decoding", OFFSET(hash), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
    { "sei_info", "Embed SEI messages identifying encoder parameters and command line arguments", OFFSET(sei_info), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
    { "xeve-params",  "Override the xeve configuration using a :-separated list of key=value parameters", OFFSET(xeve_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
    { NULL }
};

static const AVClass libxeve_class = {
    .class_name = "libxeve",
    .item_name  = av_default_item_name,
    .option     = libxeve_options,
    .version    = LIBAVUTIL_VERSION_INT,
};

/**
 *  libavcodec generic global options, which can be set on all the encoders and decoders
 *  @see https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options
 */
static const FFCodecDefault libxeve_defaults[] = {
    { "b", "0" },       // bitrate in terms of kilo-bits per second
    { "g", "0" },       // gop_size (key-frame interval 0: only one I-frame at the first time; 1: every frame is coded in I-frame)
    { "bf", "15"},      // maximum number of B frames (0: no B-frames, 1,3,7,15)
    { "threads", "0"},  // number of threads to be used (0: automatically select the number of threads to set)
    { NULL },
};

const FFCodec ff_libxeve_encoder = {
    .p.name             = "libxeve",
    .p.long_name        = NULL_IF_CONFIG_SMALL("libxeve MPEG-5 EVC"),
    .p.type             = AVMEDIA_TYPE_VIDEO,
    .p.id               = AV_CODEC_ID_EVC,
    .init               = libxeve_init,
    FF_CODEC_ENCODE_CB(libxeve_encode),
    .close              = libxeve_close,
    .priv_data_size     = sizeof(XeveContext),
    .p.priv_class       = &libxeve_class,
    .defaults           = libxeve_defaults,
    .p.capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1,
    .p.profiles         = NULL_IF_CONFIG_SMALL(ff_evc_profiles),
    .p.wrapper_name     = "libxeve",
    .p.pix_fmts         = supported_pixel_formats,
    .caps_internal      = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_NOT_INIT_THREADSAFE,
};
