/*
 * Interface to xvidcore for mpeg4 encoding
 * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net>
 *
 * 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
 */

/**
 * @file
 * Interface to xvidcore for MPEG-4 compliant encoding.
 * @author Adam Thayer (krevnik@comcast.net)
 */

#include <xvid.h>

#include "libavutil/cpu.h"
#include "libavutil/file.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"

#include "avcodec.h"
#include "internal.h"
#include "libxvid.h"
#include "mpegvideo.h"

#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#if HAVE_IO_H
#include <io.h>
#endif

/**
 * Buffer management macros.
 */
#define BUFFER_SIZE         1024
#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
#define BUFFER_CAT(x)       (&((x)[strlen(x)]))

/**
 * Structure for the private Xvid context.
 * This stores all the private context for the codec.
 */
struct xvid_context {
    AVClass *class;
    void *encoder_handle;          /**< Handle for Xvid encoder */
    int xsize;                     /**< Frame x size */
    int ysize;                     /**< Frame y size */
    int vop_flags;                 /**< VOP flags for Xvid encoder */
    int vol_flags;                 /**< VOL flags for Xvid encoder */
    int me_flags;                  /**< Motion Estimation flags */
    int qscale;                    /**< Do we use constant scale? */
    int quicktime_format;          /**< Are we in a QT-based format? */
    char *twopassbuffer;           /**< Character buffer for two-pass */
    char *old_twopassbuffer;       /**< Old character buffer (two-pass) */
    char *twopassfile;             /**< second pass temp file name */
    int twopassfd;
    unsigned char *intra_matrix;   /**< P-Frame Quant Matrix */
    unsigned char *inter_matrix;   /**< I-Frame Quant Matrix */
    int lumi_aq;                   /**< Lumi masking as an aq method */
    int variance_aq;               /**< Variance adaptive quantization */
    int ssim;                      /**< SSIM information display mode */
    int ssim_acc;                  /**< SSIM accuracy. 0: accurate. 4: fast. */
    int gmc;
    int me_quality;                /**< Motion estimation quality. 0: fast 6: best. */
};

/**
 * Structure for the private first-pass plugin.
 */
struct xvid_ff_pass1 {
    int version;                    /**< Xvid version */
    struct xvid_context *context;   /**< Pointer to private context */
};

static int xvid_encode_close(AVCodecContext *avctx);

/*
 * Xvid 2-Pass Kludge Section
 *
 * Xvid's default 2-pass doesn't allow us to create data as we need to, so
 * this section spends time replacing the first pass plugin so we can write
 * statistic information as libavcodec requests in. We have another kludge
 * that allows us to pass data to the second pass in Xvid without a custom
 * rate-control plugin.
 */

/**
 * Initialize the two-pass plugin and context.
 *
 * @param param Input construction parameter structure
 * @param handle Private context handle
 * @return Returns XVID_ERR_xxxx on failure, or 0 on success.
 */
static int xvid_ff_2pass_create(xvid_plg_create_t *param, void **handle)
{
    struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *) param->param;
    char *log = x->context->twopassbuffer;

    /* Do a quick bounds check */
    if (!log)
        return XVID_ERR_FAIL;

    /* We use snprintf() */
    /* This is because we can safely prevent a buffer overflow */
    log[0] = 0;
    snprintf(log, BUFFER_REMAINING(log),
             "# ffmpeg 2-pass log file, using xvid codec\n");
    snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
             "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
             XVID_VERSION_MAJOR(XVID_VERSION),
             XVID_VERSION_MINOR(XVID_VERSION),
             XVID_VERSION_PATCH(XVID_VERSION));

    *handle = x->context;
    return 0;
}

/**
 * Destroy the two-pass plugin context.
 *
 * @param ref Context pointer for the plugin
 * @param param Destrooy context
 * @return Returns 0, success guaranteed
 */
static int xvid_ff_2pass_destroy(struct xvid_context *ref,
                                 xvid_plg_destroy_t *param)
{
    /* Currently cannot think of anything to do on destruction */
    /* Still, the framework should be here for reference/use */
    if (ref->twopassbuffer)
        ref->twopassbuffer[0] = 0;
    return 0;
}

/**
 * Enable fast encode mode during the first pass.
 *
 * @param ref Context pointer for the plugin
 * @param param Frame data
 * @return Returns 0, success guaranteed
 */
static int xvid_ff_2pass_before(struct xvid_context *ref,
                                xvid_plg_data_t *param)
{
    int motion_remove;
    int motion_replacements;
    int vop_remove;

    /* Nothing to do here, result is changed too much */
    if (param->zone && param->zone->mode == XVID_ZONE_QUANT)
        return 0;

    /* We can implement a 'turbo' first pass mode here */
    param->quant = 2;

    /* Init values */
    motion_remove       = ~XVID_ME_CHROMA_PVOP &
                          ~XVID_ME_CHROMA_BVOP &
                          ~XVID_ME_EXTSEARCH16 &
                          ~XVID_ME_ADVANCEDDIAMOND16;
    motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
                          XVID_ME_SKIP_DELTASEARCH     |
                          XVID_ME_FASTREFINE16         |
                          XVID_ME_BFRAME_EARLYSTOP;
    vop_remove          = ~XVID_VOP_MODEDECISION_RD      &
                          ~XVID_VOP_FAST_MODEDECISION_RD &
                          ~XVID_VOP_TRELLISQUANT         &
                          ~XVID_VOP_INTER4V              &
                          ~XVID_VOP_HQACPRED;

    param->vol_flags    &= ~XVID_VOL_GMC;
    param->vop_flags    &= vop_remove;
    param->motion_flags &= motion_remove;
    param->motion_flags |= motion_replacements;

    return 0;
}

/**
 * Capture statistic data and write it during first pass.
 *
 * @param ref Context pointer for the plugin
 * @param param Statistic data
 * @return Returns XVID_ERR_xxxx on failure, or 0 on success
 */
static int xvid_ff_2pass_after(struct xvid_context *ref,
                               xvid_plg_data_t *param)
{
    char *log = ref->twopassbuffer;
    const char *frame_types = " ipbs";
    char frame_type;

    /* Quick bounds check */
    if (!log)
        return XVID_ERR_FAIL;

    /* Convert the type given to us into a character */
    if (param->type < 5 && param->type > 0)
        frame_type = frame_types[param->type];
    else
        return XVID_ERR_FAIL;

    snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
             "%c %d %d %d %d %d %d\n",
             frame_type, param->stats.quant, param->stats.kblks,
             param->stats.mblks, param->stats.ublks,
             param->stats.length, param->stats.hlength);

    return 0;
}

/**
 * Dispatch function for our custom plugin.
 * This handles the dispatch for the Xvid plugin. It passes data
 * on to other functions for actual processing.
 *
 * @param ref Context pointer for the plugin
 * @param cmd The task given for us to complete
 * @param p1 First parameter (varies)
 * @param p2 Second parameter (varies)
 * @return Returns XVID_ERR_xxxx on failure, or 0 on success
 */
static int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2)
{
    switch (cmd) {
    case XVID_PLG_INFO:
    case XVID_PLG_FRAME:
        return 0;
    case XVID_PLG_BEFORE:
        return xvid_ff_2pass_before(ref, p1);
    case XVID_PLG_CREATE:
        return xvid_ff_2pass_create(p1, p2);
    case XVID_PLG_AFTER:
        return xvid_ff_2pass_after(ref, p1);
    case XVID_PLG_DESTROY:
        return xvid_ff_2pass_destroy(ref, p1);
    default:
        return XVID_ERR_FAIL;
    }
}

/**
 * Routine to create a global VO/VOL header for MP4 container.
 * What we do here is extract the header from the Xvid bitstream
 * as it is encoded. We also strip the repeated headers from the
 * bitstream when a global header is requested for MPEG-4 ISO
 * compliance.
 *
 * @param avctx AVCodecContext pointer to context
 * @param frame Pointer to encoded frame data
 * @param header_len Length of header to search
 * @param frame_len Length of encoded frame data
 * @return Returns new length of frame data
 */
static int xvid_strip_vol_header(AVCodecContext *avctx, AVPacket *pkt,
                                 unsigned int header_len,
                                 unsigned int frame_len)
{
    int vo_len = 0, i;

    for (i = 0; i < header_len - 3; i++) {
        if (pkt->data[i]     == 0x00 &&
            pkt->data[i + 1] == 0x00 &&
            pkt->data[i + 2] == 0x01 &&
            pkt->data[i + 3] == 0xB6) {
            vo_len = i;
            break;
        }
    }

    if (vo_len > 0) {
        /* We need to store the header, so extract it */
        if (!avctx->extradata) {
            avctx->extradata = av_malloc(vo_len);
            if (!avctx->extradata)
                return AVERROR(ENOMEM);
            memcpy(avctx->extradata, pkt->data, vo_len);
            avctx->extradata_size = vo_len;
        }
        /* Less dangerous now, memmove properly copies the two
         * chunks of overlapping data */
        memmove(pkt->data, &pkt->data[vo_len], frame_len - vo_len);
        pkt->size = frame_len - vo_len;
    }
    return 0;
}

/**
 * Routine to correct a possibly erroneous framerate being fed to us.
 * Xvid currently chokes on framerates where the ticks per frame is
 * extremely large. This function works to correct problems in this area
 * by estimating a new framerate and taking the simpler fraction of
 * the two presented.
 *
 * @param avctx Context that contains the framerate to correct.
 */
static void xvid_correct_framerate(AVCodecContext *avctx)
{
    int frate, fbase;
    int est_frate, est_fbase;
    int gcd;
    float est_fps, fps;

    frate = avctx->time_base.den;
    fbase = avctx->time_base.num;

    gcd = av_gcd(frate, fbase);
    if (gcd > 1) {
        frate /= gcd;
        fbase /= gcd;
    }

    if (frate <= 65000 && fbase <= 65000) {
        avctx->time_base.den = frate;
        avctx->time_base.num = fbase;
        return;
    }

    fps     = (float) frate / (float) fbase;
    est_fps = roundf(fps * 1000.0) / 1000.0;

    est_frate = (int) est_fps;
    if (est_fps > (int) est_fps) {
        est_frate = (est_frate + 1) * 1000;
        est_fbase = (int) roundf((float) est_frate / est_fps);
    } else
        est_fbase = 1;

    gcd = av_gcd(est_frate, est_fbase);
    if (gcd > 1) {
        est_frate /= gcd;
        est_fbase /= gcd;
    }

    if (fbase > est_fbase) {
        avctx->time_base.den = est_frate;
        avctx->time_base.num = est_fbase;
        av_log(avctx, AV_LOG_DEBUG,
               "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
               est_fps, (((est_fps - fps) / fps) * 100.0));
    } else {
        avctx->time_base.den = frate;
        avctx->time_base.num = fbase;
    }
}

static av_cold int xvid_encode_init(AVCodecContext *avctx)
{
    int xerr, i, ret = -1;
    int xvid_flags = avctx->flags;
    struct xvid_context *x = avctx->priv_data;
    uint16_t *intra, *inter;
    int fd;

    xvid_plugin_single_t      single          = { 0 };
    struct xvid_ff_pass1      rc2pass1        = { 0 };
    xvid_plugin_2pass2_t      rc2pass2        = { 0 };
    xvid_plugin_lumimasking_t masking_l       = { 0 }; /* For lumi masking */
    xvid_plugin_lumimasking_t masking_v       = { 0 }; /* For variance AQ */
    xvid_plugin_ssim_t        ssim            = { 0 };
    xvid_gbl_init_t           xvid_gbl_init   = { 0 };
    xvid_enc_create_t         xvid_enc_create = { 0 };
    xvid_enc_plugin_t         plugins[4];

    x->twopassfd = -1;

    /* Bring in VOP flags from ffmpeg command-line */
    x->vop_flags = XVID_VOP_HALFPEL;              /* Bare minimum quality */
    if (xvid_flags & AV_CODEC_FLAG_4MV)
        x->vop_flags    |= XVID_VOP_INTER4V;      /* Level 3 */
    if (avctx->trellis)
        x->vop_flags    |= XVID_VOP_TRELLISQUANT; /* Level 5 */
    if (xvid_flags & AV_CODEC_FLAG_AC_PRED)
        x->vop_flags    |= XVID_VOP_HQACPRED;     /* Level 6 */
    if (xvid_flags & AV_CODEC_FLAG_GRAY)
        x->vop_flags    |= XVID_VOP_GREYSCALE;

    /* Decide which ME quality setting to use */
    x->me_flags = 0;
    switch (x->me_quality) {
    case 6:
    case 5:
        x->me_flags |= XVID_ME_EXTSEARCH16 |
                       XVID_ME_EXTSEARCH8;
    case 4:
    case 3:
        x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 |
                       XVID_ME_HALFPELREFINE8   |
                       XVID_ME_CHROMA_PVOP      |
                       XVID_ME_CHROMA_BVOP;
    case 2:
    case 1:
        x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 |
                       XVID_ME_HALFPELREFINE16;
#if FF_API_MOTION_EST
FF_DISABLE_DEPRECATION_WARNINGS
        break;
    default:
        switch (avctx->me_method) {
        case ME_FULL:   /* Quality 6 */
             x->me_flags |= XVID_ME_EXTSEARCH16 |
                            XVID_ME_EXTSEARCH8;
        case ME_EPZS:   /* Quality 4 */
             x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 |
                            XVID_ME_HALFPELREFINE8   |
                            XVID_ME_CHROMA_PVOP      |
                            XVID_ME_CHROMA_BVOP;
        case ME_LOG:    /* Quality 2 */
        case ME_PHODS:
        case ME_X1:
             x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 |
                            XVID_ME_HALFPELREFINE16;
        case ME_ZERO:   /* Quality 0 */
        default:
            break;
        }
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    }

    /* Decide how we should decide blocks */
    switch (avctx->mb_decision) {
    case 2:
        x->vop_flags |=  XVID_VOP_MODEDECISION_RD;
        x->me_flags  |=  XVID_ME_HALFPELREFINE8_RD    |
                         XVID_ME_QUARTERPELREFINE8_RD |
                         XVID_ME_EXTSEARCH_RD         |
                         XVID_ME_CHECKPREDICTION_RD;
    case 1:
        if (!(x->vop_flags & XVID_VOP_MODEDECISION_RD))
            x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
        x->me_flags |= XVID_ME_HALFPELREFINE16_RD |
                       XVID_ME_QUARTERPELREFINE16_RD;
    default:
        break;
    }

    /* Bring in VOL flags from ffmpeg command-line */
#if FF_API_GMC
    if (avctx->flags & CODEC_FLAG_GMC)
        x->gmc = 1;
#endif

    x->vol_flags = 0;
    if (x->gmc) {
        x->vol_flags |= XVID_VOL_GMC;
        x->me_flags  |= XVID_ME_GME_REFINE;
    }
    if (xvid_flags & AV_CODEC_FLAG_QPEL) {
        x->vol_flags |= XVID_VOL_QUARTERPEL;
        x->me_flags  |= XVID_ME_QUARTERPELREFINE16;
        if (x->vop_flags & XVID_VOP_INTER4V)
            x->me_flags |= XVID_ME_QUARTERPELREFINE8;
    }

    xvid_gbl_init.version   = XVID_VERSION;
    xvid_gbl_init.debug     = 0;
    xvid_gbl_init.cpu_flags = 0;

    /* Initialize */
    xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);

    /* Create the encoder reference */
    xvid_enc_create.version = XVID_VERSION;

    /* Store the desired frame size */
    xvid_enc_create.width  =
    x->xsize               = avctx->width;
    xvid_enc_create.height =
    x->ysize               = avctx->height;

    /* Xvid can determine the proper profile to use */
    /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */

    /* We don't use zones */
    xvid_enc_create.zones     = NULL;
    xvid_enc_create.num_zones = 0;

    xvid_enc_create.num_threads = avctx->thread_count;
#if (XVID_VERSION <= 0x010303) && (XVID_VERSION >= 0x010300)
    /* workaround for a bug in libxvidcore */
    if (avctx->height <= 16) {
        if (avctx->thread_count < 2) {
            xvid_enc_create.num_threads = 0;
        } else {
            av_log(avctx, AV_LOG_ERROR,
                   "Too small height for threads > 1.");
            return AVERROR(EINVAL);
        }
    }
#endif

    xvid_enc_create.plugins     = plugins;
    xvid_enc_create.num_plugins = 0;

    /* Initialize Buffers */
    x->twopassbuffer     = NULL;
    x->old_twopassbuffer = NULL;
    x->twopassfile       = NULL;

    if (xvid_flags & AV_CODEC_FLAG_PASS1) {
        rc2pass1.version     = XVID_VERSION;
        rc2pass1.context     = x;
        x->twopassbuffer     = av_malloc(BUFFER_SIZE);
        x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
        if (!x->twopassbuffer || !x->old_twopassbuffer) {
            av_log(avctx, AV_LOG_ERROR,
                   "Xvid: Cannot allocate 2-pass log buffers\n");
            return AVERROR(ENOMEM);
        }
        x->twopassbuffer[0]     =
        x->old_twopassbuffer[0] = 0;

        plugins[xvid_enc_create.num_plugins].func  = xvid_ff_2pass;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
        xvid_enc_create.num_plugins++;
    } else if (xvid_flags & AV_CODEC_FLAG_PASS2) {
        rc2pass2.version = XVID_VERSION;
        rc2pass2.bitrate = avctx->bit_rate;

        fd = av_tempfile("xvidff.", &x->twopassfile, 0, avctx);
        if (fd < 0) {
            av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n");
            return fd;
        }
        x->twopassfd = fd;

        if (!avctx->stats_in) {
            av_log(avctx, AV_LOG_ERROR,
                   "Xvid: No 2-pass information loaded for second pass\n");
            return AVERROR(EINVAL);
        }

        ret = write(fd, avctx->stats_in, strlen(avctx->stats_in));
        if (ret == -1)
            ret = AVERROR(errno);
        else if (strlen(avctx->stats_in) > ret) {
            av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write to 2-pass pipe\n");
            ret = AVERROR(EIO);
        }
        if (ret < 0)
            return ret;

        rc2pass2.filename                          = x->twopassfile;
        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_2pass2;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
        xvid_enc_create.num_plugins++;
    } else if (!(xvid_flags & AV_CODEC_FLAG_QSCALE)) {
        /* Single Pass Bitrate Control! */
        single.version = XVID_VERSION;
        single.bitrate = avctx->bit_rate;

        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_single;
        plugins[xvid_enc_create.num_plugins].param = &single;
        xvid_enc_create.num_plugins++;
    }

    if (avctx->lumi_masking != 0.0)
        x->lumi_aq = 1;

    /* Luminance Masking */
    if (x->lumi_aq) {
        masking_l.method                          = 0;
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;

        /* The old behavior is that when avctx->lumi_masking is specified,
         * plugins[...].param = NULL. Trying to keep the old behavior here. */
        plugins[xvid_enc_create.num_plugins].param =
            avctx->lumi_masking ? NULL : &masking_l;
        xvid_enc_create.num_plugins++;
    }

    /* Variance AQ */
    if (x->variance_aq) {
        masking_v.method                           = 1;
        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_lumimasking;
        plugins[xvid_enc_create.num_plugins].param = &masking_v;
        xvid_enc_create.num_plugins++;
    }

    if (x->lumi_aq && x->variance_aq )
        av_log(avctx, AV_LOG_INFO,
               "Both lumi_aq and variance_aq are enabled. The resulting quality"
               "will be the worse one of the two effects made by the AQ.\n");

    /* SSIM */
    if (x->ssim) {
        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_ssim;
        ssim.b_printstat                           = x->ssim == 2;
        ssim.acc                                   = x->ssim_acc;
        ssim.cpu_flags                             = xvid_gbl_init.cpu_flags;
        ssim.b_visualize                           = 0;
        plugins[xvid_enc_create.num_plugins].param = &ssim;
        xvid_enc_create.num_plugins++;
    }

    /* Frame Rate and Key Frames */
    xvid_correct_framerate(avctx);
    xvid_enc_create.fincr = avctx->time_base.num;
    xvid_enc_create.fbase = avctx->time_base.den;
    if (avctx->gop_size > 0)
        xvid_enc_create.max_key_interval = avctx->gop_size;
    else
        xvid_enc_create.max_key_interval = 240; /* Xvid's best default */

    /* Quants */
    if (xvid_flags & AV_CODEC_FLAG_QSCALE)
        x->qscale = 1;
    else
        x->qscale = 0;

    xvid_enc_create.min_quant[0] = avctx->qmin;
    xvid_enc_create.min_quant[1] = avctx->qmin;
    xvid_enc_create.min_quant[2] = avctx->qmin;
    xvid_enc_create.max_quant[0] = avctx->qmax;
    xvid_enc_create.max_quant[1] = avctx->qmax;
    xvid_enc_create.max_quant[2] = avctx->qmax;

    /* Quant Matrices */
    x->intra_matrix =
    x->inter_matrix = NULL;
    if (avctx->mpeg_quant)
        x->vol_flags |= XVID_VOL_MPEGQUANT;
    if ((avctx->intra_matrix || avctx->inter_matrix)) {
        x->vol_flags |= XVID_VOL_MPEGQUANT;

        if (avctx->intra_matrix) {
            intra           = avctx->intra_matrix;
            x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
            if (!x->intra_matrix)
                return AVERROR(ENOMEM);
        } else
            intra = NULL;
        if (avctx->inter_matrix) {
            inter           = avctx->inter_matrix;
            x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
            if (!x->inter_matrix)
                return AVERROR(ENOMEM);
        } else
            inter = NULL;

        for (i = 0; i < 64; i++) {
            if (intra)
                x->intra_matrix[i] = (unsigned char) intra[i];
            if (inter)
                x->inter_matrix[i] = (unsigned char) inter[i];
        }
    }

    /* Misc Settings */
    xvid_enc_create.frame_drop_ratio = 0;
    xvid_enc_create.global           = 0;
    if (xvid_flags & AV_CODEC_FLAG_CLOSED_GOP)
        xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;

    /* Determines which codec mode we are operating in */
    avctx->extradata      = NULL;
    avctx->extradata_size = 0;
    if (xvid_flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
        /* In this case, we are claiming to be MPEG4 */
        x->quicktime_format = 1;
        avctx->codec_id     = AV_CODEC_ID_MPEG4;
    } else {
        /* We are claiming to be Xvid */
        x->quicktime_format = 0;
        if (!avctx->codec_tag)
            avctx->codec_tag = AV_RL32("xvid");
    }

    /* Bframes */
    xvid_enc_create.max_bframes   = avctx->max_b_frames;
    xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
    xvid_enc_create.bquant_ratio  = 100 * avctx->b_quant_factor;
    if (avctx->max_b_frames > 0 && !x->quicktime_format)
        xvid_enc_create.global |= XVID_GLOBAL_PACKED;

    av_assert0(xvid_enc_create.num_plugins + (!!x->ssim) + (!!x->variance_aq) + (!!x->lumi_aq) <= FF_ARRAY_ELEMS(plugins));

    /* Create encoder context */
    xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
    if (xerr) {
        av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
        return AVERROR_EXTERNAL;
    }

    x->encoder_handle  = xvid_enc_create.handle;

    return 0;
}

static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *picture, int *got_packet)
{
    int xerr, i, ret, user_packet = !!pkt->data;
    struct xvid_context *x = avctx->priv_data;
    int mb_width  = (avctx->width  + 15) / 16;
    int mb_height = (avctx->height + 15) / 16;
    char *tmp;

    xvid_enc_frame_t xvid_enc_frame = { 0 };
    xvid_enc_stats_t xvid_enc_stats = { 0 };

    if ((ret = ff_alloc_packet2(avctx, pkt, mb_width*(int64_t)mb_height*MAX_MB_BYTES + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
        return ret;

    /* Start setting up the frame */
    xvid_enc_frame.version = XVID_VERSION;
    xvid_enc_stats.version = XVID_VERSION;

    /* Let Xvid know where to put the frame. */
    xvid_enc_frame.bitstream = pkt->data;
    xvid_enc_frame.length    = pkt->size;

    /* Initialize input image fields */
    if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) {
        av_log(avctx, AV_LOG_ERROR,
               "Xvid: Color spaces other than 420P not supported\n");
        return AVERROR(EINVAL);
    }

    xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */

    for (i = 0; i < 4; i++) {
        xvid_enc_frame.input.plane[i]  = picture->data[i];
        xvid_enc_frame.input.stride[i] = picture->linesize[i];
    }

    /* Encoder Flags */
    xvid_enc_frame.vop_flags = x->vop_flags;
    xvid_enc_frame.vol_flags = x->vol_flags;
    xvid_enc_frame.motion    = x->me_flags;
    xvid_enc_frame.type      =
        picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP :
        picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP :
        picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP :
                                                  XVID_TYPE_AUTO;

    /* Pixel aspect ratio setting */
    if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 ||
        avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) {
        av_log(avctx, AV_LOG_WARNING,
               "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n",
               avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
        av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
                   avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den, 255);
    }
    xvid_enc_frame.par        = XVID_PAR_EXT;
    xvid_enc_frame.par_width  = avctx->sample_aspect_ratio.num;
    xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den;

    /* Quant Setting */
    if (x->qscale)
        xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
    else
        xvid_enc_frame.quant = 0;

    /* Matrices */
    xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
    xvid_enc_frame.quant_inter_matrix = x->inter_matrix;

    /* Encode */
    xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
                       &xvid_enc_frame, &xvid_enc_stats);

    /* Two-pass log buffer swapping */
    avctx->stats_out = NULL;
    if (x->twopassbuffer) {
        tmp                  = x->old_twopassbuffer;
        x->old_twopassbuffer = x->twopassbuffer;
        x->twopassbuffer     = tmp;
        x->twopassbuffer[0]  = 0;
        if (x->old_twopassbuffer[0] != 0) {
            avctx->stats_out = x->old_twopassbuffer;
        }
    }

    if (xerr > 0) {
        int pict_type;

        *got_packet = 1;

        if (xvid_enc_stats.type == XVID_TYPE_PVOP)
            pict_type = AV_PICTURE_TYPE_P;
        else if (xvid_enc_stats.type == XVID_TYPE_BVOP)
            pict_type = AV_PICTURE_TYPE_B;
        else if (xvid_enc_stats.type == XVID_TYPE_SVOP)
            pict_type = AV_PICTURE_TYPE_S;
        else
            pict_type = AV_PICTURE_TYPE_I;

#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
        avctx->coded_frame->pict_type = pict_type;
        avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

        ff_side_data_set_encoder_stats(pkt, xvid_enc_stats.quant * FF_QP2LAMBDA, NULL, 0, pict_type);

        if (xvid_enc_frame.out_flags & XVID_KEYFRAME) {
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
            avctx->coded_frame->key_frame = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
            pkt->flags  |= AV_PKT_FLAG_KEY;
            if (x->quicktime_format)
                return xvid_strip_vol_header(avctx, pkt,
                                             xvid_enc_stats.hlength, xerr);
        } else {
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
            avctx->coded_frame->key_frame = 0;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
        }

        pkt->size = xerr;

        return 0;
    } else {
        if (!user_packet)
            av_free_packet(pkt);
        if (!xerr)
            return 0;
        av_log(avctx, AV_LOG_ERROR,
               "Xvid: Encoding Error Occurred: %i\n", xerr);
        return AVERROR_EXTERNAL;
    }
}

static av_cold int xvid_encode_close(AVCodecContext *avctx)
{
    struct xvid_context *x = avctx->priv_data;

    if (x->encoder_handle) {
        xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
        x->encoder_handle = NULL;
    }

    av_freep(&avctx->extradata);
    if (x->twopassbuffer) {
        av_freep(&x->twopassbuffer);
        av_freep(&x->old_twopassbuffer);
        avctx->stats_out = NULL;
    }
    if (x->twopassfd>=0) {
        unlink(x->twopassfile);
        close(x->twopassfd);
        x->twopassfd = -1;
    }
    av_freep(&x->twopassfile);
    av_freep(&x->intra_matrix);
    av_freep(&x->inter_matrix);

    return 0;
}

#define OFFSET(x) offsetof(struct xvid_context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    { "lumi_aq",     "Luminance masking AQ",            OFFSET(lumi_aq),     AV_OPT_TYPE_INT,   { .i64 = 0 },       0,       1, VE         },
    { "variance_aq", "Variance AQ",                     OFFSET(variance_aq), AV_OPT_TYPE_INT,   { .i64 = 0 },       0,       1, VE         },
    { "ssim",        "Show SSIM information to stdout", OFFSET(ssim),        AV_OPT_TYPE_INT,   { .i64 = 0 },       0,       2, VE, "ssim" },
    { "off",         NULL,                                                0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "ssim" },
    { "avg",         NULL,                                                0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "ssim" },
    { "frame",       NULL,                                                0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "ssim" },
    { "ssim_acc",    "SSIM accuracy",                   OFFSET(ssim_acc),    AV_OPT_TYPE_INT,   { .i64 = 2 },       0,       4, VE         },
    { "gmc",         "use GMC",                         OFFSET(gmc),         AV_OPT_TYPE_INT,   { .i64 = 0 },       0,       1, VE         },
    { "me_quality",  "Motion estimation quality",       OFFSET(me_quality),  AV_OPT_TYPE_INT,   { .i64 = 0 },       0,       6, VE         },
    { NULL },
};

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

AVCodec ff_libxvid_encoder = {
    .name           = "libxvid",
    .long_name      = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_MPEG4,
    .priv_data_size = sizeof(struct xvid_context),
    .init           = xvid_encode_init,
    .encode2        = xvid_encode_frame,
    .close          = xvid_encode_close,
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
    .priv_class     = &xvid_class,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                      FF_CODEC_CAP_INIT_CLEANUP,
};
