/*
 *  Copyright (c) 2010 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.
 */


#include "vp8/common/onyxc_int.h"
#include "onyx_int.h"
#include "vp8/common/systemdependent.h"
#include "quantize.h"
#include "vp8/common/alloccommon.h"
#include "mcomp.h"
#include "firstpass.h"
#include "psnr.h"
#include "vpx_scale/vpxscale.h"
#include "vp8/common/extend.h"
#include "ratectrl.h"
#include "vp8/common/quant_common.h"
#include "segmentation.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/swapyv12buffer.h"
#include "vp8/common/threading.h"
#include "vpx_ports/vpx_timer.h"

#include <math.h>
#include <limits.h>

#define ALT_REF_MC_ENABLED 1    /* dis/enable MC in AltRef filtering */
#define ALT_REF_SUBPEL_ENABLED 1 /* dis/enable subpel in MC AltRef filtering */

#if VP8_TEMPORAL_ALT_REF

static void vp8_temporal_filter_predictors_mb_c
(
    MACROBLOCKD *x,
    unsigned char *y_mb_ptr,
    unsigned char *u_mb_ptr,
    unsigned char *v_mb_ptr,
    int stride,
    int mv_row,
    int mv_col,
    unsigned char *pred
)
{
    int offset;
    unsigned char *yptr, *uptr, *vptr;

    /* Y */
    yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3);

    if ((mv_row | mv_col) & 7)
    {
        x->subpixel_predict16x16(yptr, stride,
                                    mv_col & 7, mv_row & 7, &pred[0], 16);
    }
    else
    {
        vp8_copy_mem16x16(yptr, stride, &pred[0], 16);
    }

    /* U & V */
    mv_row >>= 1;
    mv_col >>= 1;
    stride = (stride + 1) >> 1;
    offset = (mv_row >> 3) * stride + (mv_col >> 3);
    uptr = u_mb_ptr + offset;
    vptr = v_mb_ptr + offset;

    if ((mv_row | mv_col) & 7)
    {
        x->subpixel_predict8x8(uptr, stride,
                            mv_col & 7, mv_row & 7, &pred[256], 8);
        x->subpixel_predict8x8(vptr, stride,
                            mv_col & 7, mv_row & 7, &pred[320], 8);
    }
    else
    {
        vp8_copy_mem8x8(uptr, stride, &pred[256], 8);
        vp8_copy_mem8x8(vptr, stride, &pred[320], 8);
    }
}
void vp8_temporal_filter_apply_c
(
    unsigned char *frame1,
    unsigned int stride,
    unsigned char *frame2,
    unsigned int block_size,
    int strength,
    int filter_weight,
    unsigned int *accumulator,
    unsigned short *count
)
{
    unsigned int i, j, k;
    int modifier;
    int byte = 0;

    for (i = 0,k = 0; i < block_size; i++)
    {
        for (j = 0; j < block_size; j++, k++)
        {

            int src_byte = frame1[byte];
            int pixel_value = *frame2++;

            modifier   = src_byte - pixel_value;
            /* This is an integer approximation of:
             * float coeff = (3.0 * modifer * modifier) / pow(2, strength);
             * modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
             */
            modifier  *= modifier;
            modifier  *= 3;
            modifier  += 1 << (strength - 1);
            modifier >>= strength;

            if (modifier > 16)
                modifier = 16;

            modifier = 16 - modifier;
            modifier *= filter_weight;

            count[k] += modifier;
            accumulator[k] += modifier * pixel_value;

            byte++;
        }

        byte += stride - block_size;
    }
}

#if ALT_REF_MC_ENABLED

static int vp8_temporal_filter_find_matching_mb_c
(
    VP8_COMP *cpi,
    YV12_BUFFER_CONFIG *arf_frame,
    YV12_BUFFER_CONFIG *frame_ptr,
    int mb_offset,
    int error_thresh
)
{
    MACROBLOCK *x = &cpi->mb;
    int step_param;
    int sadpb = x->sadperbit16;
    int bestsme = INT_MAX;

    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    int_mv best_ref_mv1;
    int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */

    /* Save input state */
    unsigned char **base_src = b->base_src;
    int src = b->src;
    int src_stride = b->src_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
    int pre = d->offset;
    int pre_stride = x->e_mbd.pre.y_stride;

    best_ref_mv1.as_int = 0;
    best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >>3;
    best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >>3;

    /* Setup frame pointers */
    b->base_src = &arf_frame->y_buffer;
    b->src_stride = arf_frame->y_stride;
    b->src = mb_offset;

    x->e_mbd.pre.y_buffer = frame_ptr->y_buffer;
    x->e_mbd.pre.y_stride = frame_ptr->y_stride;
    d->offset = mb_offset;

    /* Further step/diamond searches as necessary */
    if (cpi->Speed < 8)
    {
        step_param = cpi->sf.first_step + (cpi->Speed > 5);
    }
    else
    {
        step_param = cpi->sf.first_step + 2;
    }

    /* TODO Check that the 16x16 vf & sdf are selected here */
    /* Ignore mv costing by sending NULL cost arrays */
    bestsme = vp8_hex_search(x, b, d, &best_ref_mv1_full, &d->bmi.mv,
                             step_param, sadpb,
                             &cpi->fn_ptr[BLOCK_16X16],
                             NULL, NULL, &best_ref_mv1);

#if ALT_REF_SUBPEL_ENABLED
    /* Try sub-pixel MC? */
    {
        int distortion;
        unsigned int sse;
        /* Ignore mv costing by sending NULL cost array */
        bestsme = cpi->find_fractional_mv_step(x, b, d,
                                               &d->bmi.mv,
                                               &best_ref_mv1,
                                               x->errorperbit,
                                               &cpi->fn_ptr[BLOCK_16X16],
                                               NULL, &distortion, &sse);
    }
#endif

    /* Save input state */
    b->base_src = base_src;
    b->src = src;
    b->src_stride = src_stride;
    x->e_mbd.pre.y_buffer = base_pre;
    d->offset = pre;
    x->e_mbd.pre.y_stride = pre_stride;

    return bestsme;
}
#endif

static void vp8_temporal_filter_iterate_c
(
    VP8_COMP *cpi,
    int frame_count,
    int alt_ref_index,
    int strength
)
{
    int byte;
    int frame;
    int mb_col, mb_row;
    unsigned int filter_weight;
    int mb_cols = cpi->common.mb_cols;
    int mb_rows = cpi->common.mb_rows;
    int mb_y_offset = 0;
    int mb_uv_offset = 0;
    DECLARE_ALIGNED_ARRAY(16, unsigned int, accumulator, 16*16 + 8*8 + 8*8);
    DECLARE_ALIGNED_ARRAY(16, unsigned short, count, 16*16 + 8*8 + 8*8);
    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
    YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
    unsigned char *dst1, *dst2;
    DECLARE_ALIGNED_ARRAY(16, unsigned char,  predictor, 16*16 + 8*8 + 8*8);

    /* Save input state */
    unsigned char *y_buffer = mbd->pre.y_buffer;
    unsigned char *u_buffer = mbd->pre.u_buffer;
    unsigned char *v_buffer = mbd->pre.v_buffer;

    for (mb_row = 0; mb_row < mb_rows; mb_row++)
    {
#if ALT_REF_MC_ENABLED
        /* Source frames are extended to 16 pixels.  This is different than
         *  L/A/G reference frames that have a border of 32 (VP8BORDERINPIXELS)
         * A 6 tap filter is used for motion search.  This requires 2 pixels
         *  before and 3 pixels after.  So the largest Y mv on a border would
         *  then be 16 - 3.  The UV blocks are half the size of the Y and
         *  therefore only extended by 8.  The largest mv that a UV block
         *  can support is 8 - 3.  A UV mv is half of a Y mv.
         *  (16 - 3) >> 1 == 6 which is greater than 8 - 3.
         * To keep the mv in play for both Y and UV planes the max that it
         *  can be on a border is therefore 16 - 5.
         */
        cpi->mb.mv_row_min = -((mb_row * 16) + (16 - 5));
        cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
                                + (16 - 5);
#endif

        for (mb_col = 0; mb_col < mb_cols; mb_col++)
        {
            int i, j, k;
            int stride;

            vpx_memset(accumulator, 0, 384*sizeof(unsigned int));
            vpx_memset(count, 0, 384*sizeof(unsigned short));

#if ALT_REF_MC_ENABLED
            cpi->mb.mv_col_min = -((mb_col * 16) + (16 - 5));
            cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16)
                                    + (16 - 5);
#endif

            for (frame = 0; frame < frame_count; frame++)
            {
                if (cpi->frames[frame] == NULL)
                    continue;

                mbd->block[0].bmi.mv.as_mv.row = 0;
                mbd->block[0].bmi.mv.as_mv.col = 0;

                if (frame == alt_ref_index)
                {
                    filter_weight = 2;
                }
                else
                {
                    int err = 0;
#if ALT_REF_MC_ENABLED
#define THRESH_LOW   10000
#define THRESH_HIGH  20000
                    /* Find best match in this frame by MC */
                    err = vp8_temporal_filter_find_matching_mb_c
                              (cpi,
                               cpi->frames[alt_ref_index],
                               cpi->frames[frame],
                               mb_y_offset,
                               THRESH_LOW);
#endif
                    /* Assign higher weight to matching MB if it's error
                     * score is lower. If not applying MC default behavior
                     * is to weight all MBs equal.
                     */
                    filter_weight = err<THRESH_LOW
                                       ? 2 : err<THRESH_HIGH ? 1 : 0;
                }

                if (filter_weight != 0)
                {
                    /* Construct the predictors */
                    vp8_temporal_filter_predictors_mb_c
                        (mbd,
                         cpi->frames[frame]->y_buffer + mb_y_offset,
                         cpi->frames[frame]->u_buffer + mb_uv_offset,
                         cpi->frames[frame]->v_buffer + mb_uv_offset,
                         cpi->frames[frame]->y_stride,
                         mbd->block[0].bmi.mv.as_mv.row,
                         mbd->block[0].bmi.mv.as_mv.col,
                         predictor);

                    /* Apply the filter (YUV) */
                    vp8_temporal_filter_apply
                        (f->y_buffer + mb_y_offset,
                         f->y_stride,
                         predictor,
                         16,
                         strength,
                         filter_weight,
                         accumulator,
                         count);

                    vp8_temporal_filter_apply
                        (f->u_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 256,
                         8,
                         strength,
                         filter_weight,
                         accumulator + 256,
                         count + 256);

                    vp8_temporal_filter_apply
                        (f->v_buffer + mb_uv_offset,
                         f->uv_stride,
                         predictor + 320,
                         8,
                         strength,
                         filter_weight,
                         accumulator + 320,
                         count + 320);
                }
            }

            /* Normalize filter output to produce AltRef frame */
            dst1 = cpi->alt_ref_buffer.y_buffer;
            stride = cpi->alt_ref_buffer.y_stride;
            byte = mb_y_offset;
            for (i = 0,k = 0; i < 16; i++)
            {
                for (j = 0; j < 16; j++, k++)
                {
                    unsigned int pval = accumulator[k] + (count[k] >> 1);
                    pval *= cpi->fixed_divide[count[k]];
                    pval >>= 19;

                    dst1[byte] = (unsigned char)pval;

                    /* move to next pixel */
                    byte++;
                }

                byte += stride - 16;
            }

            dst1 = cpi->alt_ref_buffer.u_buffer;
            dst2 = cpi->alt_ref_buffer.v_buffer;
            stride = cpi->alt_ref_buffer.uv_stride;
            byte = mb_uv_offset;
            for (i = 0,k = 256; i < 8; i++)
            {
                for (j = 0; j < 8; j++, k++)
                {
                    int m=k+64;

                    /* U */
                    unsigned int pval = accumulator[k] + (count[k] >> 1);
                    pval *= cpi->fixed_divide[count[k]];
                    pval >>= 19;
                    dst1[byte] = (unsigned char)pval;

                    /* V */
                    pval = accumulator[m] + (count[m] >> 1);
                    pval *= cpi->fixed_divide[count[m]];
                    pval >>= 19;
                    dst2[byte] = (unsigned char)pval;

                    /* move to next pixel */
                    byte++;
                }

                byte += stride - 8;
            }

            mb_y_offset += 16;
            mb_uv_offset += 8;
        }

        mb_y_offset += 16*(f->y_stride-mb_cols);
        mb_uv_offset += 8*(f->uv_stride-mb_cols);
    }

    /* Restore input state */
    mbd->pre.y_buffer = y_buffer;
    mbd->pre.u_buffer = u_buffer;
    mbd->pre.v_buffer = v_buffer;
}

void vp8_temporal_filter_prepare_c
(
    VP8_COMP *cpi,
    int distance
)
{
    int frame = 0;

    int num_frames_backward = 0;
    int num_frames_forward = 0;
    int frames_to_blur_backward = 0;
    int frames_to_blur_forward = 0;
    int frames_to_blur = 0;
    int start_frame = 0;

    int strength = cpi->oxcf.arnr_strength;

    int blur_type = cpi->oxcf.arnr_type;

    int max_frames = cpi->active_arnr_frames;

    num_frames_backward = distance;
    num_frames_forward = vp8_lookahead_depth(cpi->lookahead)
                         - (num_frames_backward + 1);

    switch (blur_type)
    {
    case 1:
        /* Backward Blur */

        frames_to_blur_backward = num_frames_backward;

        if (frames_to_blur_backward >= max_frames)
            frames_to_blur_backward = max_frames - 1;

        frames_to_blur = frames_to_blur_backward + 1;
        break;

    case 2:
        /* Forward Blur */

        frames_to_blur_forward = num_frames_forward;

        if (frames_to_blur_forward >= max_frames)
            frames_to_blur_forward = max_frames - 1;

        frames_to_blur = frames_to_blur_forward + 1;
        break;

    case 3:
    default:
        /* Center Blur */
        frames_to_blur_forward = num_frames_forward;
        frames_to_blur_backward = num_frames_backward;

        if (frames_to_blur_forward > frames_to_blur_backward)
            frames_to_blur_forward = frames_to_blur_backward;

        if (frames_to_blur_backward > frames_to_blur_forward)
            frames_to_blur_backward = frames_to_blur_forward;

        /* When max_frames is even we have 1 more frame backward than forward */
        if (frames_to_blur_forward > (max_frames - 1) / 2)
            frames_to_blur_forward = ((max_frames - 1) / 2);

        if (frames_to_blur_backward > (max_frames / 2))
            frames_to_blur_backward = (max_frames / 2);

        frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
        break;
    }

    start_frame = distance + frames_to_blur_forward;

    /* Setup frame pointers, NULL indicates frame not included in filter */
    vpx_memset(cpi->frames, 0, max_frames*sizeof(YV12_BUFFER_CONFIG *));
    for (frame = 0; frame < frames_to_blur; frame++)
    {
        int which_buffer =  start_frame - frame;
        struct lookahead_entry* buf = vp8_lookahead_peek(cpi->lookahead,
                                                         which_buffer,
                                                         PEEK_FORWARD);
        cpi->frames[frames_to_blur-1-frame] = &buf->img;
    }

    vp8_temporal_filter_iterate_c (
        cpi,
        frames_to_blur,
        frames_to_blur_backward,
        strength );
}
#endif
