/*
 *  Copyright (c) 2011 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 <assert.h>

#include "error_concealment.h"
#include "onyxd_int.h"
#include "decodemv.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/findnearmv.h"
#include "vp8/common/common.h"

#define FLOOR(x,q) ((x) & -(1 << (q)))

#define NUM_NEIGHBORS 20

typedef struct ec_position
{
    int row;
    int col;
} EC_POS;

/*
 * Regenerate the table in Matlab with:
 * x = meshgrid((1:4), (1:4));
 * y = meshgrid((1:4), (1:4))';
 * W = round((1./(sqrt(x.^2 + y.^2))*2^7));
 * W(1,1) = 0;
 */
static const int weights_q7[5][5] = {
       {  0,   128,    64,    43,    32 },
       {128,    91,    57,    40,    31 },
       { 64,    57,    45,    36,    29 },
       { 43,    40,    36,    30,    26 },
       { 32,    31,    29,    26,    23 }
};

int vp8_alloc_overlap_lists(VP8D_COMP *pbi)
{
    if (pbi->overlaps != NULL)
    {
        vpx_free(pbi->overlaps);
        pbi->overlaps = NULL;
    }

    pbi->overlaps = vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols,
                               sizeof(MB_OVERLAP));

    if (pbi->overlaps == NULL)
        return -1;

    return 0;
}

void vp8_de_alloc_overlap_lists(VP8D_COMP *pbi)
{
    vpx_free(pbi->overlaps);
    pbi->overlaps = NULL;
}

/* Inserts a new overlap area value to the list of overlaps of a block */
static void assign_overlap(OVERLAP_NODE* overlaps,
                           union b_mode_info *bmi,
                           int overlap)
{
    int i;
    if (overlap <= 0)
        return;
    /* Find and assign to the next empty overlap node in the list of overlaps.
     * Empty is defined as bmi == NULL */
    for (i = 0; i < MAX_OVERLAPS; i++)
    {
        if (overlaps[i].bmi == NULL)
        {
            overlaps[i].bmi = bmi;
            overlaps[i].overlap = overlap;
            break;
        }
    }
}

/* Calculates the overlap area between two 4x4 squares, where the first
 * square has its upper-left corner at (b1_row, b1_col) and the second
 * square has its upper-left corner at (b2_row, b2_col). Doesn't
 * properly handle squares which do not overlap.
 */
static int block_overlap(int b1_row, int b1_col, int b2_row, int b2_col)
{
    const int int_top = MAX(b1_row, b2_row); // top
    const int int_left = MAX(b1_col, b2_col); // left
    /* Since each block is 4x4 pixels, adding 4 (Q3) to the left/top edge
     * gives us the right/bottom edge.
     */
    const int int_right = MIN(b1_col + (4<<3), b2_col + (4<<3)); // right
    const int int_bottom = MIN(b1_row + (4<<3), b2_row + (4<<3)); // bottom
    return (int_bottom - int_top) * (int_right - int_left);
}

/* Calculates the overlap area for all blocks in a macroblock at position
 * (mb_row, mb_col) in macroblocks, which are being overlapped by a given
 * overlapping block at position (new_row, new_col) (in pixels, Q3). The
 * first block being overlapped in the macroblock has position (first_blk_row,
 * first_blk_col) in blocks relative the upper-left corner of the image.
 */
static void calculate_overlaps_mb(B_OVERLAP *b_overlaps, union b_mode_info *bmi,
                                  int new_row, int new_col,
                                  int mb_row, int mb_col,
                                  int first_blk_row, int first_blk_col)
{
    /* Find the blocks within this MB (defined by mb_row, mb_col) which are
     * overlapped by bmi and calculate and assign overlap for each of those
     * blocks. */

    /* Block coordinates relative the upper-left block */
    const int rel_ol_blk_row = first_blk_row - mb_row * 4;
    const int rel_ol_blk_col = first_blk_col - mb_col * 4;
    /* If the block partly overlaps any previous MB, these coordinates
     * can be < 0. We don't want to access blocks in previous MBs.
     */
    const int blk_idx = MAX(rel_ol_blk_row,0) * 4 + MAX(rel_ol_blk_col,0);
    /* Upper left overlapping block */
    B_OVERLAP *b_ol_ul = &(b_overlaps[blk_idx]);

    /* Calculate and assign overlaps for all blocks in this MB
     * which the motion compensated block overlaps
     */
    /* Avoid calculating overlaps for blocks in later MBs */
    int end_row = MIN(4 + mb_row * 4 - first_blk_row, 2);
    int end_col = MIN(4 + mb_col * 4 - first_blk_col, 2);
    int row, col;

    /* Check if new_row and new_col are evenly divisible by 4 (Q3),
     * and if so we shouldn't check neighboring blocks
     */
    if (new_row >= 0 && (new_row & 0x1F) == 0)
        end_row = 1;
    if (new_col >= 0 && (new_col & 0x1F) == 0)
        end_col = 1;

    /* Check if the overlapping block partly overlaps a previous MB
     * and if so, we're overlapping fewer blocks in this MB.
     */
    if (new_row < (mb_row*16)<<3)
        end_row = 1;
    if (new_col < (mb_col*16)<<3)
        end_col = 1;

    for (row = 0; row < end_row; ++row)
    {
        for (col = 0; col < end_col; ++col)
        {
            /* input in Q3, result in Q6 */
            const int overlap = block_overlap(new_row, new_col,
                                                  (((first_blk_row + row) *
                                                      4) << 3),
                                                  (((first_blk_col + col) *
                                                      4) << 3));
            assign_overlap(b_ol_ul[row * 4 + col].overlaps, bmi, overlap);
        }
    }
}

void vp8_calculate_overlaps(MB_OVERLAP *overlap_ul,
                            int mb_rows, int mb_cols,
                            union b_mode_info *bmi,
                            int b_row, int b_col)
{
    MB_OVERLAP *mb_overlap;
    int row, col, rel_row, rel_col;
    int new_row, new_col;
    int end_row, end_col;
    int overlap_b_row, overlap_b_col;
    int overlap_mb_row, overlap_mb_col;

    /* mb subpixel position */
    row = (4 * b_row) << 3; /* Q3 */
    col = (4 * b_col) << 3; /* Q3 */

    /* reverse compensate for motion */
    new_row = row - bmi->mv.as_mv.row;
    new_col = col - bmi->mv.as_mv.col;

    if (new_row >= ((16*mb_rows) << 3) || new_col >= ((16*mb_cols) << 3))
    {
        /* the new block ended up outside the frame */
        return;
    }

    if (new_row <= (-4 << 3) || new_col <= (-4 << 3))
    {
        /* outside the frame */
        return;
    }
    /* overlapping block's position in blocks */
    overlap_b_row = FLOOR(new_row / 4, 3) >> 3;
    overlap_b_col = FLOOR(new_col / 4, 3) >> 3;

    /* overlapping block's MB position in MBs
     * operations are done in Q3
     */
    overlap_mb_row = FLOOR((overlap_b_row << 3) / 4, 3) >> 3;
    overlap_mb_col = FLOOR((overlap_b_col << 3) / 4, 3) >> 3;

    end_row = MIN(mb_rows - overlap_mb_row, 2);
    end_col = MIN(mb_cols - overlap_mb_col, 2);

    /* Don't calculate overlap for MBs we don't overlap */
    /* Check if the new block row starts at the last block row of the MB */
    if (abs(new_row - ((16*overlap_mb_row) << 3)) < ((3*4) << 3))
        end_row = 1;
    /* Check if the new block col starts at the last block col of the MB */
    if (abs(new_col - ((16*overlap_mb_col) << 3)) < ((3*4) << 3))
        end_col = 1;

    /* find the MB(s) this block is overlapping */
    for (rel_row = 0; rel_row < end_row; ++rel_row)
    {
        for (rel_col = 0; rel_col < end_col; ++rel_col)
        {
            if (overlap_mb_row + rel_row < 0 ||
                overlap_mb_col + rel_col < 0)
                continue;
            mb_overlap = overlap_ul + (overlap_mb_row + rel_row) * mb_cols +
                 overlap_mb_col + rel_col;

            calculate_overlaps_mb(mb_overlap->overlaps, bmi,
                                  new_row, new_col,
                                  overlap_mb_row + rel_row,
                                  overlap_mb_col + rel_col,
                                  overlap_b_row + rel_row,
                                  overlap_b_col + rel_col);
        }
    }
}

/* Estimates a motion vector given the overlapping blocks' motion vectors.
 * Filters out all overlapping blocks which do not refer to the correct
 * reference frame type.
 */
static void estimate_mv(const OVERLAP_NODE *overlaps, union b_mode_info *bmi)
{
    int i;
    int overlap_sum = 0;
    int row_acc = 0;
    int col_acc = 0;

    bmi->mv.as_int = 0;
    for (i=0; i < MAX_OVERLAPS; ++i)
    {
        if (overlaps[i].bmi == NULL)
            break;
        col_acc += overlaps[i].overlap * overlaps[i].bmi->mv.as_mv.col;
        row_acc += overlaps[i].overlap * overlaps[i].bmi->mv.as_mv.row;
        overlap_sum += overlaps[i].overlap;
    }
    if (overlap_sum > 0)
    {
        /* Q9 / Q6 = Q3 */
        bmi->mv.as_mv.col = col_acc / overlap_sum;
        bmi->mv.as_mv.row = row_acc / overlap_sum;
    }
    else
    {
        bmi->mv.as_mv.col = 0;
        bmi->mv.as_mv.row = 0;
    }
}

/* Estimates all motion vectors for a macroblock given the lists of
 * overlaps for each block. Decides whether or not the MVs must be clamped.
 */
static void estimate_mb_mvs(const B_OVERLAP *block_overlaps,
                            MODE_INFO *mi,
                            int mb_to_left_edge,
                            int mb_to_right_edge,
                            int mb_to_top_edge,
                            int mb_to_bottom_edge)
{
    int row, col;
    int non_zero_count = 0;
    MV * const filtered_mv = &(mi->mbmi.mv.as_mv);
    union b_mode_info * const bmi = mi->bmi;
    filtered_mv->col = 0;
    filtered_mv->row = 0;
    mi->mbmi.need_to_clamp_mvs = 0;
    for (row = 0; row < 4; ++row)
    {
        int this_b_to_top_edge = mb_to_top_edge + ((row*4)<<3);
        int this_b_to_bottom_edge = mb_to_bottom_edge - ((row*4)<<3);
        for (col = 0; col < 4; ++col)
        {
            int i = row * 4 + col;
            int this_b_to_left_edge = mb_to_left_edge + ((col*4)<<3);
            int this_b_to_right_edge = mb_to_right_edge - ((col*4)<<3);
            /* Estimate vectors for all blocks which are overlapped by this */
            /* type. Interpolate/extrapolate the rest of the block's MVs */
            estimate_mv(block_overlaps[i].overlaps, &(bmi[i]));
            mi->mbmi.need_to_clamp_mvs |= vp8_check_mv_bounds(
                                                         &bmi[i].mv,
                                                         this_b_to_left_edge,
                                                         this_b_to_right_edge,
                                                         this_b_to_top_edge,
                                                         this_b_to_bottom_edge);
            if (bmi[i].mv.as_int != 0)
            {
                ++non_zero_count;
                filtered_mv->col += bmi[i].mv.as_mv.col;
                filtered_mv->row += bmi[i].mv.as_mv.row;
            }
        }
    }
    if (non_zero_count > 0)
    {
        filtered_mv->col /= non_zero_count;
        filtered_mv->row /= non_zero_count;
    }
}

static void calc_prev_mb_overlaps(MB_OVERLAP *overlaps, MODE_INFO *prev_mi,
                                    int mb_row, int mb_col,
                                    int mb_rows, int mb_cols)
{
    int sub_row;
    int sub_col;
    for (sub_row = 0; sub_row < 4; ++sub_row)
    {
        for (sub_col = 0; sub_col < 4; ++sub_col)
        {
            vp8_calculate_overlaps(
                                overlaps, mb_rows, mb_cols,
                                &(prev_mi->bmi[sub_row * 4 + sub_col]),
                                4 * mb_row + sub_row,
                                4 * mb_col + sub_col);
        }
    }
}

/* Estimate all missing motion vectors. This function does the same as the one
 * above, but has different input arguments. */
static void estimate_missing_mvs(MB_OVERLAP *overlaps,
                                 MODE_INFO *mi, MODE_INFO *prev_mi,
                                 int mb_rows, int mb_cols,
                                 unsigned int first_corrupt)
{
    int mb_row, mb_col;
    vpx_memset(overlaps, 0, sizeof(MB_OVERLAP) * mb_rows * mb_cols);
    /* First calculate the overlaps for all blocks */
    for (mb_row = 0; mb_row < mb_rows; ++mb_row)
    {
        for (mb_col = 0; mb_col < mb_cols; ++mb_col)
        {
            /* We're only able to use blocks referring to the last frame
             * when extrapolating new vectors.
             */
            if (prev_mi->mbmi.ref_frame == LAST_FRAME)
            {
                calc_prev_mb_overlaps(overlaps, prev_mi,
                                      mb_row, mb_col,
                                      mb_rows, mb_cols);
            }
            ++prev_mi;
        }
        ++prev_mi;
    }

    mb_row = first_corrupt / mb_cols;
    mb_col = first_corrupt - mb_row * mb_cols;
    mi += mb_row*(mb_cols + 1) + mb_col;
    /* Go through all macroblocks in the current image with missing MVs
     * and calculate new MVs using the overlaps.
     */
    for (; mb_row < mb_rows; ++mb_row)
    {
        int mb_to_top_edge = -((mb_row * 16)) << 3;
        int mb_to_bottom_edge = ((mb_rows - 1 - mb_row) * 16) << 3;
        for (; mb_col < mb_cols; ++mb_col)
        {
            int mb_to_left_edge = -((mb_col * 16) << 3);
            int mb_to_right_edge = ((mb_cols - 1 - mb_col) * 16) << 3;
            const B_OVERLAP *block_overlaps =
                    overlaps[mb_row*mb_cols + mb_col].overlaps;
            mi->mbmi.ref_frame = LAST_FRAME;
            mi->mbmi.mode = SPLITMV;
            mi->mbmi.uv_mode = DC_PRED;
            mi->mbmi.partitioning = 3;
            mi->mbmi.segment_id = 0;
            estimate_mb_mvs(block_overlaps,
                            mi,
                            mb_to_left_edge,
                            mb_to_right_edge,
                            mb_to_top_edge,
                            mb_to_bottom_edge);
            ++mi;
        }
        mb_col = 0;
        ++mi;
    }
}

void vp8_estimate_missing_mvs(VP8D_COMP *pbi)
{
    VP8_COMMON * const pc = &pbi->common;
    estimate_missing_mvs(pbi->overlaps,
                         pc->mi, pc->prev_mi,
                         pc->mb_rows, pc->mb_cols,
                         pbi->mvs_corrupt_from_mb);
}

static void assign_neighbor(EC_BLOCK *neighbor, MODE_INFO *mi, int block_idx)
{
    assert(mi->mbmi.ref_frame < MAX_REF_FRAMES);
    neighbor->ref_frame = mi->mbmi.ref_frame;
    neighbor->mv = mi->bmi[block_idx].mv.as_mv;
}

/* Finds the neighboring blocks of a macroblocks. In the general case
 * 20 blocks are found. If a fewer number of blocks are found due to
 * image boundaries, those positions in the EC_BLOCK array are left "empty".
 * The neighbors are enumerated with the upper-left neighbor as the first
 * element, the second element refers to the neighbor to right of the previous
 * neighbor, and so on. The last element refers to the neighbor below the first
 * neighbor.
 */
static void find_neighboring_blocks(MODE_INFO *mi,
                                    EC_BLOCK *neighbors,
                                    int mb_row, int mb_col,
                                    int mb_rows, int mb_cols,
                                    int mi_stride)
{
    int i = 0;
    int j;
    if (mb_row > 0)
    {
        /* upper left */
        if (mb_col > 0)
            assign_neighbor(&neighbors[i], mi - mi_stride - 1, 15);
        ++i;
        /* above */
        for (j = 12; j < 16; ++j, ++i)
            assign_neighbor(&neighbors[i], mi - mi_stride, j);
    }
    else
        i += 5;
    if (mb_col < mb_cols - 1)
    {
        /* upper right */
        if (mb_row > 0)
            assign_neighbor(&neighbors[i], mi - mi_stride + 1, 12);
        ++i;
        /* right */
        for (j = 0; j <= 12; j += 4, ++i)
            assign_neighbor(&neighbors[i], mi + 1, j);
    }
    else
        i += 5;
    if (mb_row < mb_rows - 1)
    {
        /* lower right */
        if (mb_col < mb_cols - 1)
            assign_neighbor(&neighbors[i], mi + mi_stride + 1, 0);
        ++i;
        /* below */
        for (j = 0; j < 4; ++j, ++i)
            assign_neighbor(&neighbors[i], mi + mi_stride, j);
    }
    else
        i += 5;
    if (mb_col > 0)
    {
        /* lower left */
        if (mb_row < mb_rows - 1)
            assign_neighbor(&neighbors[i], mi + mi_stride - 1, 4);
        ++i;
        /* left */
        for (j = 3; j < 16; j += 4, ++i)
        {
            assign_neighbor(&neighbors[i], mi - 1, j);
        }
    }
    else
        i += 5;
    assert(i == 20);
}

/* Interpolates all motion vectors for a macroblock from the neighboring blocks'
 * motion vectors.
 */
static void interpolate_mvs(MACROBLOCKD *mb,
                         EC_BLOCK *neighbors,
                         MV_REFERENCE_FRAME dom_ref_frame)
{
    int row, col, i;
    MODE_INFO * const mi = mb->mode_info_context;
    /* Table with the position of the neighboring blocks relative the position
     * of the upper left block of the current MB. Starting with the upper left
     * neighbor and going to the right.
     */
    const EC_POS neigh_pos[NUM_NEIGHBORS] = {
                                        {-1,-1}, {-1,0}, {-1,1}, {-1,2}, {-1,3},
                                        {-1,4}, {0,4}, {1,4}, {2,4}, {3,4},
                                        {4,4}, {4,3}, {4,2}, {4,1}, {4,0},
                                        {4,-1}, {3,-1}, {2,-1}, {1,-1}, {0,-1}
                                      };
    mi->mbmi.need_to_clamp_mvs = 0;
    for (row = 0; row < 4; ++row)
    {
        int mb_to_top_edge = mb->mb_to_top_edge + ((row*4)<<3);
        int mb_to_bottom_edge = mb->mb_to_bottom_edge - ((row*4)<<3);
        for (col = 0; col < 4; ++col)
        {
            int mb_to_left_edge = mb->mb_to_left_edge + ((col*4)<<3);
            int mb_to_right_edge = mb->mb_to_right_edge - ((col*4)<<3);
            int w_sum = 0;
            int mv_row_sum = 0;
            int mv_col_sum = 0;
            int_mv * const mv = &(mi->bmi[row*4 + col].mv);
            mv->as_int = 0;
            for (i = 0; i < NUM_NEIGHBORS; ++i)
            {
                /* Calculate the weighted sum of neighboring MVs referring
                 * to the dominant frame type.
                 */
                const int w = weights_q7[abs(row - neigh_pos[i].row)]
                                        [abs(col - neigh_pos[i].col)];
                if (neighbors[i].ref_frame != dom_ref_frame)
                    continue;
                w_sum += w;
                /* Q7 * Q3 = Q10 */
                mv_row_sum += w*neighbors[i].mv.row;
                mv_col_sum += w*neighbors[i].mv.col;
            }
            if (w_sum > 0)
            {
                /* Avoid division by zero.
                 * Normalize with the sum of the coefficients
                 * Q3 = Q10 / Q7
                 */
                mv->as_mv.row = mv_row_sum / w_sum;
                mv->as_mv.col = mv_col_sum / w_sum;
                mi->mbmi.need_to_clamp_mvs |= vp8_check_mv_bounds(
                                                            mv,
                                                            mb_to_left_edge,
                                                            mb_to_right_edge,
                                                            mb_to_top_edge,
                                                            mb_to_bottom_edge);
            }
        }
    }
}

void vp8_interpolate_motion(MACROBLOCKD *mb,
                        int mb_row, int mb_col,
                        int mb_rows, int mb_cols,
                        int mi_stride)
{
    /* Find relevant neighboring blocks */
    EC_BLOCK neighbors[NUM_NEIGHBORS];
    int i;
    /* Initialize the array. MAX_REF_FRAMES is interpreted as "doesn't exist" */
    for (i = 0; i < NUM_NEIGHBORS; ++i)
    {
        neighbors[i].ref_frame = MAX_REF_FRAMES;
        neighbors[i].mv.row = neighbors[i].mv.col = 0;
    }
    find_neighboring_blocks(mb->mode_info_context,
                                neighbors,
                                mb_row, mb_col,
                                mb_rows, mb_cols,
                                mb->mode_info_stride);
    /* Interpolate MVs for the missing blocks from the surrounding
     * blocks which refer to the last frame. */
    interpolate_mvs(mb, neighbors, LAST_FRAME);

    mb->mode_info_context->mbmi.ref_frame = LAST_FRAME;
    mb->mode_info_context->mbmi.mode = SPLITMV;
    mb->mode_info_context->mbmi.uv_mode = DC_PRED;
    mb->mode_info_context->mbmi.partitioning = 3;
    mb->mode_info_context->mbmi.segment_id = 0;
}

void vp8_conceal_corrupt_mb(MACROBLOCKD *xd)
{
    /* This macroblock has corrupt residual, use the motion compensated
       image (predictor) for concealment */

    /* The build predictor functions now output directly into the dst buffer,
     * so the copies are no longer necessary */

}
