
/*
 *  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 = vp9_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] =
        vp9_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);
}
