/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


/* MFQE: Multiframe Quality Enhancement
 * In rate limited situations keyframes may cause significant visual artifacts
 * commonly referred to as "popping." This file implements a postproccesing
 * algorithm which blends data from the preceeding frame when there is no
 * motion and the q from the previous frame is lower which indicates that it is
 * higher quality.
 */

#include "postproc.h"
#include "variance.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8_rtcd.h"
#include "vpx_scale/yv12config.h"

#include <limits.h>
#include <stdlib.h>

static void filter_by_weight(unsigned char *src, int src_stride,
                             unsigned char *dst, int dst_stride,
                             int block_size, int src_weight)
{
    int dst_weight = (1 << MFQE_PRECISION) - src_weight;
    int rounding_bit = 1 << (MFQE_PRECISION - 1);
    int r, c;

    for (r = 0; r < block_size; r++)
    {
        for (c = 0; c < block_size; c++)
        {
            dst[c] = (src[c] * src_weight +
                      dst[c] * dst_weight +
                      rounding_bit) >> MFQE_PRECISION;
        }
        src += src_stride;
        dst += dst_stride;
    }
}

void vp8_filter_by_weight16x16_c(unsigned char *src, int src_stride,
                                 unsigned char *dst, int dst_stride,
                                 int src_weight)
{
    filter_by_weight(src, src_stride, dst, dst_stride, 16, src_weight);
}

void vp8_filter_by_weight8x8_c(unsigned char *src, int src_stride,
                               unsigned char *dst, int dst_stride,
                               int src_weight)
{
    filter_by_weight(src, src_stride, dst, dst_stride, 8, src_weight);
}

void vp8_filter_by_weight4x4_c(unsigned char *src, int src_stride,
                               unsigned char *dst, int dst_stride,
                               int src_weight)
{
    filter_by_weight(src, src_stride, dst, dst_stride, 4, src_weight);
}

static void apply_ifactor(unsigned char *y_src,
                          int y_src_stride,
                          unsigned char *y_dst,
                          int y_dst_stride,
                          unsigned char *u_src,
                          unsigned char *v_src,
                          int uv_src_stride,
                          unsigned char *u_dst,
                          unsigned char *v_dst,
                          int uv_dst_stride,
                          int block_size,
                          int src_weight)
{
    if (block_size == 16)
    {
        vp8_filter_by_weight16x16(y_src, y_src_stride, y_dst, y_dst_stride, src_weight);
        vp8_filter_by_weight8x8(u_src, uv_src_stride, u_dst, uv_dst_stride, src_weight);
        vp8_filter_by_weight8x8(v_src, uv_src_stride, v_dst, uv_dst_stride, src_weight);
    }
    else /* if (block_size == 8) */
    {
        vp8_filter_by_weight8x8(y_src, y_src_stride, y_dst, y_dst_stride, src_weight);
        vp8_filter_by_weight4x4(u_src, uv_src_stride, u_dst, uv_dst_stride, src_weight);
        vp8_filter_by_weight4x4(v_src, uv_src_stride, v_dst, uv_dst_stride, src_weight);
    }
}

static unsigned int int_sqrt(unsigned int x)
{
    unsigned int y = x;
    unsigned int guess;
    int p = 1;
    while (y>>=1) p++;
    p>>=1;

    guess=0;
    while (p>=0)
    {
        guess |= (1<<p);
        if (x<guess*guess)
            guess -= (1<<p);
        p--;
    }
    /* choose between guess or guess+1 */
    return guess+(guess*guess+guess+1<=x);
}

#define USE_SSD
static void multiframe_quality_enhance_block
(
    int blksize, /* Currently only values supported are 16, 8 */
    int qcurr,
    int qprev,
    unsigned char *y,
    unsigned char *u,
    unsigned char *v,
    int y_stride,
    int uv_stride,
    unsigned char *yd,
    unsigned char *ud,
    unsigned char *vd,
    int yd_stride,
    int uvd_stride
)
{
    static const unsigned char VP8_ZEROS[16]=
    {
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    };
    int uvblksize = blksize >> 1;
    int qdiff = qcurr - qprev;

    int i;
    unsigned char *up;
    unsigned char *udp;
    unsigned char *vp;
    unsigned char *vdp;

    unsigned int act, actd, sad, usad, vsad, sse, thr, thrsq, actrisk;

    if (blksize == 16)
    {
        actd = (vp8_variance16x16(yd, yd_stride, VP8_ZEROS, 0, &sse)+128)>>8;
        act = (vp8_variance16x16(y, y_stride, VP8_ZEROS, 0, &sse)+128)>>8;
#ifdef USE_SSD
        sad = (vp8_variance16x16(y, y_stride, yd, yd_stride, &sse));
        sad = (sse + 128)>>8;
        usad = (vp8_variance8x8(u, uv_stride, ud, uvd_stride, &sse));
        usad = (sse + 32)>>6;
        vsad = (vp8_variance8x8(v, uv_stride, vd, uvd_stride, &sse));
        vsad = (sse + 32)>>6;
#else
        sad = (vp8_sad16x16(y, y_stride, yd, yd_stride, UINT_MAX) + 128) >> 8;
        usad = (vp8_sad8x8(u, uv_stride, ud, uvd_stride, UINT_MAX) + 32) >> 6;
        vsad = (vp8_sad8x8(v, uv_stride, vd, uvd_stride, UINT_MAX)+ 32) >> 6;
#endif
    }
    else /* if (blksize == 8) */
    {
        actd = (vp8_variance8x8(yd, yd_stride, VP8_ZEROS, 0, &sse)+32)>>6;
        act = (vp8_variance8x8(y, y_stride, VP8_ZEROS, 0, &sse)+32)>>6;
#ifdef USE_SSD
        sad = (vp8_variance8x8(y, y_stride, yd, yd_stride, &sse));
        sad = (sse + 32)>>6;
        usad = (vp8_variance4x4(u, uv_stride, ud, uvd_stride, &sse));
        usad = (sse + 8)>>4;
        vsad = (vp8_variance4x4(v, uv_stride, vd, uvd_stride, &sse));
        vsad = (sse + 8)>>4;
#else
        sad = (vp8_sad8x8(y, y_stride, yd, yd_stride, UINT_MAX) + 32) >> 6;
        usad = (vp8_sad4x4(u, uv_stride, ud, uvd_stride, UINT_MAX) + 8) >> 4;
        vsad = (vp8_sad4x4(v, uv_stride, vd, uvd_stride, UINT_MAX) + 8) >> 4;
#endif
    }

    actrisk = (actd > act * 5);

    /* thr = qdiff/16 + log2(act) + log4(qprev) */
    thr = (qdiff >> 4);
    while (actd >>= 1) thr++;
    while (qprev >>= 2) thr++;

#ifdef USE_SSD
    thrsq = thr * thr;
    if (sad < thrsq &&
        /* additional checks for color mismatch and excessive addition of
         * high-frequencies */
        4 * usad < thrsq && 4 * vsad < thrsq && !actrisk)
#else
    if (sad < thr &&
        /* additional checks for color mismatch and excessive addition of
         * high-frequencies */
        2 * usad < thr && 2 * vsad < thr && !actrisk)
#endif
    {
        int ifactor;
#ifdef USE_SSD
        /* TODO: optimize this later to not need sqr root */
        sad = int_sqrt(sad);
#endif
        ifactor = (sad << MFQE_PRECISION) / thr;
        ifactor >>= (qdiff >> 5);

        if (ifactor)
        {
            apply_ifactor(y, y_stride, yd, yd_stride,
                          u, v, uv_stride,
                          ud, vd, uvd_stride,
                          blksize, ifactor);
        }
    }
    else  /* else implicitly copy from previous frame */
    {
        if (blksize == 16)
        {
            vp8_copy_mem16x16(y, y_stride, yd, yd_stride);
            vp8_copy_mem8x8(u, uv_stride, ud, uvd_stride);
            vp8_copy_mem8x8(v, uv_stride, vd, uvd_stride);
        }
        else  /* if (blksize == 8) */
        {
            vp8_copy_mem8x8(y, y_stride, yd, yd_stride);
            for (up = u, udp = ud, i = 0; i < uvblksize; ++i, up += uv_stride, udp += uvd_stride)
                vpx_memcpy(udp, up, uvblksize);
            for (vp = v, vdp = vd, i = 0; i < uvblksize; ++i, vp += uv_stride, vdp += uvd_stride)
                vpx_memcpy(vdp, vp, uvblksize);
        }
    }
}

static int qualify_inter_mb(const MODE_INFO *mode_info_context, int *map)
{
    if (mode_info_context->mbmi.mb_skip_coeff)
        map[0] = map[1] = map[2] = map[3] = 1;
    else if (mode_info_context->mbmi.mode==SPLITMV)
    {
        static int ndx[4][4] =
        {
            {0, 1, 4, 5},
            {2, 3, 6, 7},
            {8, 9, 12, 13},
            {10, 11, 14, 15}
        };
        int i, j;
        for (i=0; i<4; ++i)
        {
            map[i] = 1;
            for (j=0; j<4 && map[j]; ++j)
                map[i] &= (mode_info_context->bmi[ndx[i][j]].mv.as_mv.row <= 2 &&
                           mode_info_context->bmi[ndx[i][j]].mv.as_mv.col <= 2);
        }
    }
    else
    {
        map[0] = map[1] = map[2] = map[3] =
            (mode_info_context->mbmi.mode > B_PRED &&
             abs(mode_info_context->mbmi.mv.as_mv.row) <= 2 &&
             abs(mode_info_context->mbmi.mv.as_mv.col) <= 2);
    }
    return (map[0]+map[1]+map[2]+map[3]);
}

void vp8_multiframe_quality_enhance
(
    VP8_COMMON *cm
)
{
    YV12_BUFFER_CONFIG *show = cm->frame_to_show;
    YV12_BUFFER_CONFIG *dest = &cm->post_proc_buffer;

    FRAME_TYPE frame_type = cm->frame_type;
    /* Point at base of Mb MODE_INFO list has motion vectors etc */
    const MODE_INFO *mode_info_context = cm->show_frame_mi;
    int mb_row;
    int mb_col;
    int totmap, map[4];
    int qcurr = cm->base_qindex;
    int qprev = cm->postproc_state.last_base_qindex;

    unsigned char *y_ptr, *u_ptr, *v_ptr;
    unsigned char *yd_ptr, *ud_ptr, *vd_ptr;

    /* Set up the buffer pointers */
    y_ptr = show->y_buffer;
    u_ptr = show->u_buffer;
    v_ptr = show->v_buffer;
    yd_ptr = dest->y_buffer;
    ud_ptr = dest->u_buffer;
    vd_ptr = dest->v_buffer;

    /* postprocess each macro block */
    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    {
        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
        {
            /* if motion is high there will likely be no benefit */
            if (frame_type == INTER_FRAME) totmap = qualify_inter_mb(mode_info_context, map);
            else totmap = (frame_type == KEY_FRAME ? 4 : 0);
            if (totmap)
            {
                if (totmap < 4)
                {
                    int i, j;
                    for (i=0; i<2; ++i)
                        for (j=0; j<2; ++j)
                        {
                            if (map[i*2+j])
                            {
                                multiframe_quality_enhance_block(8, qcurr, qprev,
                                                                 y_ptr + 8*(i*show->y_stride+j),
                                                                 u_ptr + 4*(i*show->uv_stride+j),
                                                                 v_ptr + 4*(i*show->uv_stride+j),
                                                                 show->y_stride,
                                                                 show->uv_stride,
                                                                 yd_ptr + 8*(i*dest->y_stride+j),
                                                                 ud_ptr + 4*(i*dest->uv_stride+j),
                                                                 vd_ptr + 4*(i*dest->uv_stride+j),
                                                                 dest->y_stride,
                                                                 dest->uv_stride);
                            }
                            else
                            {
                                /* copy a 8x8 block */
                                int k;
                                unsigned char *up = u_ptr + 4*(i*show->uv_stride+j);
                                unsigned char *udp = ud_ptr + 4*(i*dest->uv_stride+j);
                                unsigned char *vp = v_ptr + 4*(i*show->uv_stride+j);
                                unsigned char *vdp = vd_ptr + 4*(i*dest->uv_stride+j);
                                vp8_copy_mem8x8(y_ptr + 8*(i*show->y_stride+j), show->y_stride,
                                                yd_ptr + 8*(i*dest->y_stride+j), dest->y_stride);
                                for (k = 0; k < 4; ++k, up += show->uv_stride, udp += dest->uv_stride,
                                                        vp += show->uv_stride, vdp += dest->uv_stride)
                                {
                                    vpx_memcpy(udp, up, 4);
                                    vpx_memcpy(vdp, vp, 4);
                                }
                            }
                        }
                }
                else /* totmap = 4 */
                {
                    multiframe_quality_enhance_block(16, qcurr, qprev, y_ptr,
                                                     u_ptr, v_ptr,
                                                     show->y_stride,
                                                     show->uv_stride,
                                                     yd_ptr, ud_ptr, vd_ptr,
                                                     dest->y_stride,
                                                     dest->uv_stride);
                }
            }
            else
            {
                vp8_copy_mem16x16(y_ptr, show->y_stride, yd_ptr, dest->y_stride);
                vp8_copy_mem8x8(u_ptr, show->uv_stride, ud_ptr, dest->uv_stride);
                vp8_copy_mem8x8(v_ptr, show->uv_stride, vd_ptr, dest->uv_stride);
            }
            y_ptr += 16;
            u_ptr += 8;
            v_ptr += 8;
            yd_ptr += 16;
            ud_ptr += 8;
            vd_ptr += 8;
            mode_info_context++;     /* step to next MB */
        }

        y_ptr += show->y_stride  * 16 - 16 * cm->mb_cols;
        u_ptr += show->uv_stride *  8 - 8 * cm->mb_cols;
        v_ptr += show->uv_stride *  8 - 8 * cm->mb_cols;
        yd_ptr += dest->y_stride  * 16 - 16 * cm->mb_cols;
        ud_ptr += dest->uv_stride *  8 - 8 * cm->mb_cols;
        vd_ptr += dest->uv_stride *  8 - 8 * cm->mb_cols;

        mode_info_context++;         /* Skip border mb */
    }
}
