
/*
 *  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.
 */

#include "vp8/common/pred_common.h"
#include "vp8/common/seg_common.h"

// TBD prediction functions for various bitstream signals

// Returns a context number for the given MB prediction signal
unsigned char vp9_get_pred_context(const VP8_COMMON *const cm,
                                   const MACROBLOCKD *const xd,
                                   PRED_ID pred_id) {
  int pred_context;
  MODE_INFO *m = xd->mode_info_context;

  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  switch (pred_id) {
    case PRED_SEG_ID:
      pred_context = (m - 1)->mbmi.seg_id_predicted +
                     (m - cm->mode_info_stride)->mbmi.seg_id_predicted;
      break;


    case PRED_REF:
      pred_context = (m - 1)->mbmi.ref_predicted +
                     (m - cm->mode_info_stride)->mbmi.ref_predicted;
      break;

    case PRED_COMP:
      // Context based on use of comp pred flag by neighbours
      // pred_context =
      //   ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) +
      //    ((m - cm->mode_info_stride)->mbmi.second_ref_frame != INTRA_FRAME);

      // Context based on mode and reference frame
      // if ( m->mbmi.ref_frame == LAST_FRAME )
      //    pred_context = 0 + (m->mbmi.mode != ZEROMV);
      // else if ( m->mbmi.ref_frame == GOLDEN_FRAME )
      //    pred_context = 2 + (m->mbmi.mode != ZEROMV);
      // else
      //    pred_context = 4 + (m->mbmi.mode != ZEROMV);

      if (m->mbmi.ref_frame == LAST_FRAME)
        pred_context = 0;
      else
        pred_context = 1;

      break;

    case PRED_MBSKIP:
      pred_context = (m - 1)->mbmi.mb_skip_coeff +
                     (m - cm->mode_info_stride)->mbmi.mb_skip_coeff;
      break;

    case PRED_SWITCHABLE_INTERP:
      {
        int left_in_image = (m - 1)->mbmi.mb_in_image;
        int above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
        int left_mode = (m - 1)->mbmi.mode;
        int above_mode = (m - cm->mode_info_stride)->mbmi.mode;
        int left_interp, above_interp;
        if (left_in_image && left_mode >= NEARESTMV && left_mode <= SPLITMV)
          left_interp = vp8_switchable_interp_map[(m - 1)->mbmi.interp_filter];
        else
          left_interp = VP8_SWITCHABLE_FILTERS;
        if (above_in_image && above_mode >= NEARESTMV && above_mode <= SPLITMV)
          above_interp = vp8_switchable_interp_map[
              (m - cm->mode_info_stride)->mbmi.interp_filter];
        else
          above_interp = VP8_SWITCHABLE_FILTERS;

        if (left_interp == above_interp)
          pred_context = left_interp;
        else if (left_interp == VP8_SWITCHABLE_FILTERS &&
                 above_interp != VP8_SWITCHABLE_FILTERS)
          pred_context = above_interp;
        else if (left_interp != VP8_SWITCHABLE_FILTERS &&
                 above_interp == VP8_SWITCHABLE_FILTERS)
          pred_context = left_interp;
        else
          pred_context = VP8_SWITCHABLE_FILTERS;
      }
      break;

    default:
      // TODO *** add error trap code.
      pred_context = 0;
      break;
  }

  return pred_context;
}

// This function returns a context probability for coding a given
// prediction signal
vp8_prob vp9_get_pred_prob(const VP8_COMMON *const cm,
                          const MACROBLOCKD *const xd,
                          PRED_ID pred_id) {
  vp8_prob pred_probability;
  int pred_context;

  // Get the appropriate prediction context
  pred_context = vp9_get_pred_context(cm, xd, pred_id);

  switch (pred_id) {
    case PRED_SEG_ID:
      pred_probability = cm->segment_pred_probs[pred_context];
      break;

    case PRED_REF:
      pred_probability = cm->ref_pred_probs[pred_context];
      break;

    case PRED_COMP:
      // In keeping with convention elsewhre the probability returned is
      // the probability of a "0" outcome which in this case means the
      // probability of comp pred off.
      pred_probability = cm->prob_comppred[pred_context];
      break;

    case PRED_MBSKIP:
      pred_probability = cm->mbskip_pred_probs[pred_context];
      break;

    default:
      // TODO *** add error trap code.
      pred_probability = 128;
      break;
  }

  return pred_probability;
}

// This function returns a context probability ptr for coding a given
// prediction signal
const vp8_prob *vp9_get_pred_probs(const VP8_COMMON *const cm,
                                   const MACROBLOCKD *const xd,
                                   PRED_ID pred_id) {
  const vp8_prob *pred_probability;
  int pred_context;

  // Get the appropriate prediction context
  pred_context = vp9_get_pred_context(cm, xd, pred_id);

  switch (pred_id) {
    case PRED_SEG_ID:
      pred_probability = &cm->segment_pred_probs[pred_context];
      break;

    case PRED_REF:
      pred_probability = &cm->ref_pred_probs[pred_context];
      break;

    case PRED_COMP:
      // In keeping with convention elsewhre the probability returned is
      // the probability of a "0" outcome which in this case means the
      // probability of comp pred off.
      pred_probability = &cm->prob_comppred[pred_context];
      break;

    case PRED_MBSKIP:
      pred_probability = &cm->mbskip_pred_probs[pred_context];
      break;

    case PRED_SWITCHABLE_INTERP:
      pred_probability = &cm->fc.switchable_interp_prob[pred_context][0];
      break;

    default:
      // TODO *** add error trap code.
      pred_probability = NULL;
      break;
  }

  return pred_probability;
}

// This function returns the status of the given prediction signal.
// I.e. is the predicted value for the given signal correct.
unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd,
                                PRED_ID pred_id) {
  unsigned char pred_flag = 0;

  switch (pred_id) {
    case PRED_SEG_ID:
      pred_flag = xd->mode_info_context->mbmi.seg_id_predicted;
      break;

    case PRED_REF:
      pred_flag = xd->mode_info_context->mbmi.ref_predicted;
      break;

    case PRED_MBSKIP:
      pred_flag = xd->mode_info_context->mbmi.mb_skip_coeff;
      break;

    default:
      // TODO *** add error trap code.
      pred_flag = 0;
      break;
  }

  return pred_flag;
}

// This function sets the status of the given prediction signal.
// I.e. is the predicted value for the given signal correct.
void vp9_set_pred_flag(MACROBLOCKD *const xd,
                       PRED_ID pred_id,
                       unsigned char pred_flag) {
#if CONFIG_SUPERBLOCKS
  const int mis = xd->mode_info_stride;
#endif

  switch (pred_id) {
    case PRED_SEG_ID:
      xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
      if (xd->mode_info_context->mbmi.encoded_as_sb) {
        if (xd->mb_to_right_edge > 0)
          xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
        if (xd->mb_to_bottom_edge > 0) {
          xd->mode_info_context[mis].mbmi.seg_id_predicted = pred_flag;
          if (xd->mb_to_right_edge > 0)
            xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
        }
      }
#endif
      break;

    case PRED_REF:
      xd->mode_info_context->mbmi.ref_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
      if (xd->mode_info_context->mbmi.encoded_as_sb) {
        if (xd->mb_to_right_edge > 0)
          xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
        if (xd->mb_to_bottom_edge > 0) {
          xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
          if (xd->mb_to_right_edge > 0)
            xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
        }
      }
#endif
      break;

    case PRED_MBSKIP:
      xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
#if CONFIG_SUPERBLOCKS
      if (xd->mode_info_context->mbmi.encoded_as_sb) {
        if (xd->mb_to_right_edge > 0)
          xd->mode_info_context[1].mbmi.mb_skip_coeff = pred_flag;
        if (xd->mb_to_bottom_edge > 0) {
          xd->mode_info_context[mis].mbmi.mb_skip_coeff = pred_flag;
          if (xd->mb_to_right_edge > 0)
            xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
        }
      }
#endif
      break;

    default:
      // TODO *** add error trap code.
      break;
  }
}


// The following contain the guts of the prediction code used to
// peredict various bitstream signals.

// Macroblock segment id prediction function
unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
                                    const MACROBLOCKD *const xd, int MbIndex) {
  // Currently the prediction for the macroblock segment ID is
  // the value stored for this macroblock in the previous frame.
#if CONFIG_SUPERBLOCKS
  if (!xd->mode_info_context->mbmi.encoded_as_sb) {
#endif
    return cm->last_frame_seg_map[MbIndex];
#if CONFIG_SUPERBLOCKS
  } else {
    int seg_id = cm->last_frame_seg_map[MbIndex];
    int mb_col = MbIndex % cm->mb_cols;
    int mb_row = MbIndex / cm->mb_cols;
    if (mb_col + 1 < cm->mb_cols)
      seg_id = seg_id && cm->last_frame_seg_map[MbIndex + 1];
    if (mb_row + 1 < cm->mb_rows) {
      seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols];
      if (mb_col + 1 < cm->mb_cols)
        seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols + 1];
    }
    return seg_id;
  }
#endif
}

MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
                                    const MACROBLOCKD *const xd) {
  MODE_INFO *m = xd->mode_info_context;

  MV_REFERENCE_FRAME left;
  MV_REFERENCE_FRAME above;
  MV_REFERENCE_FRAME above_left;
  MV_REFERENCE_FRAME pred_ref = LAST_FRAME;

  int segment_id = xd->mode_info_context->mbmi.segment_id;
  int seg_ref_active;
  int i;

  unsigned char frame_allowed[MAX_REF_FRAMES] = {1, 1, 1, 1};
  unsigned char ref_score[MAX_REF_FRAMES];
  unsigned char best_score = 0;
  unsigned char left_in_image;
  unsigned char above_in_image;
  unsigned char above_left_in_image;

  // Is segment coding ennabled
  seg_ref_active = segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);

  // Special case treatment if segment coding is enabled.
  // Dont allow prediction of a reference frame that the segment
  // does not allow
  if (seg_ref_active) {
    for (i = 0; i < MAX_REF_FRAMES; i++) {
      frame_allowed[i] =
        check_segref(xd, segment_id, i);

      // Score set to 0 if ref frame not allowed
      ref_score[i] = cm->ref_scores[i] * frame_allowed[i];
    }
  } else
    vpx_memcpy(ref_score, cm->ref_scores, sizeof(ref_score));

  // Reference frames used by neighbours
  left = (m - 1)->mbmi.ref_frame;
  above = (m - cm->mode_info_stride)->mbmi.ref_frame;
  above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;

  // Are neighbours in image
  left_in_image = (m - 1)->mbmi.mb_in_image;
  above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
  above_left_in_image = (m - 1 - cm->mode_info_stride)->mbmi.mb_in_image;

  // Adjust scores for candidate reference frames based on neigbours
  if (frame_allowed[left] && left_in_image) {
    ref_score[left] += 16;
    if (above_left_in_image && (left == above_left))
      ref_score[left] += 4;
  }
  if (frame_allowed[above] && above_in_image) {
    ref_score[above] += 16;
    if (above_left_in_image && (above == above_left))
      ref_score[above] += 4;
  }

  // Now choose the candidate with the highest score
  for (i = 0; i < MAX_REF_FRAMES; i++) {
    if (ref_score[i] > best_score) {
      pred_ref = i;
      best_score = ref_score[i];
    }
  }

  return pred_ref;
}

// Functions to computes a set of modified reference frame probabilities
// to use when the prediction of the reference frame value fails
void vp9_calc_ref_probs(int *count, vp8_prob *probs) {
  int tot_count;

  tot_count = count[0] + count[1] + count[2] + count[3];
  if (tot_count) {
    probs[0] = (vp8_prob)((count[0] * 255 + (tot_count >> 1)) / tot_count);
    probs[0] += !probs[0];
  } else
    probs[0] = 128;

  tot_count -= count[0];
  if (tot_count) {
    probs[1] = (vp8_prob)((count[1] * 255 + (tot_count >> 1)) / tot_count);
    probs[1] += !probs[1];
  } else
    probs[1] = 128;

  tot_count -= count[1];
  if (tot_count) {
    probs[2] = (vp8_prob)((count[2] * 255 + (tot_count >> 1)) / tot_count);
    probs[2] += !probs[2];
  } else
    probs[2] = 128;

}

// Computes a set of modified conditional probabilities for the reference frame
// Values willbe set to 0 for reference frame options that are not possible
// because wither they were predicted and prediction has failed or because
// they are not allowed for a given segment.
void vp9_compute_mod_refprobs(VP8_COMMON *const cm) {
  int norm_cnt[MAX_REF_FRAMES];
  int intra_count;
  int inter_count;
  int last_count;
  int gfarf_count;
  int gf_count;
  int arf_count;

  intra_count = cm->prob_intra_coded;
  inter_count = (255 - intra_count);
  last_count = (inter_count * cm->prob_last_coded) / 255;
  gfarf_count = inter_count - last_count;
  gf_count = (gfarf_count * cm->prob_gf_coded) / 255;
  arf_count = gfarf_count - gf_count;

  // Work out modified reference frame probabilities to use where prediction
  // of the reference frame fails
  norm_cnt[0] = 0;
  norm_cnt[1] = last_count;
  norm_cnt[2] = gf_count;
  norm_cnt[3] = arf_count;
  vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[INTRA_FRAME]);
  cm->mod_refprobs[INTRA_FRAME][0] = 0;    // This branch implicit

  norm_cnt[0] = intra_count;
  norm_cnt[1] = 0;
  norm_cnt[2] = gf_count;
  norm_cnt[3] = arf_count;
  vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[LAST_FRAME]);
  cm->mod_refprobs[LAST_FRAME][1] = 0;    // This branch implicit

  norm_cnt[0] = intra_count;
  norm_cnt[1] = last_count;
  norm_cnt[2] = 0;
  norm_cnt[3] = arf_count;
  vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[GOLDEN_FRAME]);
  cm->mod_refprobs[GOLDEN_FRAME][2] = 0;  // This branch implicit

  norm_cnt[0] = intra_count;
  norm_cnt[1] = last_count;
  norm_cnt[2] = gf_count;
  norm_cnt[3] = 0;
  vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[ALTREF_FRAME]);
  cm->mod_refprobs[ALTREF_FRAME][2] = 0;  // This branch implicit

  // Score the reference frames based on overal frequency.
  // These scores contribute to the prediction choices.
  // Max score 17 min 1
  cm->ref_scores[INTRA_FRAME] = 1 + (intra_count * 16 / 255);
  cm->ref_scores[LAST_FRAME] = 1 + (last_count * 16 / 255);
  cm->ref_scores[GOLDEN_FRAME] = 1 + (gf_count * 16 / 255);
  cm->ref_scores[ALTREF_FRAME] = 1 + (arf_count * 16 / 255);
}
