/*
 * libx265 encoder
 *
 * Copyright (c) 2013-2014 Derek Buitenhuis
 *
 * 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
 */

#if defined(_MSC_VER)
#define X265_API_IMPORTS 1
#endif

#include <x265.h>
#include <float.h>

#include "libavutil/internal.h"
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "internal.h"
#include "packet_internal.h"

typedef struct libx265Context {
    const AVClass *class;

    x265_encoder *encoder;
    x265_param   *params;
    const x265_api *api;

    float crf;
    int   cqp;
    int   forced_idr;
    char *preset;
    char *tune;
    char *profile;
    AVDictionary *x265_opts;

    /**
     * If the encoder does not support ROI then warn the first time we
     * encounter a frame with ROI side data.
     */
    int roi_warned;
} libx265Context;

static int is_keyframe(NalUnitType naltype)
{
    switch (naltype) {
    case NAL_UNIT_CODED_SLICE_BLA_W_LP:
    case NAL_UNIT_CODED_SLICE_BLA_W_RADL:
    case NAL_UNIT_CODED_SLICE_BLA_N_LP:
    case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
    case NAL_UNIT_CODED_SLICE_IDR_N_LP:
    case NAL_UNIT_CODED_SLICE_CRA:
        return 1;
    default:
        return 0;
    }
}

static av_cold int libx265_encode_close(AVCodecContext *avctx)
{
    libx265Context *ctx = avctx->priv_data;

    ctx->api->param_free(ctx->params);

    if (ctx->encoder)
        ctx->api->encoder_close(ctx->encoder);

    return 0;
}

static av_cold int libx265_param_parse_float(AVCodecContext *avctx,
                                           const char *key, float value)
{
    libx265Context *ctx = avctx->priv_data;
    char buf[256];

    snprintf(buf, sizeof(buf), "%2.2f", value);
    if (ctx->api->param_parse(ctx->params, key, buf) == X265_PARAM_BAD_VALUE) {
        av_log(avctx, AV_LOG_ERROR, "Invalid value %2.2f for param \"%s\".\n", value, key);
        return AVERROR(EINVAL);
    }

    return 0;
}

static av_cold int libx265_param_parse_int(AVCodecContext *avctx,
                                           const char *key, int value)
{
    libx265Context *ctx = avctx->priv_data;
    char buf[256];

    snprintf(buf, sizeof(buf), "%d", value);
    if (ctx->api->param_parse(ctx->params, key, buf) == X265_PARAM_BAD_VALUE) {
        av_log(avctx, AV_LOG_ERROR, "Invalid value %d for param \"%s\".\n", value, key);
        return AVERROR(EINVAL);
    }

    return 0;
}

static av_cold int libx265_encode_init(AVCodecContext *avctx)
{
    libx265Context *ctx = avctx->priv_data;
    AVCPBProperties *cpb_props = NULL;
    int ret;

    ctx->api = x265_api_get(av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth);
    if (!ctx->api)
        ctx->api = x265_api_get(0);

    ctx->params = ctx->api->param_alloc();
    if (!ctx->params) {
        av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n");
        return AVERROR(ENOMEM);
    }

    if (ctx->api->param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) {
        int i;

        av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", ctx->preset, ctx->tune);
        av_log(avctx, AV_LOG_INFO, "Possible presets:");
        for (i = 0; x265_preset_names[i]; i++)
            av_log(avctx, AV_LOG_INFO, " %s", x265_preset_names[i]);

        av_log(avctx, AV_LOG_INFO, "\n");
        av_log(avctx, AV_LOG_INFO, "Possible tunes:");
        for (i = 0; x265_tune_names[i]; i++)
            av_log(avctx, AV_LOG_INFO, " %s", x265_tune_names[i]);

        av_log(avctx, AV_LOG_INFO, "\n");

        return AVERROR(EINVAL);
    }

    ctx->params->frameNumThreads = avctx->thread_count;
    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
        ctx->params->fpsNum      = avctx->framerate.num;
        ctx->params->fpsDenom    = avctx->framerate.den;
    } else {
        ctx->params->fpsNum      = avctx->time_base.den;
        ctx->params->fpsDenom    = avctx->time_base.num * avctx->ticks_per_frame;
    }
    ctx->params->sourceWidth     = avctx->width;
    ctx->params->sourceHeight    = avctx->height;
    ctx->params->bEnablePsnr     = !!(avctx->flags & AV_CODEC_FLAG_PSNR);
    ctx->params->bOpenGOP        = !(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);

    /* Tune the CTU size based on input resolution. */
    if (ctx->params->sourceWidth < 64 || ctx->params->sourceHeight < 64)
        ctx->params->maxCUSize = 32;
    if (ctx->params->sourceWidth < 32 || ctx->params->sourceHeight < 32)
        ctx->params->maxCUSize = 16;
    if (ctx->params->sourceWidth < 16 || ctx->params->sourceHeight < 16) {
        av_log(avctx, AV_LOG_ERROR, "Image size is too small (%dx%d).\n",
               ctx->params->sourceWidth, ctx->params->sourceHeight);
        return AVERROR(EINVAL);
    }


    ctx->params->vui.bEnableVideoSignalTypePresentFlag = 1;

    ctx->params->vui.bEnableVideoFullRangeFlag = avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
                                                 avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
                                                 avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
                                                 avctx->color_range == AVCOL_RANGE_JPEG;

    if ((avctx->color_primaries <= AVCOL_PRI_SMPTE432 &&
         avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) ||
        (avctx->color_trc <= AVCOL_TRC_ARIB_STD_B67 &&
         avctx->color_trc != AVCOL_TRC_UNSPECIFIED) ||
        (avctx->colorspace <= AVCOL_SPC_ICTCP &&
         avctx->colorspace != AVCOL_SPC_UNSPECIFIED)) {

        ctx->params->vui.bEnableColorDescriptionPresentFlag = 1;

        // x265 validates the parameters internally
        ctx->params->vui.colorPrimaries          = avctx->color_primaries;
        ctx->params->vui.transferCharacteristics = avctx->color_trc;
#if X265_BUILD >= 159
        if (avctx->color_trc == AVCOL_TRC_ARIB_STD_B67)
            ctx->params->preferredTransferCharacteristics = ctx->params->vui.transferCharacteristics;
#endif
        ctx->params->vui.matrixCoeffs            = avctx->colorspace;
    }

    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
        char sar[12];
        int sar_num, sar_den;

        av_reduce(&sar_num, &sar_den,
                  avctx->sample_aspect_ratio.num,
                  avctx->sample_aspect_ratio.den, 65535);
        snprintf(sar, sizeof(sar), "%d:%d", sar_num, sar_den);
        if (ctx->api->param_parse(ctx->params, "sar", sar) == X265_PARAM_BAD_VALUE) {
            av_log(avctx, AV_LOG_ERROR, "Invalid SAR: %d:%d.\n", sar_num, sar_den);
            return AVERROR_INVALIDDATA;
        }
    }

    switch (avctx->pix_fmt) {
    case AV_PIX_FMT_YUV420P:
    case AV_PIX_FMT_YUV420P10:
    case AV_PIX_FMT_YUV420P12:
        ctx->params->internalCsp = X265_CSP_I420;
        break;
    case AV_PIX_FMT_YUV422P:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV422P12:
        ctx->params->internalCsp = X265_CSP_I422;
        break;
    case AV_PIX_FMT_GBRP:
    case AV_PIX_FMT_GBRP10:
    case AV_PIX_FMT_GBRP12:
        ctx->params->vui.matrixCoeffs = AVCOL_SPC_RGB;
        ctx->params->vui.bEnableVideoSignalTypePresentFlag  = 1;
        ctx->params->vui.bEnableColorDescriptionPresentFlag = 1;
    case AV_PIX_FMT_YUV444P:
    case AV_PIX_FMT_YUV444P10:
    case AV_PIX_FMT_YUV444P12:
        ctx->params->internalCsp = X265_CSP_I444;
        break;
    case AV_PIX_FMT_GRAY8:
    case AV_PIX_FMT_GRAY10:
    case AV_PIX_FMT_GRAY12:
        if (ctx->api->api_build_number < 85) {
            av_log(avctx, AV_LOG_ERROR,
                   "libx265 version is %d, must be at least 85 for gray encoding.\n",
                   ctx->api->api_build_number);
            return AVERROR_INVALIDDATA;
        }
        ctx->params->internalCsp = X265_CSP_I400;
        break;
    }

    if (ctx->crf >= 0) {
        char crf[6];

        snprintf(crf, sizeof(crf), "%2.2f", ctx->crf);
        if (ctx->api->param_parse(ctx->params, "crf", crf) == X265_PARAM_BAD_VALUE) {
            av_log(avctx, AV_LOG_ERROR, "Invalid crf: %2.2f.\n", ctx->crf);
            return AVERROR(EINVAL);
        }
    } else if (avctx->bit_rate > 0) {
        ctx->params->rc.bitrate         = avctx->bit_rate / 1000;
        ctx->params->rc.rateControlMode = X265_RC_ABR;
    } else if (ctx->cqp >= 0) {
        ret = libx265_param_parse_int(avctx, "qp", ctx->cqp);
        if (ret < 0)
            return ret;
    }

#if X265_BUILD >= 89
    if (avctx->qmin >= 0) {
        ret = libx265_param_parse_int(avctx, "qpmin", avctx->qmin);
        if (ret < 0)
            return ret;
    }
    if (avctx->qmax >= 0) {
        ret = libx265_param_parse_int(avctx, "qpmax", avctx->qmax);
        if (ret < 0)
            return ret;
    }
#endif
    if (avctx->max_qdiff >= 0) {
        ret = libx265_param_parse_int(avctx, "qpstep", avctx->max_qdiff);
        if (ret < 0)
            return ret;
    }
    if (avctx->qblur >= 0) {
        ret = libx265_param_parse_float(avctx, "qblur", avctx->qblur);
        if (ret < 0)
            return ret;
    }
    if (avctx->qcompress >= 0) {
        ret = libx265_param_parse_float(avctx, "qcomp", avctx->qcompress);
        if (ret < 0)
            return ret;
    }
    if (avctx->i_quant_factor >= 0) {
        ret = libx265_param_parse_float(avctx, "ipratio", avctx->i_quant_factor);
        if (ret < 0)
            return ret;
    }
    if (avctx->b_quant_factor >= 0) {
        ret = libx265_param_parse_float(avctx, "pbratio", avctx->b_quant_factor);
        if (ret < 0)
            return ret;
    }

    ctx->params->rc.vbvBufferSize = avctx->rc_buffer_size / 1000;
    ctx->params->rc.vbvMaxBitrate = avctx->rc_max_rate    / 1000;

    cpb_props = ff_add_cpb_side_data(avctx);
    if (!cpb_props)
        return AVERROR(ENOMEM);
    cpb_props->buffer_size = ctx->params->rc.vbvBufferSize * 1000;
    cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000LL;
    cpb_props->avg_bitrate = ctx->params->rc.bitrate       * 1000LL;

    if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
        ctx->params->bRepeatHeaders = 1;

    if (avctx->gop_size >= 0) {
        ret = libx265_param_parse_int(avctx, "keyint", avctx->gop_size);
        if (ret < 0)
            return ret;
    }
    if (avctx->keyint_min > 0) {
        ret = libx265_param_parse_int(avctx, "min-keyint", avctx->keyint_min);
        if (ret < 0)
            return ret;
    }
    if (avctx->max_b_frames >= 0) {
        ret = libx265_param_parse_int(avctx, "bframes", avctx->max_b_frames);
        if (ret < 0)
            return ret;
    }
    if (avctx->refs >= 0) {
        ret = libx265_param_parse_int(avctx, "ref", avctx->refs);
        if (ret < 0)
            return ret;
    }

    {
        AVDictionaryEntry *en = NULL;
        while ((en = av_dict_get(ctx->x265_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
            int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value);

            switch (parse_ret) {
            case X265_PARAM_BAD_NAME:
                av_log(avctx, AV_LOG_WARNING,
                      "Unknown option: %s.\n", en->key);
                break;
            case X265_PARAM_BAD_VALUE:
                av_log(avctx, AV_LOG_WARNING,
                      "Invalid value for %s: %s.\n", en->key, en->value);
                break;
            default:
                break;
            }
        }
    }

    if (ctx->params->rc.vbvBufferSize && avctx->rc_initial_buffer_occupancy > 1000 &&
        ctx->params->rc.vbvBufferInit == 0.9) {
        ctx->params->rc.vbvBufferInit = (float)avctx->rc_initial_buffer_occupancy / 1000;
    }

    if (ctx->profile) {
        if (ctx->api->param_apply_profile(ctx->params, ctx->profile) < 0) {
            int i;
            av_log(avctx, AV_LOG_ERROR, "Invalid or incompatible profile set: %s.\n", ctx->profile);
            av_log(avctx, AV_LOG_INFO, "Possible profiles:");
            for (i = 0; x265_profile_names[i]; i++)
                av_log(avctx, AV_LOG_INFO, " %s", x265_profile_names[i]);
            av_log(avctx, AV_LOG_INFO, "\n");
            return AVERROR(EINVAL);
        }
    }

    ctx->encoder = ctx->api->encoder_open(ctx->params);
    if (!ctx->encoder) {
        av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");
        libx265_encode_close(avctx);
        return AVERROR_INVALIDDATA;
    }

    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
        x265_nal *nal;
        int nnal;

        avctx->extradata_size = ctx->api->encoder_headers(ctx->encoder, &nal, &nnal);
        if (avctx->extradata_size <= 0) {
            av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n");
            libx265_encode_close(avctx);
            return AVERROR_INVALIDDATA;
        }

        avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!avctx->extradata) {
            av_log(avctx, AV_LOG_ERROR,
                   "Cannot allocate HEVC header of size %d.\n", avctx->extradata_size);
            libx265_encode_close(avctx);
            return AVERROR(ENOMEM);
        }

        memcpy(avctx->extradata, nal[0].payload, avctx->extradata_size);
        memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    }

    return 0;
}

static av_cold int libx265_encode_set_roi(libx265Context *ctx, const AVFrame *frame, x265_picture* pic)
{
    AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
    if (sd) {
        if (ctx->params->rc.aqMode == X265_AQ_NONE) {
            if (!ctx->roi_warned) {
                ctx->roi_warned = 1;
                av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
            }
        } else {
            /* 8x8 block when qg-size is 8, 16*16 block otherwise. */
            int mb_size = (ctx->params->rc.qgSize == 8) ? 8 : 16;
            int mbx = (frame->width + mb_size - 1) / mb_size;
            int mby = (frame->height + mb_size - 1) / mb_size;
            int qp_range = 51 + 6 * (pic->bitDepth - 8);
            int nb_rois;
            const AVRegionOfInterest *roi;
            uint32_t roi_size;
            float *qoffsets;         /* will be freed after encode is called. */

            roi = (const AVRegionOfInterest*)sd->data;
            roi_size = roi->self_size;
            if (!roi_size || sd->size % roi_size != 0) {
                av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
                return AVERROR(EINVAL);
            }
            nb_rois = sd->size / roi_size;

            qoffsets = av_mallocz_array(mbx * mby, sizeof(*qoffsets));
            if (!qoffsets)
                return AVERROR(ENOMEM);

            // This list must be iterated in reverse because the first
            // region in the list applies when regions overlap.
            for (int i = nb_rois - 1; i >= 0; i--) {
                int startx, endx, starty, endy;
                float qoffset;

                roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);

                starty = FFMIN(mby, roi->top / mb_size);
                endy   = FFMIN(mby, (roi->bottom + mb_size - 1)/ mb_size);
                startx = FFMIN(mbx, roi->left / mb_size);
                endx   = FFMIN(mbx, (roi->right + mb_size - 1)/ mb_size);

                if (roi->qoffset.den == 0) {
                    av_free(qoffsets);
                    av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
                    return AVERROR(EINVAL);
                }
                qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
                qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);

                for (int y = starty; y < endy; y++)
                    for (int x = startx; x < endx; x++)
                        qoffsets[x + y*mbx] = qoffset;
            }

            pic->quantOffsets = qoffsets;
        }
    }
    return 0;
}

static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                const AVFrame *pic, int *got_packet)
{
    libx265Context *ctx = avctx->priv_data;
    x265_picture x265pic;
    x265_picture x265pic_out = { 0 };
    x265_nal *nal;
    uint8_t *dst;
    int pict_type;
    int payload = 0;
    int nnal;
    int ret;
    int i;

    ctx->api->picture_init(ctx->params, &x265pic);

    if (pic) {
        for (i = 0; i < 3; i++) {
           x265pic.planes[i] = pic->data[i];
           x265pic.stride[i] = pic->linesize[i];
        }

        x265pic.pts      = pic->pts;
        x265pic.bitDepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth;

        x265pic.sliceType = pic->pict_type == AV_PICTURE_TYPE_I ?
                                              (ctx->forced_idr ? X265_TYPE_IDR : X265_TYPE_I) :
                            pic->pict_type == AV_PICTURE_TYPE_P ? X265_TYPE_P :
                            pic->pict_type == AV_PICTURE_TYPE_B ? X265_TYPE_B :
                            X265_TYPE_AUTO;

        ret = libx265_encode_set_roi(ctx, pic, &x265pic);
        if (ret < 0)
            return ret;

        if (pic->reordered_opaque) {
            x265pic.userData = av_malloc(sizeof(pic->reordered_opaque));
            if (!x265pic.userData) {
                av_freep(&x265pic.quantOffsets);
                return AVERROR(ENOMEM);
            }

            memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque));
        }
    }

    ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
                                   pic ? &x265pic : NULL, &x265pic_out);

    av_freep(&x265pic.quantOffsets);

    if (ret < 0)
        return AVERROR_EXTERNAL;

    if (!nnal)
        return 0;

    for (i = 0; i < nnal; i++)
        payload += nal[i].sizeBytes;

    ret = ff_alloc_packet2(avctx, pkt, payload, payload);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
        return ret;
    }
    dst = pkt->data;

    for (i = 0; i < nnal; i++) {
        memcpy(dst, nal[i].payload, nal[i].sizeBytes);
        dst += nal[i].sizeBytes;

        if (is_keyframe(nal[i].type))
            pkt->flags |= AV_PKT_FLAG_KEY;
    }

    pkt->pts = x265pic_out.pts;
    pkt->dts = x265pic_out.dts;

    switch (x265pic_out.sliceType) {
    case X265_TYPE_IDR:
    case X265_TYPE_I:
        pict_type = AV_PICTURE_TYPE_I;
        break;
    case X265_TYPE_P:
        pict_type = AV_PICTURE_TYPE_P;
        break;
    case X265_TYPE_B:
    case X265_TYPE_BREF:
        pict_type = AV_PICTURE_TYPE_B;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered.\n");
        return AVERROR_EXTERNAL;
    }

#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
    avctx->coded_frame->pict_type = pict_type;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

#if X265_BUILD >= 130
    if (x265pic_out.sliceType == X265_TYPE_B)
#else
    if (x265pic_out.frameData.sliceType == 'b')
#endif
        pkt->flags |= AV_PKT_FLAG_DISPOSABLE;

    ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type);

    if (x265pic_out.userData) {
        memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque));
        av_freep(&x265pic_out.userData);
    } else
        avctx->reordered_opaque = 0;

    *got_packet = 1;
    return 0;
}

static const enum AVPixelFormat x265_csp_eight[] = {
    AV_PIX_FMT_YUV420P,
    AV_PIX_FMT_YUVJ420P,
    AV_PIX_FMT_YUV422P,
    AV_PIX_FMT_YUVJ422P,
    AV_PIX_FMT_YUV444P,
    AV_PIX_FMT_YUVJ444P,
    AV_PIX_FMT_GBRP,
    AV_PIX_FMT_GRAY8,
    AV_PIX_FMT_NONE
};

static const enum AVPixelFormat x265_csp_ten[] = {
    AV_PIX_FMT_YUV420P,
    AV_PIX_FMT_YUVJ420P,
    AV_PIX_FMT_YUV422P,
    AV_PIX_FMT_YUVJ422P,
    AV_PIX_FMT_YUV444P,
    AV_PIX_FMT_YUVJ444P,
    AV_PIX_FMT_GBRP,
    AV_PIX_FMT_YUV420P10,
    AV_PIX_FMT_YUV422P10,
    AV_PIX_FMT_YUV444P10,
    AV_PIX_FMT_GBRP10,
    AV_PIX_FMT_GRAY8,
    AV_PIX_FMT_GRAY10,
    AV_PIX_FMT_NONE
};

static const enum AVPixelFormat x265_csp_twelve[] = {
    AV_PIX_FMT_YUV420P,
    AV_PIX_FMT_YUVJ420P,
    AV_PIX_FMT_YUV422P,
    AV_PIX_FMT_YUVJ422P,
    AV_PIX_FMT_YUV444P,
    AV_PIX_FMT_YUVJ444P,
    AV_PIX_FMT_GBRP,
    AV_PIX_FMT_YUV420P10,
    AV_PIX_FMT_YUV422P10,
    AV_PIX_FMT_YUV444P10,
    AV_PIX_FMT_GBRP10,
    AV_PIX_FMT_YUV420P12,
    AV_PIX_FMT_YUV422P12,
    AV_PIX_FMT_YUV444P12,
    AV_PIX_FMT_GBRP12,
    AV_PIX_FMT_GRAY8,
    AV_PIX_FMT_GRAY10,
    AV_PIX_FMT_GRAY12,
    AV_PIX_FMT_NONE
};

static av_cold void libx265_encode_init_csp(AVCodec *codec)
{
    if (x265_api_get(12))
        codec->pix_fmts = x265_csp_twelve;
    else if (x265_api_get(10))
        codec->pix_fmts = x265_csp_ten;
    else if (x265_api_get(8))
        codec->pix_fmts = x265_csp_eight;
}

#define OFFSET(x) offsetof(libx265Context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    { "crf",         "set the x265 crf",                                                            OFFSET(crf),       AV_OPT_TYPE_FLOAT,  { .dbl = -1 }, -1, FLT_MAX, VE },
    { "qp",          "set the x265 qp",                                                             OFFSET(cqp),       AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE },
    { "forced-idr",  "if forcing keyframes, force them as IDR frames",                              OFFSET(forced_idr),AV_OPT_TYPE_BOOL,   { .i64 =  0 },  0,       1, VE },
    { "preset",      "set the x265 preset",                                                         OFFSET(preset),    AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    { "tune",        "set the x265 tune parameter",                                                 OFFSET(tune),      AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    { "profile",     "set the x265 profile",                                                        OFFSET(profile),   AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT,   { 0 }, 0, 0, VE },
    { NULL }
};

static const AVClass class = {
    .class_name = "libx265",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

static const AVCodecDefault x265_defaults[] = {
    { "b", "0" },
    { "bf", "-1" },
    { "g", "-1" },
    { "keyint_min", "-1" },
    { "refs", "-1" },
    { "qmin", "-1" },
    { "qmax", "-1" },
    { "qdiff", "-1" },
    { "qblur", "-1" },
    { "qcomp", "-1" },
    { "i_qfactor", "-1" },
    { "b_qfactor", "-1" },
    { NULL },
};

AVCodec ff_libx265_encoder = {
    .name             = "libx265",
    .long_name        = NULL_IF_CONFIG_SMALL("libx265 H.265 / HEVC"),
    .type             = AVMEDIA_TYPE_VIDEO,
    .id               = AV_CODEC_ID_HEVC,
    .init             = libx265_encode_init,
    .init_static_data = libx265_encode_init_csp,
    .encode2          = libx265_encode_frame,
    .close            = libx265_encode_close,
    .priv_data_size   = sizeof(libx265Context),
    .priv_class       = &class,
    .defaults         = x265_defaults,
    .capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .wrapper_name     = "libx265",
};
