/*
 * Ut Video encoder
 * Copyright (c) 2012 Jan Ekström
 *
 * 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
 * Ut Video encoder
 */

#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "internal.h"
#include "bswapdsp.h"
#include "bytestream.h"
#include "put_bits.h"
#include "huffyuvencdsp.h"
#include "mathops.h"
#include "utvideo.h"
#include "huffman.h"

/* Compare huffentry symbols */
static int huff_cmp_sym(const void *a, const void *b)
{
    const HuffEntry *aa = a, *bb = b;
    return aa->sym - bb->sym;
}

static av_cold int utvideo_encode_close(AVCodecContext *avctx)
{
    UtvideoContext *c = avctx->priv_data;
    int i;

    av_freep(&avctx->coded_frame);
    av_freep(&c->slice_bits);
    for (i = 0; i < 4; i++)
        av_freep(&c->slice_buffer[i]);

    return 0;
}

static av_cold int utvideo_encode_init(AVCodecContext *avctx)
{
    UtvideoContext *c = avctx->priv_data;
    int i, subsampled_height;
    uint32_t original_format;

    c->avctx           = avctx;
    c->frame_info_size = 4;
    c->slice_stride    = FFALIGN(avctx->width, 32);

    switch (avctx->pix_fmt) {
    case AV_PIX_FMT_RGB24:
        c->planes        = 3;
        avctx->codec_tag = MKTAG('U', 'L', 'R', 'G');
        original_format  = UTVIDEO_RGB;
        break;
    case AV_PIX_FMT_RGBA:
        c->planes        = 4;
        avctx->codec_tag = MKTAG('U', 'L', 'R', 'A');
        original_format  = UTVIDEO_RGBA;
        break;
    case AV_PIX_FMT_YUV420P:
        if (avctx->width & 1 || avctx->height & 1) {
            av_log(avctx, AV_LOG_ERROR,
                   "4:2:0 video requires even width and height.\n");
            return AVERROR_INVALIDDATA;
        }
        c->planes        = 3;
        if (avctx->colorspace == AVCOL_SPC_BT709)
            avctx->codec_tag = MKTAG('U', 'L', 'H', '0');
        else
            avctx->codec_tag = MKTAG('U', 'L', 'Y', '0');
        original_format  = UTVIDEO_420;
        break;
    case AV_PIX_FMT_YUV422P:
        if (avctx->width & 1) {
            av_log(avctx, AV_LOG_ERROR,
                   "4:2:2 video requires even width.\n");
            return AVERROR_INVALIDDATA;
        }
        c->planes        = 3;
        if (avctx->colorspace == AVCOL_SPC_BT709)
            avctx->codec_tag = MKTAG('U', 'L', 'H', '2');
        else
            avctx->codec_tag = MKTAG('U', 'L', 'Y', '2');
        original_format  = UTVIDEO_422;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
               avctx->pix_fmt);
        return AVERROR_INVALIDDATA;
    }

    ff_bswapdsp_init(&c->bdsp);
    ff_huffyuvencdsp_init(&c->hdsp);

    /* Check the prediction method, and error out if unsupported */
    if (avctx->prediction_method < 0 || avctx->prediction_method > 4) {
        av_log(avctx, AV_LOG_WARNING,
               "Prediction method %d is not supported in Ut Video.\n",
               avctx->prediction_method);
        return AVERROR_OPTION_NOT_FOUND;
    }

    if (avctx->prediction_method == FF_PRED_PLANE) {
        av_log(avctx, AV_LOG_ERROR,
               "Plane prediction is not supported in Ut Video.\n");
        return AVERROR_OPTION_NOT_FOUND;
    }

    /* Convert from libavcodec prediction type to Ut Video's */
    c->frame_pred = ff_ut_pred_order[avctx->prediction_method];

    if (c->frame_pred == PRED_GRADIENT) {
        av_log(avctx, AV_LOG_ERROR, "Gradient prediction is not supported.\n");
        return AVERROR_OPTION_NOT_FOUND;
    }

    /*
     * Check the asked slice count for obviously invalid
     * values (> 256 or negative).
     */
    if (avctx->slices > 256 || avctx->slices < 0) {
        av_log(avctx, AV_LOG_ERROR,
               "Slice count %d is not supported in Ut Video (theoretical range is 0-256).\n",
               avctx->slices);
        return AVERROR(EINVAL);
    }

    /* Check that the slice count is not larger than the subsampled height */
    subsampled_height = avctx->height >> av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_h;
    if (avctx->slices > subsampled_height) {
        av_log(avctx, AV_LOG_ERROR,
               "Slice count %d is larger than the subsampling-applied height %d.\n",
               avctx->slices, subsampled_height);
        return AVERROR(EINVAL);
    }

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame) {
        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
        utvideo_encode_close(avctx);
        return AVERROR(ENOMEM);
    }

    /* extradata size is 4 * 32bit */
    avctx->extradata_size = 16;

    avctx->extradata = av_mallocz(avctx->extradata_size +
                                  FF_INPUT_BUFFER_PADDING_SIZE);

    if (!avctx->extradata) {
        av_log(avctx, AV_LOG_ERROR, "Could not allocate extradata.\n");
        utvideo_encode_close(avctx);
        return AVERROR(ENOMEM);
    }

    for (i = 0; i < c->planes; i++) {
        c->slice_buffer[i] = av_malloc(c->slice_stride * (avctx->height + 2) +
                                       FF_INPUT_BUFFER_PADDING_SIZE);
        if (!c->slice_buffer[i]) {
            av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 1.\n");
            utvideo_encode_close(avctx);
            return AVERROR(ENOMEM);
        }
    }

    /*
     * Set the version of the encoder.
     * Last byte is "implementation ID", which is
     * obtained from the creator of the format.
     * Libavcodec has been assigned with the ID 0xF0.
     */
    AV_WB32(avctx->extradata, MKTAG(1, 0, 0, 0xF0));

    /*
     * Set the "original format"
     * Not used for anything during decoding.
     */
    AV_WL32(avctx->extradata + 4, original_format);

    /* Write 4 as the 'frame info size' */
    AV_WL32(avctx->extradata + 8, c->frame_info_size);

    /*
     * Set how many slices are going to be used.
     * By default uses multiple slices depending on the subsampled height.
     * This enables multithreading in the official decoder.
     */
    if (!avctx->slices) {
        c->slices = subsampled_height / 120;

        if (!c->slices)
            c->slices = 1;
        else if (c->slices > 256)
            c->slices = 256;
    } else {
        c->slices = avctx->slices;
    }

    /* Set compression mode */
    c->compression = COMP_HUFF;

    /*
     * Set the encoding flags:
     * - Slice count minus 1
     * - Interlaced encoding mode flag, set to zero for now.
     * - Compression mode (none/huff)
     * And write the flags.
     */
    c->flags  = (c->slices - 1) << 24;
    c->flags |= 0 << 11; // bit field to signal interlaced encoding mode
    c->flags |= c->compression;

    AV_WL32(avctx->extradata + 12, c->flags);

    return 0;
}

static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src,
                              int step, int stride, int width, int height)
{
    int i, j;
    int k = 2 * dst_stride;
    unsigned int g;

    for (j = 0; j < height; j++) {
        if (step == 3) {
            for (i = 0; i < width * step; i += step) {
                g         = src[i + 1];
                dst[0][k] = g;
                g        += 0x80;
                dst[1][k] = src[i + 2] - g;
                dst[2][k] = src[i + 0] - g;
                k++;
            }
        } else {
            for (i = 0; i < width * step; i += step) {
                g         = src[i + 1];
                dst[0][k] = g;
                g        += 0x80;
                dst[1][k] = src[i + 2] - g;
                dst[2][k] = src[i + 0] - g;
                dst[3][k] = src[i + 3];
                k++;
            }
        }
        k += dst_stride - width;
        src += stride;
    }
}

/* Write data to a plane with left prediction */
static void left_predict(uint8_t *src, uint8_t *dst, int stride,
                         int width, int height)
{
    int i, j;
    uint8_t prev;

    prev = 0x80; /* Set the initial value */
    for (j = 0; j < height; j++) {
        for (i = 0; i < width; i++) {
            *dst++ = src[i] - prev;
            prev   = src[i];
        }
        src += stride;
    }
}

/* Write data to a plane with median prediction */
static void median_predict(UtvideoContext *c, uint8_t *src, uint8_t *dst, int stride,
                           int width, int height)
{
    int i, j;
    int A, B;
    uint8_t prev;

    /* First line uses left neighbour prediction */
    prev = 0x80; /* Set the initial value */
    for (i = 0; i < width; i++) {
        *dst++ = src[i] - prev;
        prev   = src[i];
    }

    if (height == 1)
        return;

    src += stride;

    /*
     * Second line uses top prediction for the first sample,
     * and median for the rest.
     */
    A = B = 0;

    /* Rest of the coded part uses median prediction */
    for (j = 1; j < height; j++) {
        c->hdsp.sub_hfyu_median_pred(dst, src - stride, src, width, &A, &B);
        dst += width;
        src += stride;
    }
}

/* Count the usage of values in a plane */
static void count_usage(uint8_t *src, int width,
                        int height, uint64_t *counts)
{
    int i, j;

    for (j = 0; j < height; j++) {
        for (i = 0; i < width; i++) {
            counts[src[i]]++;
        }
        src += width;
    }
}

/* Calculate the actual huffman codes from the code lengths */
static void calculate_codes(HuffEntry *he)
{
    int last, i;
    uint32_t code;

    qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len);

    last = 255;
    while (he[last].len == 255 && last)
        last--;

    code = 1;
    for (i = last; i >= 0; i--) {
        he[i].code  = code >> (32 - he[i].len);
        code       += 0x80000000u >> (he[i].len - 1);
    }

    qsort(he, 256, sizeof(*he), huff_cmp_sym);
}

/* Write huffman bit codes to a memory block */
static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size,
                            int width, int height, HuffEntry *he)
{
    PutBitContext pb;
    int i, j;
    int count;

    init_put_bits(&pb, dst, dst_size);

    /* Write the codes */
    for (j = 0; j < height; j++) {
        for (i = 0; i < width; i++)
            put_bits(&pb, he[src[i]].len, he[src[i]].code);

        src += width;
    }

    /* Pad output to a 32bit boundary */
    count = put_bits_count(&pb) & 0x1F;

    if (count)
        put_bits(&pb, 32 - count, 0);

    /* Get the amount of bits written */
    count = put_bits_count(&pb);

    /* Flush the rest with zeroes */
    flush_put_bits(&pb);

    return count;
}

static int encode_plane(AVCodecContext *avctx, uint8_t *src,
                        uint8_t *dst, int stride, int plane_no,
                        int width, int height, PutByteContext *pb)
{
    UtvideoContext *c        = avctx->priv_data;
    uint8_t  lengths[256];
    uint64_t counts[256]     = { 0 };

    HuffEntry he[256];

    uint32_t offset = 0, slice_len = 0;
    const int cmask = ~(!plane_no && avctx->pix_fmt == AV_PIX_FMT_YUV420P);
    int      i, sstart, send = 0;
    int      symbol;
    int      ret;

    /* Do prediction / make planes */
    switch (c->frame_pred) {
    case PRED_NONE:
        for (i = 0; i < c->slices; i++) {
            sstart = send;
            send   = height * (i + 1) / c->slices & cmask;
            av_image_copy_plane(dst + sstart * width, width,
                                src + sstart * stride, stride,
                                width, send - sstart);
        }
        break;
    case PRED_LEFT:
        for (i = 0; i < c->slices; i++) {
            sstart = send;
            send   = height * (i + 1) / c->slices & cmask;
            left_predict(src + sstart * stride, dst + sstart * width,
                         stride, width, send - sstart);
        }
        break;
    case PRED_MEDIAN:
        for (i = 0; i < c->slices; i++) {
            sstart = send;
            send   = height * (i + 1) / c->slices & cmask;
            median_predict(c, src + sstart * stride, dst + sstart * width,
                           stride, width, send - sstart);
        }
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown prediction mode: %d\n",
               c->frame_pred);
        return AVERROR_OPTION_NOT_FOUND;
    }

    /* Count the usage of values */
    count_usage(dst, width, height, counts);

    /* Check for a special case where only one symbol was used */
    for (symbol = 0; symbol < 256; symbol++) {
        /* If non-zero count is found, see if it matches width * height */
        if (counts[symbol]) {
            /* Special case if only one symbol was used */
            if (counts[symbol] == width * (int64_t)height) {
                /*
                 * Write a zero for the single symbol
                 * used in the plane, else 0xFF.
                 */
                for (i = 0; i < 256; i++) {
                    if (i == symbol)
                        bytestream2_put_byte(pb, 0);
                    else
                        bytestream2_put_byte(pb, 0xFF);
                }

                /* Write zeroes for lengths */
                for (i = 0; i < c->slices; i++)
                    bytestream2_put_le32(pb, 0);

                /* And that's all for that plane folks */
                return 0;
            }
            break;
        }
    }

    /* Calculate huffman lengths */
    if ((ret = ff_huff_gen_len_table(lengths, counts, 256, 1)) < 0)
        return ret;

    /*
     * Write the plane's header into the output packet:
     * - huffman code lengths (256 bytes)
     * - slice end offsets (gotten from the slice lengths)
     */
    for (i = 0; i < 256; i++) {
        bytestream2_put_byte(pb, lengths[i]);

        he[i].len = lengths[i];
        he[i].sym = i;
    }

    /* Calculate the huffman codes themselves */
    calculate_codes(he);

    send = 0;
    for (i = 0; i < c->slices; i++) {
        sstart  = send;
        send    = height * (i + 1) / c->slices & cmask;

        /*
         * Write the huffman codes to a buffer,
         * get the offset in bits and convert to bytes.
         */
        offset += write_huff_codes(dst + sstart * width, c->slice_bits,
                                   width * height + 4, width,
                                   send - sstart, he) >> 3;

        slice_len = offset - slice_len;

        /* Byteswap the written huffman codes */
        c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
                          (uint32_t *) c->slice_bits,
                          slice_len >> 2);

        /* Write the offset to the stream */
        bytestream2_put_le32(pb, offset);

        /* Seek to the data part of the packet */
        bytestream2_seek_p(pb, 4 * (c->slices - i - 1) +
                           offset - slice_len, SEEK_CUR);

        /* Write the slices' data into the output packet */
        bytestream2_put_buffer(pb, c->slice_bits, slice_len);

        /* Seek back to the slice offsets */
        bytestream2_seek_p(pb, -4 * (c->slices - i - 1) - offset,
                           SEEK_CUR);

        slice_len = offset;
    }

    /* And at the end seek to the end of written slice(s) */
    bytestream2_seek_p(pb, offset, SEEK_CUR);

    return 0;
}

static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                const AVFrame *pic, int *got_packet)
{
    UtvideoContext *c = avctx->priv_data;
    PutByteContext pb;

    uint32_t frame_info;

    uint8_t *dst;

    int width = avctx->width, height = avctx->height;
    int i, ret = 0;

    /* Allocate a new packet if needed, and set it to the pointer dst */
    ret = ff_alloc_packet2(avctx, pkt, (256 + 4 * c->slices + width * height) *
                           c->planes + 4);

    if (ret < 0)
        return ret;

    dst = pkt->data;

    bytestream2_init_writer(&pb, dst, pkt->size);

    av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height + 4);

    if (!c->slice_bits) {
        av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n");
        return AVERROR(ENOMEM);
    }

    /* In case of RGB, mangle the planes to Ut Video's format */
    if (avctx->pix_fmt == AV_PIX_FMT_RGBA || avctx->pix_fmt == AV_PIX_FMT_RGB24)
        mangle_rgb_planes(c->slice_buffer, c->slice_stride, pic->data[0],
                          c->planes, pic->linesize[0], width, height);

    /* Deal with the planes */
    switch (avctx->pix_fmt) {
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
        for (i = 0; i < c->planes; i++) {
            ret = encode_plane(avctx, c->slice_buffer[i] + 2 * c->slice_stride,
                               c->slice_buffer[i], c->slice_stride, i,
                               width, height, &pb);

            if (ret) {
                av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
                return ret;
            }
        }
        break;
    case AV_PIX_FMT_YUV422P:
        for (i = 0; i < c->planes; i++) {
            ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
                               pic->linesize[i], i, width >> !!i, height, &pb);

            if (ret) {
                av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
                return ret;
            }
        }
        break;
    case AV_PIX_FMT_YUV420P:
        for (i = 0; i < c->planes; i++) {
            ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
                               pic->linesize[i], i, width >> !!i, height >> !!i,
                               &pb);

            if (ret) {
                av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
                return ret;
            }
        }
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
               avctx->pix_fmt);
        return AVERROR_INVALIDDATA;
    }

    /*
     * Write frame information (LE 32bit unsigned)
     * into the output packet.
     * Contains the prediction method.
     */
    frame_info = c->frame_pred << 8;
    bytestream2_put_le32(&pb, frame_info);

    /*
     * At least currently Ut Video is IDR only.
     * Set flags accordingly.
     */
    avctx->coded_frame->key_frame = 1;
    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    pkt->size   = bytestream2_tell_p(&pb);
    pkt->flags |= AV_PKT_FLAG_KEY;

    /* Packet should be done */
    *got_packet = 1;

    return 0;
}

AVCodec ff_utvideo_encoder = {
    .name           = "utvideo",
    .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_UTVIDEO,
    .priv_data_size = sizeof(UtvideoContext),
    .init           = utvideo_encode_init,
    .encode2        = utvideo_encode_frame,
    .close          = utvideo_encode_close,
    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
    .pix_fmts       = (const enum AVPixelFormat[]) {
                          AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV422P,
                          AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
                      },
};
