/*
 * Flash Screen Video Version 2 encoder
 * Copyright (C) 2009 Joshua Warner
 *
 * 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
 * Flash Screen Video Version 2 encoder
 * @author Joshua Warner
 */

/* Differences from version 1 stream:
 * NOTE: Currently, the only player that supports version 2 streams is Adobe Flash Player itself.
 * * Supports sending only a range of scanlines in a block,
 *   indicating a difference from the corresponding block in the last keyframe.
 * * Supports initializing the zlib dictionary with data from the corresponding
 *   block in the last keyframe, to improve compression.
 * * Supports a hybrid 15-bit rgb / 7-bit palette color space.
 */

/* TODO:
 * Don't keep Block structures for both current frame and keyframe.
 * Make better heuristics for deciding stream parameters (optimum_* functions).  Currently these return constants.
 * Figure out how to encode palette information in the stream, choose an optimum palette at each keyframe.
 * Figure out how the zlibPrimeCompressCurrent flag works, implement support.
 * Find other sample files (that weren't generated here), develop a decoder.
 */

#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>

#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "put_bits.h"
#include "bytestream.h"

#define HAS_IFRAME_IMAGE 0x02
#define HAS_PALLET_INFO 0x01

#define COLORSPACE_BGR 0x00
#define COLORSPACE_15_7 0x10
#define HAS_DIFF_BLOCKS 0x04
#define ZLIB_PRIME_COMPRESS_CURRENT 0x02
#define ZLIB_PRIME_COMPRESS_PREVIOUS 0x01

// Disables experimental "smart" parameter-choosing code, as well as the statistics that it depends on.
// At the moment, the "smart" code is a great example of how the parameters *shouldn't* be chosen.
#define FLASHSV2_DUMB

typedef struct Block {
    uint8_t *enc;
    uint8_t *sl_begin, *sl_end;
    int enc_size;
    uint8_t *data;
    unsigned long data_size;

    uint8_t start, len;
    uint8_t dirty;
    uint8_t col, row, width, height;
    uint8_t flags;
} Block;

typedef struct Palette {
    unsigned colors[128];
    uint8_t index[1 << 15];
} Palette;

typedef struct FlashSV2Context {
    AVCodecContext *avctx;
    uint8_t *current_frame;
    uint8_t *key_frame;
    AVFrame frame;
    uint8_t *encbuffer;
    uint8_t *keybuffer;
    uint8_t *databuffer;

    Block *frame_blocks;
    Block *key_blocks;
    int frame_size;
    int blocks_size;

    int use15_7, dist, comp;

    int rows, cols;

    int last_key_frame;

    int image_width, image_height;
    int block_width, block_height;
    uint8_t flags;
    uint8_t use_custom_palette;
    uint8_t palette_type;       ///< 0=>default, 1=>custom - changed when palette regenerated.
    Palette palette;
#ifndef FLASHSV2_DUMB
    double tot_blocks;          ///< blocks encoded since last keyframe
    double diff_blocks;         ///< blocks that were different since last keyframe
    double tot_lines;           ///< total scanlines in image since last keyframe
    double diff_lines;          ///< scanlines that were different since last keyframe
    double raw_size;            ///< size of raw frames since last keyframe
    double comp_size;           ///< size of compressed data since last keyframe
    double uncomp_size;         ///< size of uncompressed data since last keyframe

    double total_bits;          ///< total bits written to stream so far
#endif
} FlashSV2Context;

static av_cold void cleanup(FlashSV2Context * s)
{
    av_freep(&s->encbuffer);
    av_freep(&s->keybuffer);
    av_freep(&s->databuffer);
    av_freep(&s->current_frame);
    av_freep(&s->key_frame);

    av_freep(&s->frame_blocks);
    av_freep(&s->key_blocks);
}

static void init_blocks(FlashSV2Context * s, Block * blocks,
                        uint8_t * encbuf, uint8_t * databuf)
{
    int row, col;
    Block *b;
    for (col = 0; col < s->cols; col++) {
        for (row = 0; row < s->rows; row++) {
            b = blocks + (col + row * s->cols);
            b->width = (col < s->cols - 1) ?
                s->block_width :
                s->image_width - col * s->block_width;

            b->height = (row < s->rows - 1) ?
                s->block_height :
                s->image_height - row * s->block_height;

            b->row   = row;
            b->col   = col;
            b->enc   = encbuf;
            b->data  = databuf;
            encbuf  += b->width * b->height * 3;
            databuf += !databuf ? 0 : b->width * b->height * 6;
        }
    }
}

static void reset_stats(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
    s->diff_blocks = 0.1;
    s->tot_blocks = 1;
    s->diff_lines = 0.1;
    s->tot_lines = 1;
    s->raw_size = s->comp_size = s->uncomp_size = 10;
#endif
}

static av_cold int flashsv2_encode_init(AVCodecContext * avctx)
{
    FlashSV2Context *s = avctx->priv_data;

    s->avctx = avctx;

    s->comp = avctx->compression_level;
    if (s->comp == -1)
        s->comp = 9;
    if (s->comp < 0 || s->comp > 9) {
        av_log(avctx, AV_LOG_ERROR,
               "Compression level should be 0-9, not %d\n", s->comp);
        return -1;
    }


    if ((avctx->width > 4095) || (avctx->height > 4095)) {
        av_log(avctx, AV_LOG_ERROR,
               "Input dimensions too large, input must be max 4096x4096 !\n");
        return -1;
    }

    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)
        return -1;


    s->last_key_frame = 0;

    s->image_width  = avctx->width;
    s->image_height = avctx->height;

    s->block_width  = (s->image_width /  12) & ~15;
    s->block_height = (s->image_height / 12) & ~15;

    s->rows = (s->image_height + s->block_height - 1) / s->block_height;
    s->cols = (s->image_width +  s->block_width -  1) / s->block_width;

    s->frame_size  = s->image_width * s->image_height * 3;
    s->blocks_size = s->rows * s->cols * sizeof(Block);

    s->encbuffer     = av_mallocz(s->frame_size);
    s->keybuffer     = av_mallocz(s->frame_size);
    s->databuffer    = av_mallocz(s->frame_size * 6);
    s->current_frame = av_mallocz(s->frame_size);
    s->key_frame     = av_mallocz(s->frame_size);
    s->frame_blocks  = av_mallocz(s->blocks_size);
    s->key_blocks    = av_mallocz(s->blocks_size);

    init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
    init_blocks(s, s->key_blocks,   s->keybuffer, 0);
    reset_stats(s);
#ifndef FLASHSV2_DUMB
    s->total_bits = 1;
#endif

    s->use_custom_palette =  0;
    s->palette_type       = -1;        // so that the palette will be generated in reconfigure_at_keyframe

    if (!s->encbuffer || !s->keybuffer || !s->databuffer
        || !s->current_frame || !s->key_frame || !s->key_blocks
        || !s->frame_blocks) {
        av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
        cleanup(s);
        return -1;
    }

    return 0;
}

static int new_key_frame(FlashSV2Context * s)
{
    int i;
    memcpy(s->key_blocks, s->frame_blocks, s->blocks_size);
    memcpy(s->key_frame, s->current_frame, s->frame_size);

    for (i = 0; i < s->rows * s->cols; i++) {
        s->key_blocks[i].enc += (s->keybuffer - s->encbuffer);
        s->key_blocks[i].sl_begin = 0;
        s->key_blocks[i].sl_end   = 0;
        s->key_blocks[i].data     = 0;
    }
    FFSWAP(uint8_t * , s->keybuffer, s->encbuffer);

    return 0;
}

static int write_palette(FlashSV2Context * s, uint8_t * buf, int buf_size)
{
    //this isn't implemented yet!  Default palette only!
    return -1;
}

static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size)
{
    PutBitContext pb;
    int buf_pos, len;

    if (buf_size < 5)
        return -1;

    init_put_bits(&pb, buf, buf_size);

    put_bits(&pb, 4, (s->block_width  >> 4) - 1);
    put_bits(&pb, 12, s->image_width);
    put_bits(&pb, 4, (s->block_height >> 4) - 1);
    put_bits(&pb, 12, s->image_height);

    flush_put_bits(&pb);
    buf_pos = 4;

    buf[buf_pos++] = s->flags;

    if (s->flags & HAS_PALLET_INFO) {
        len = write_palette(s, buf + buf_pos, buf_size - buf_pos);
        if (len < 0)
            return -1;
        buf_pos += len;
    }

    return buf_pos;
}

static int write_block(Block * b, uint8_t * buf, int buf_size)
{
    int buf_pos = 0;
    unsigned block_size = b->data_size;

    if (b->flags & HAS_DIFF_BLOCKS)
        block_size += 2;
    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT)
        block_size += 2;
    if (block_size > 0)
        block_size += 1;
    if (buf_size < block_size + 2)
        return -1;

    buf[buf_pos++] = block_size >> 8;
    buf[buf_pos++] = block_size;

    if (block_size == 0)
        return buf_pos;

    buf[buf_pos++] = b->flags;

    if (b->flags & HAS_DIFF_BLOCKS) {
        buf[buf_pos++] = (b->start);
        buf[buf_pos++] = (b->len);
    }

    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) {
        //This feature of the format is poorly understood, and as of now, unused.
        buf[buf_pos++] = (b->col);
        buf[buf_pos++] = (b->row);
    }

    memcpy(buf + buf_pos, b->data, b->data_size);

    buf_pos += b->data_size;

    return buf_pos;
}

static int encode_zlib(Block * b, uint8_t * buf, unsigned long *buf_size, int comp)
{
    int res = compress2(buf, buf_size, b->sl_begin, b->sl_end - b->sl_begin, comp);
    return res == Z_OK ? 0 : -1;
}

static int encode_zlibprime(Block * b, Block * prime, uint8_t * buf,
                            int *buf_size, int comp)
{
    z_stream s;
    int res;
    s.zalloc = NULL;
    s.zfree  = NULL;
    s.opaque = NULL;
    res = deflateInit(&s, comp);
    if (res < 0)
        return -1;

    s.next_in  = prime->enc;
    s.avail_in = prime->enc_size;
    while (s.avail_in > 0) {
        s.next_out  = buf;
        s.avail_out = *buf_size;
        res = deflate(&s, Z_SYNC_FLUSH);
        if (res < 0)
            return -1;
    }

    s.next_in   = b->sl_begin;
    s.avail_in  = b->sl_end - b->sl_begin;
    s.next_out  = buf;
    s.avail_out = *buf_size;
    res = deflate(&s, Z_FINISH);
    deflateEnd(&s);
    *buf_size -= s.avail_out;
    if (res != Z_STREAM_END)
        return -1;
    return 0;
}

static int encode_bgr(Block * b, const uint8_t * src, int stride)
{
    int i;
    uint8_t *ptr = b->enc;
    for (i = 0; i < b->start; i++)
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
    b->sl_begin = ptr + i * b->width * 3;
    for (; i < b->start + b->len; i++)
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
    b->sl_end = ptr + i * b->width * 3;
    for (; i < b->height; i++)
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
    b->enc_size = ptr + i * b->width * 3 - b->enc;
    return b->enc_size;
}

static inline unsigned pixel_color15(const uint8_t * src)
{
    return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7);
}

static inline unsigned int chroma_diff(unsigned int c1, unsigned int c2)
{
    unsigned int t1 = (c1 & 0x000000ff) + ((c1 & 0x0000ff00) >> 8) + ((c1 & 0x00ff0000) >> 16);
    unsigned int t2 = (c2 & 0x000000ff) + ((c2 & 0x0000ff00) >> 8) + ((c2 & 0x00ff0000) >> 16);

    return abs(t1 - t2) + abs((c1 & 0x000000ff) - (c2 & 0x000000ff)) +
        abs(((c1 & 0x0000ff00) >> 8) - ((c2 & 0x0000ff00) >> 8)) +
        abs(((c1 & 0x00ff0000) >> 16) - ((c2 & 0x00ff0000) >> 16));
}

static inline int pixel_color7_fast(Palette * palette, unsigned c15)
{
    return palette->index[c15];
}

static int pixel_color7_slow(Palette * palette, unsigned color)
{
    int i, min = 0x7fffffff;
    int minc = -1;
    for (i = 0; i < 128; i++) {
        int c1 = palette->colors[i];
        int diff = chroma_diff(c1, color);
        if (diff < min) {
            min = diff;
            minc = i;
        }
    }
    return minc;
}

static inline unsigned pixel_bgr(const uint8_t * src)
{
    return (src[0]) | (src[1] << 8) | (src[2] << 16);
}

static int write_pixel_15_7(Palette * palette, uint8_t * dest, const uint8_t * src,
                            int dist)
{
    unsigned c15 = pixel_color15(src);
    unsigned color = pixel_bgr(src);
    int d15 = chroma_diff(color, color & 0x00f8f8f8);
    int c7 = pixel_color7_fast(palette, c15);
    int d7 = chroma_diff(color, palette->colors[c7]);
    if (dist + d15 >= d7) {
        dest[0] = c7;
        return 1;
    } else {
        dest[0] = 0x80 | (c15 >> 8);
        dest[1] = c15 & 0xff;
        return 2;
    }
}

static int update_palette_index(Palette * palette)
{
    int r, g, b;
    unsigned int bgr, c15, index;
    for (r = 4; r < 256; r += 8) {
        for (g = 4; g < 256; g += 8) {
            for (b = 4; b < 256; b += 8) {
                bgr = b | (g << 8) | (r << 16);
                c15 = (b >> 3) | ((g & 0xf8) << 2) | ((r & 0xf8) << 7);
                index = pixel_color7_slow(palette, bgr);

                palette->index[c15] = index;
            }
        }
    }
    return 0;
}

static const unsigned int default_screen_video_v2_palette[128] = {
    0x00000000, 0x00333333, 0x00666666, 0x00999999, 0x00CCCCCC, 0x00FFFFFF,
    0x00330000, 0x00660000, 0x00990000, 0x00CC0000, 0x00FF0000, 0x00003300,
    0x00006600, 0x00009900, 0x0000CC00, 0x0000FF00, 0x00000033, 0x00000066,
    0x00000099, 0x000000CC, 0x000000FF, 0x00333300, 0x00666600, 0x00999900,
    0x00CCCC00, 0x00FFFF00, 0x00003333, 0x00006666, 0x00009999, 0x0000CCCC,
    0x0000FFFF, 0x00330033, 0x00660066, 0x00990099, 0x00CC00CC, 0x00FF00FF,
    0x00FFFF33, 0x00FFFF66, 0x00FFFF99, 0x00FFFFCC, 0x00FF33FF, 0x00FF66FF,
    0x00FF99FF, 0x00FFCCFF, 0x0033FFFF, 0x0066FFFF, 0x0099FFFF, 0x00CCFFFF,
    0x00CCCC33, 0x00CCCC66, 0x00CCCC99, 0x00CCCCFF, 0x00CC33CC, 0x00CC66CC,
    0x00CC99CC, 0x00CCFFCC, 0x0033CCCC, 0x0066CCCC, 0x0099CCCC, 0x00FFCCCC,
    0x00999933, 0x00999966, 0x009999CC, 0x009999FF, 0x00993399, 0x00996699,
    0x0099CC99, 0x0099FF99, 0x00339999, 0x00669999, 0x00CC9999, 0x00FF9999,
    0x00666633, 0x00666699, 0x006666CC, 0x006666FF, 0x00663366, 0x00669966,
    0x0066CC66, 0x0066FF66, 0x00336666, 0x00996666, 0x00CC6666, 0x00FF6666,
    0x00333366, 0x00333399, 0x003333CC, 0x003333FF, 0x00336633, 0x00339933,
    0x0033CC33, 0x0033FF33, 0x00663333, 0x00993333, 0x00CC3333, 0x00FF3333,
    0x00003366, 0x00336600, 0x00660033, 0x00006633, 0x00330066, 0x00663300,
    0x00336699, 0x00669933, 0x00993366, 0x00339966, 0x00663399, 0x00996633,
    0x006699CC, 0x0099CC66, 0x00CC6699, 0x0066CC99, 0x009966CC, 0x00CC9966,
    0x0099CCFF, 0x00CCFF99, 0x00FF99CC, 0x0099FFCC, 0x00CC99FF, 0x00FFCC99,
    0x00111111, 0x00222222, 0x00444444, 0x00555555, 0x00AAAAAA, 0x00BBBBBB,
    0x00DDDDDD, 0x00EEEEEE
};

static int generate_default_palette(Palette * palette)
{
    memcpy(palette->colors, default_screen_video_v2_palette,
           sizeof(default_screen_video_v2_palette));

    return update_palette_index(palette);
}

static int generate_optimum_palette(Palette * palette, const uint8_t * image,
                                   int width, int height, int stride)
{
    //this isn't implemented yet!  Default palette only!
    return -1;
}

static inline int encode_15_7_sl(Palette * palette, uint8_t * dest,
                                 const uint8_t * src, int width, int dist)
{
    int len = 0, x;
    for (x = 0; x < width; x++) {
        len += write_pixel_15_7(palette, dest + len, src + 3 * x, dist);
    }
    return len;
}

static int encode_15_7(Palette * palette, Block * b, const uint8_t * src,
                       int stride, int dist)
{
    int i;
    uint8_t *ptr = b->enc;
    for (i = 0; i < b->start; i++)
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
    b->sl_begin = ptr;
    for (; i < b->start + b->len; i++)
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
    b->sl_end = ptr;
    for (; i < b->height; i++)
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
    b->enc_size = ptr - b->enc;
    return b->enc_size;
}

static int encode_block(Palette * palette, Block * b, Block * prev,
                        const uint8_t * src, int stride, int comp, int dist,
                        int keyframe)
{
    unsigned buf_size = b->width * b->height * 6;
    uint8_t buf[buf_size];
    int res;
    if (b->flags & COLORSPACE_15_7) {
        encode_15_7(palette, b, src, stride, dist);
    } else {
        encode_bgr(b, src, stride);
    }

    if (b->len > 0) {
        b->data_size = buf_size;
        res = encode_zlib(b, b->data, &b->data_size, comp);
        if (res)
            return res;

        if (!keyframe) {
            res = encode_zlibprime(b, prev, buf, &buf_size, comp);
            if (res)
                return res;

            if (buf_size < b->data_size) {
                b->data_size = buf_size;
                memcpy(b->data, buf, buf_size);
                b->flags |= ZLIB_PRIME_COMPRESS_PREVIOUS;
            }
        }
    } else {
        b->data_size = 0;
    }
    return 0;
}

static int compare_sl(FlashSV2Context * s, Block * b, const uint8_t * src,
                      uint8_t * frame, uint8_t * key, int y, int keyframe)
{
    if (memcmp(src, frame, b->width * 3) != 0) {
        b->dirty = 1;
        memcpy(frame, src, b->width * 3);
#ifndef FLASHSV2_DUMB
        s->diff_lines++;
#endif
    }
    if (memcmp(src, key, b->width * 3) != 0) {
        if (b->len == 0)
            b->start = y;
        b->len = y + 1 - b->start;
    }
    return 0;
}

static int mark_all_blocks(FlashSV2Context * s, const uint8_t * src, int stride,
                           int keyframe)
{
    int sl, rsl, col, pos, possl;
    Block *b;
    for (sl = s->image_height - 1; sl >= 0; sl--) {
        for (col = 0; col < s->cols; col++) {
            rsl = s->image_height - sl - 1;
            b = s->frame_blocks + col + rsl / s->block_height * s->cols;
            possl = stride * sl + col * s->block_width * 3;
            pos = s->image_width * rsl * 3 + col * s->block_width * 3;
            compare_sl(s, b, src + possl, s->current_frame + pos,
                       s->key_frame + pos, rsl % s->block_height, keyframe);
        }
    }
#ifndef FLASHSV2_DUMB
    s->tot_lines += s->image_height * s->cols;
#endif
    return 0;
}

static int encode_all_blocks(FlashSV2Context * s, int keyframe)
{
    int row, col, res;
    uint8_t *data;
    Block *b, *prev;
    for (row = 0; row < s->rows; row++) {
        for (col = 0; col < s->cols; col++) {
            b = s->frame_blocks + (row * s->cols + col);
            prev = s->key_blocks + (row * s->cols + col);
            if (keyframe) {
                b->start = 0;
                b->len = b->height;
                b->flags = s->use15_7 ? COLORSPACE_15_7 : 0;
            } else if (!b->dirty) {
                b->start = 0;
                b->len = 0;
                b->data_size = 0;
                b->flags = s->use15_7 ? COLORSPACE_15_7 : 0;
                continue;
            } else {
                b->flags = s->use15_7 ? COLORSPACE_15_7 | HAS_DIFF_BLOCKS : HAS_DIFF_BLOCKS;
            }
            data = s->current_frame + s->image_width * 3 * s->block_height * row + s->block_width * col * 3;
            res = encode_block(&s->palette, b, prev, data, s->image_width * 3, s->comp, s->dist, keyframe);
#ifndef FLASHSV2_DUMB
            if (b->dirty)
                s->diff_blocks++;
            s->comp_size += b->data_size;
            s->uncomp_size += b->enc_size;
#endif
            if (res)
                return res;
        }
    }
#ifndef FLASHSV2_DUMB
    s->raw_size += s->image_width * s->image_height * 3;
    s->tot_blocks += s->rows * s->cols;
#endif
    return 0;
}

static int write_all_blocks(FlashSV2Context * s, uint8_t * buf,
                            int buf_size)
{
    int row, col, buf_pos = 0, len;
    Block *b;
    for (row = 0; row < s->rows; row++) {
        for (col = 0; col < s->cols; col++) {
            b = s->frame_blocks + row * s->cols + col;
            len = write_block(b, buf + buf_pos, buf_size - buf_pos);
            b->start = b->len = b->dirty = 0;
            if (len < 0)
                return len;
            buf_pos += len;
        }
    }
    return buf_pos;
}

static int write_bitstream(FlashSV2Context * s, const uint8_t * src, int stride,
                           uint8_t * buf, int buf_size, int keyframe)
{
    int buf_pos, res;

    res = mark_all_blocks(s, src, stride, keyframe);
    if (res)
        return res;
    res = encode_all_blocks(s, keyframe);
    if (res)
        return res;

    res = write_header(s, buf, buf_size);
    if (res < 0) {
        return res;
    } else {
        buf_pos = res;
    }
    res = write_all_blocks(s, buf + buf_pos, buf_size - buf_pos);
    if (res < 0)
        return res;
    buf_pos += res;
#ifndef FLASHSV2_DUMB
    s->total_bits += ((double) buf_pos) * 8.0;
#endif

    return buf_pos;
}

static void recommend_keyframe(FlashSV2Context * s, int *keyframe)
{
#ifndef FLASHSV2_DUMB
    double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio;
    if (s->avctx->gop_size > 0) {
        block_ratio = s->diff_blocks / s->tot_blocks;
        line_ratio = s->diff_lines / s->tot_lines;
        enc_ratio = s->uncomp_size / s->raw_size;
        comp_ratio = s->comp_size / s->uncomp_size;
        data_ratio = s->comp_size / s->raw_size;

        if ((block_ratio >= 0.5 && line_ratio / block_ratio <= 0.5) || line_ratio >= 0.95) {
            *keyframe = 1;
            return;
        }
    }
#else
    return;
#endif
}

static const double block_size_fraction = 1.0 / 300;
static int optimum_block_width(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
    double width = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_width;
    int pwidth = ((int) width);
    return FFCLIP(pwidth & ~15, 256, 16);
#else
    return 64;
#endif
}

static int optimum_block_height(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
    double height = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_height;
    int pheight = ((int) height);
    return FFCLIP(pheight & ~15, 256, 16);
#else
    return 64;
#endif
}

static const double use15_7_threshold = 8192;

static int optimum_use15_7(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
    double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) /
        ((double) s->avctx->time_base.num) * s->avctx->frame_number;
    if (ideal + use15_7_threshold < s->total_bits) {
        return 1;
    } else {
        return 0;
    }
#else
    return s->avctx->global_quality == 0;
#endif
}

static const double color15_7_factor = 100;

static int optimum_dist(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
    double ideal =
        s->avctx->bit_rate * s->avctx->time_base.den *
        s->avctx->ticks_per_frame;
    int dist = pow((s->total_bits / ideal) * color15_7_factor, 3);
    av_log(s->avctx, AV_LOG_DEBUG, "dist: %d\n", dist);
    return dist;
#else
    return 15;
#endif
}


static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image,
                                   int stride)
{
    int update_palette = 0;
    int res;
    s->block_width = optimum_block_width(s);
    s->block_height = optimum_block_height(s);

    s->rows = (s->image_height + s->block_height - 1) / s->block_height;
    s->cols = (s->image_width +  s->block_width -  1) / s->block_width;

    if (s->rows * s->cols != s->blocks_size / sizeof(Block)) {
        if (s->rows * s->cols > s->blocks_size / sizeof(Block)) {
            s->frame_blocks = av_realloc(s->frame_blocks, s->rows * s->cols * sizeof(Block));
            s->key_blocks = av_realloc(s->key_blocks, s->cols * s->rows * sizeof(Block));
            if (!s->frame_blocks || !s->key_blocks) {
                av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
                return -1;
            }
            s->blocks_size = s->rows * s->cols * sizeof(Block);
        }
        init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
        init_blocks(s, s->key_blocks, s->keybuffer, 0);

    }

    s->use15_7 = optimum_use15_7(s);
    if (s->use15_7) {
        if ((s->use_custom_palette && s->palette_type != 1) || update_palette) {
            res = generate_optimum_palette(&s->palette, image, s->image_width, s->image_height, stride);
            if (res)
                return res;
            s->palette_type = 1;
            av_log(s->avctx, AV_LOG_DEBUG, "Generated optimum palette\n");
        } else if (!s->use_custom_palette && s->palette_type != 0) {
            res = generate_default_palette(&s->palette);
            if (res)
                return res;
            s->palette_type = 0;
            av_log(s->avctx, AV_LOG_DEBUG, "Generated default palette\n");
        }
    }


    reset_stats(s);

    return 0;
}

static int flashsv2_encode_frame(AVCodecContext * avctx, uint8_t * buf,
                                 int buf_size, void *data)
{
    FlashSV2Context *const s = avctx->priv_data;
    AVFrame *pict = data;
    AVFrame *const p = &s->frame;
    int res;
    int keyframe = 0;

    *p = *pict;

    /* First frame needs to be a keyframe */
    if (avctx->frame_number == 0)
        keyframe = 1;

    /* Check the placement of keyframes */
    if (avctx->gop_size > 0) {
        if (avctx->frame_number >= s->last_key_frame + avctx->gop_size)
            keyframe = 1;
    }

    if (buf_size < s->frame_size) {
        //Conservative upper bound check for compressed data
        av_log(avctx, AV_LOG_ERROR, "buf_size %d <  %d\n", buf_size, s->frame_size);
        return -1;
    }

    if (!keyframe
        && avctx->frame_number > s->last_key_frame + avctx->keyint_min) {
        recommend_keyframe(s, &keyframe);
        if (keyframe)
            av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number);
    }

    if (keyframe) {
        res = reconfigure_at_keyframe(s, p->data[0], p->linesize[0]);
        if (res)
            return res;
    }

    if (s->use15_7)
        s->dist = optimum_dist(s);

    res = write_bitstream(s, p->data[0], p->linesize[0], buf, buf_size, keyframe);

    if (keyframe) {
        new_key_frame(s);
        p->pict_type = AV_PICTURE_TYPE_I;
        p->key_frame = 1;
        s->last_key_frame = avctx->frame_number;
        av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
    } else {
        p->pict_type = AV_PICTURE_TYPE_P;
        p->key_frame = 0;
    }

    avctx->coded_frame = p;

    return res;
}

static av_cold int flashsv2_encode_end(AVCodecContext * avctx)
{
    FlashSV2Context *s = avctx->priv_data;

    cleanup(s);

    return 0;
}

AVCodec ff_flashsv2_encoder = {
    .name           = "flashsv2",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_FLASHSV2,
    .priv_data_size = sizeof(FlashSV2Context),
    .init           = flashsv2_encode_init,
    .encode         = flashsv2_encode_frame,
    .close          = flashsv2_encode_end,
    .pix_fmts = (enum PixelFormat[]) {PIX_FMT_BGR24, PIX_FMT_NONE},
    .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"),
    .capabilities   =  CODEC_CAP_EXPERIMENTAL,
};
