/*
 *  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/header.h"
#include "encodemv.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/findnearmv.h"
#include "mcomp.h"
#include "vp8/common/systemdependent.h"
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include "vpx/vpx_encoder.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/system_state.h"
#include "bitstream.h"

#include "defaultcoefcounts.h"
#include "vp8/common/common.h"

const int vp8cx_base_skip_false_prob[128] = {
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 248, 244, 240,
  236, 232, 229, 225, 221, 217, 213, 208, 204, 199, 194, 190, 187, 183, 179,
  175, 172, 168, 164, 160, 157, 153, 149, 145, 142, 138, 134, 130, 127, 124,
  120, 117, 114, 110, 107, 104, 101, 98,  95,  92,  89,  86,  83,  80,  77,
  74,  71,  68,  65,  62,  59,  56,  53,  50,  47,  44,  41,  38,  35,  32,
  30,  28,  26,  24,  22,  20,  18,  16,
};

#if defined(SECTIONBITS_OUTPUT)
unsigned __int64 Sectionbits[500];
#endif

#ifdef MODE_STATS
int count_mb_seg[4] = { 0, 0, 0, 0 };
#endif

static void update_mode(vp8_writer *const w, int n, vp8_token tok[/* n */],
                        vp8_tree tree, vp8_prob Pnew[/* n-1 */],
                        vp8_prob Pcur[/* n-1 */],
                        unsigned int bct[/* n-1 */][2],
                        const unsigned int num_events[/* n */]) {
  unsigned int new_b = 0, old_b = 0;
  int i = 0;

  vp8_tree_probs_from_distribution(n--, tok, tree, Pnew, bct, num_events, 256,
                                   1);

  do {
    new_b += vp8_cost_branch(bct[i], Pnew[i]);
    old_b += vp8_cost_branch(bct[i], Pcur[i]);
  } while (++i < n);

  if (new_b + (n << 8) < old_b) {
    int j = 0;

    vp8_write_bit(w, 1);

    do {
      const vp8_prob p = Pnew[j];

      vp8_write_literal(w, Pcur[j] = p ? p : 1, 8);
    } while (++j < n);
  } else
    vp8_write_bit(w, 0);
}

static void update_mbintra_mode_probs(VP8_COMP *cpi) {
  VP8_COMMON *const x = &cpi->common;

  vp8_writer *const w = cpi->bc;

  {
    vp8_prob Pnew[VP8_YMODES - 1];
    unsigned int bct[VP8_YMODES - 1][2];

    update_mode(w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree, Pnew,
                x->fc.ymode_prob, bct, (unsigned int *)cpi->mb.ymode_count);
  }
  {
    vp8_prob Pnew[VP8_UV_MODES - 1];
    unsigned int bct[VP8_UV_MODES - 1][2];

    update_mode(w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, Pnew,
                x->fc.uv_mode_prob, bct, (unsigned int *)cpi->mb.uv_mode_count);
  }
}

static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
}

static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
}

static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
}

static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p) {
  vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);
}

static void write_split(vp8_writer *bc, int x) {
  vp8_write_token(bc, vp8_mbsplit_tree, vp8_mbsplit_probs,
                  vp8_mbsplit_encodings + x);
}

void vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount) {
  const TOKENEXTRA *stop = p + xcount;
  unsigned int split;
  int shift;
  int count = w->count;
  unsigned int range = w->range;
  unsigned int lowvalue = w->lowvalue;

  while (p < stop) {
    const int t = p->Token;
    vp8_token *a = vp8_coef_encodings + t;
    const vp8_extra_bit_struct *b = vp8_extra_bits + t;
    int i = 0;
    const unsigned char *pp = p->context_tree;
    int v = a->value;
    int n = a->Len;

    if (p->skip_eob_node) {
      n--;
      i = 2;
    }

    do {
      const int bb = (v >> --n) & 1;
      split = 1 + (((range - 1) * pp[i >> 1]) >> 8);
      i = vp8_coef_tree[i + bb];

      if (bb) {
        lowvalue += split;
        range = range - split;
      } else {
        range = split;
      }

      shift = vp8_norm[range];
      range <<= shift;
      count += shift;

      if (count >= 0) {
        int offset = shift - count;

        if ((lowvalue << (offset - 1)) & 0x80000000) {
          int x = w->pos - 1;

          while (x >= 0 && w->buffer[x] == 0xff) {
            w->buffer[x] = (unsigned char)0;
            x--;
          }

          w->buffer[x] += 1;
        }

        validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);

        w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff;
        lowvalue <<= offset;
        shift = count;
        lowvalue &= 0xffffff;
        count -= 8;
      }

      lowvalue <<= shift;
    } while (n);

    if (b->base_val) {
      const int e = p->Extra, L = b->Len;

      if (L) {
        const unsigned char *proba = b->prob;
        const int v2 = e >> 1;
        int n2 = L; /* number of bits in v2, assumed nonzero */
        i = 0;

        do {
          const int bb = (v2 >> --n2) & 1;
          split = 1 + (((range - 1) * proba[i >> 1]) >> 8);
          i = b->tree[i + bb];

          if (bb) {
            lowvalue += split;
            range = range - split;
          } else {
            range = split;
          }

          shift = vp8_norm[range];
          range <<= shift;
          count += shift;

          if (count >= 0) {
            int offset = shift - count;

            if ((lowvalue << (offset - 1)) & 0x80000000) {
              int x = w->pos - 1;

              while (x >= 0 && w->buffer[x] == 0xff) {
                w->buffer[x] = (unsigned char)0;
                x--;
              }

              w->buffer[x] += 1;
            }

            validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);

            w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff;
            lowvalue <<= offset;
            shift = count;
            lowvalue &= 0xffffff;
            count -= 8;
          }

          lowvalue <<= shift;
        } while (n2);
      }

      {
        split = (range + 1) >> 1;

        if (e & 1) {
          lowvalue += split;
          range = range - split;
        } else {
          range = split;
        }

        range <<= 1;

        if ((lowvalue & 0x80000000)) {
          int x = w->pos - 1;

          while (x >= 0 && w->buffer[x] == 0xff) {
            w->buffer[x] = (unsigned char)0;
            x--;
          }

          w->buffer[x] += 1;
        }

        lowvalue <<= 1;

        if (!++count) {
          count = -8;

          validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);

          w->buffer[w->pos++] = (lowvalue >> 24);
          lowvalue &= 0xffffff;
        }
      }
    }

    ++p;
  }

  w->count = count;
  w->lowvalue = lowvalue;
  w->range = range;
}

static void write_partition_size(unsigned char *cx_data, int size) {
  signed char csize;

  csize = size & 0xff;
  *cx_data = csize;
  csize = (size >> 8) & 0xff;
  *(cx_data + 1) = csize;
  csize = (size >> 16) & 0xff;
  *(cx_data + 2) = csize;
}

static void pack_tokens_into_partitions(VP8_COMP *cpi, unsigned char *cx_data,
                                        unsigned char *cx_data_end,
                                        int num_part) {
  int i;
  unsigned char *ptr = cx_data;
  unsigned char *ptr_end = cx_data_end;
  vp8_writer *w;

  for (i = 0; i < num_part; ++i) {
    int mb_row;

    w = cpi->bc + i + 1;

    vp8_start_encode(w, ptr, ptr_end);

    for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part) {
      const TOKENEXTRA *p = cpi->tplist[mb_row].start;
      const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
      int tokens = (int)(stop - p);

      vp8_pack_tokens(w, p, tokens);
    }

    vp8_stop_encode(w);
    ptr += w->pos;
  }
}

#if CONFIG_MULTITHREAD
static void pack_mb_row_tokens(VP8_COMP *cpi, vp8_writer *w) {
  int mb_row;

  for (mb_row = 0; mb_row < cpi->common.mb_rows; ++mb_row) {
    const TOKENEXTRA *p = cpi->tplist[mb_row].start;
    const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
    int tokens = (int)(stop - p);

    vp8_pack_tokens(w, p, tokens);
  }
}
#endif  // CONFIG_MULTITHREAD

static void write_mv_ref(vp8_writer *w, MB_PREDICTION_MODE m,
                         const vp8_prob *p) {
  assert(NEARESTMV <= m && m <= SPLITMV);
  vp8_write_token(w, vp8_mv_ref_tree, p,
                  vp8_mv_ref_encoding_array + (m - NEARESTMV));
}

static void write_sub_mv_ref(vp8_writer *w, B_PREDICTION_MODE m,
                             const vp8_prob *p) {
  assert(LEFT4X4 <= m && m <= NEW4X4);
  vp8_write_token(w, vp8_sub_mv_ref_tree, p,
                  vp8_sub_mv_ref_encoding_array + (m - LEFT4X4));
}

static void write_mv(vp8_writer *w, const MV *mv, const int_mv *ref,
                     const MV_CONTEXT *mvc) {
  MV e;
  e.row = mv->row - ref->as_mv.row;
  e.col = mv->col - ref->as_mv.col;

  vp8_encode_motion_vector(w, &e, mvc);
}

static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi,
                              const MACROBLOCKD *x) {
  /* Encode the MB segment id. */
  if (x->segmentation_enabled && x->update_mb_segmentation_map) {
    switch (mi->segment_id) {
      case 0:
        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
        vp8_write(w, 0, x->mb_segment_tree_probs[1]);
        break;
      case 1:
        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
        vp8_write(w, 1, x->mb_segment_tree_probs[1]);
        break;
      case 2:
        vp8_write(w, 1, x->mb_segment_tree_probs[0]);
        vp8_write(w, 0, x->mb_segment_tree_probs[2]);
        break;
      case 3:
        vp8_write(w, 1, x->mb_segment_tree_probs[0]);
        vp8_write(w, 1, x->mb_segment_tree_probs[2]);
        break;

      /* TRAP.. This should not happen */
      default:
        vp8_write(w, 0, x->mb_segment_tree_probs[0]);
        vp8_write(w, 0, x->mb_segment_tree_probs[1]);
        break;
    }
  }
}
void vp8_convert_rfct_to_prob(VP8_COMP *const cpi) {
  const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
  const int rf_intra = rfct[INTRA_FRAME];
  const int rf_inter =
      rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];

  /* Calculate the probabilities used to code the ref frame based on usage */
  if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) {
    cpi->prob_intra_coded = 1;
  }

  cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;

  if (!cpi->prob_last_coded) cpi->prob_last_coded = 1;

  cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
                           ? (rfct[GOLDEN_FRAME] * 255) /
                                 (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
                           : 128;

  if (!cpi->prob_gf_coded) cpi->prob_gf_coded = 1;
}

static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
  VP8_COMMON *const pc = &cpi->common;
  vp8_writer *const w = cpi->bc;
  const MV_CONTEXT *mvc = pc->fc.mvc;

  MODE_INFO *m = pc->mi;
  const int mis = pc->mode_info_stride;
  int mb_row = -1;

  int prob_skip_false = 0;

  cpi->mb.partition_info = cpi->mb.pi;

  vp8_convert_rfct_to_prob(cpi);

  if (pc->mb_no_coeff_skip) {
    int total_mbs = pc->mb_rows * pc->mb_cols;

    prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;

    if (prob_skip_false <= 1) prob_skip_false = 1;

    if (prob_skip_false > 255) prob_skip_false = 255;

    cpi->prob_skip_false = prob_skip_false;
    vp8_write_literal(w, prob_skip_false, 8);
  }

  vp8_write_literal(w, cpi->prob_intra_coded, 8);
  vp8_write_literal(w, cpi->prob_last_coded, 8);
  vp8_write_literal(w, cpi->prob_gf_coded, 8);

  update_mbintra_mode_probs(cpi);

  vp8_write_mvprobs(cpi);

  while (++mb_row < pc->mb_rows) {
    int mb_col = -1;

    while (++mb_col < pc->mb_cols) {
      const MB_MODE_INFO *const mi = &m->mbmi;
      const MV_REFERENCE_FRAME rf = mi->ref_frame;
      const MB_PREDICTION_MODE mode = mi->mode;

      MACROBLOCKD *xd = &cpi->mb.e_mbd;

      /* Distance of Mb to the various image edges.
       * These specified to 8th pel as they are always compared to MV
       * values that are in 1/8th pel units
       */
      xd->mb_to_left_edge = -((mb_col * 16) << 3);
      xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
      xd->mb_to_top_edge = -((mb_row * 16) << 3);
      xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;

      if (cpi->mb.e_mbd.update_mb_segmentation_map) {
        write_mb_features(w, mi, &cpi->mb.e_mbd);
      }

      if (pc->mb_no_coeff_skip) {
        vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
      }

      if (rf == INTRA_FRAME) {
        vp8_write(w, 0, cpi->prob_intra_coded);
        write_ymode(w, mode, pc->fc.ymode_prob);

        if (mode == B_PRED) {
          int j = 0;

          do {
            write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob);
          } while (++j < 16);
        }

        write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
      } else { /* inter coded */
        int_mv best_mv;
        vp8_prob mv_ref_p[VP8_MVREFS - 1];

        vp8_write(w, 1, cpi->prob_intra_coded);

        if (rf == LAST_FRAME)
          vp8_write(w, 0, cpi->prob_last_coded);
        else {
          vp8_write(w, 1, cpi->prob_last_coded);
          vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cpi->prob_gf_coded);
        }

        {
          int_mv n1, n2;
          int ct[4];

          vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf,
                            cpi->common.ref_frame_sign_bias);
          vp8_clamp_mv2(&best_mv, xd);

          vp8_mv_ref_probs(mv_ref_p, ct);
        }

        write_mv_ref(w, mode, mv_ref_p);

        switch (mode) /* new, split require MVs */
        {
          case NEWMV: write_mv(w, &mi->mv.as_mv, &best_mv, mvc); break;

          case SPLITMV: {
            int j = 0;

#ifdef MODE_STATS
            ++count_mb_seg[mi->partitioning];
#endif

            write_split(w, mi->partitioning);

            do {
              B_PREDICTION_MODE blockmode;
              int_mv blockmv;
              const int *const L = vp8_mbsplits[mi->partitioning];
              int k = -1; /* first block in subset j */
              int mv_contz;
              int_mv leftmv, abovemv;

              blockmode = cpi->mb.partition_info->bmi[j].mode;
              blockmv = cpi->mb.partition_info->bmi[j].mv;
              while (j != L[++k]) {
                assert(k < 16);
              }
              leftmv.as_int = left_block_mv(m, k);
              abovemv.as_int = above_block_mv(m, k, mis);
              mv_contz = vp8_mv_cont(&leftmv, &abovemv);

              write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2[mv_contz]);

              if (blockmode == NEW4X4) {
                write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *)mvc);
              }
            } while (++j < cpi->mb.partition_info->count);
            break;
          }
          default: break;
        }
      }

      ++m;
      cpi->mb.partition_info++;
    }

    ++m; /* skip L prediction border */
    cpi->mb.partition_info++;
  }
}

static void write_kfmodes(VP8_COMP *cpi) {
  vp8_writer *const bc = cpi->bc;
  const VP8_COMMON *const c = &cpi->common;
  /* const */
  MODE_INFO *m = c->mi;

  int mb_row = -1;
  int prob_skip_false = 0;

  if (c->mb_no_coeff_skip) {
    int total_mbs = c->mb_rows * c->mb_cols;

    prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;

    if (prob_skip_false <= 1) prob_skip_false = 1;

    if (prob_skip_false >= 255) prob_skip_false = 255;

    cpi->prob_skip_false = prob_skip_false;
    vp8_write_literal(bc, prob_skip_false, 8);
  }

  while (++mb_row < c->mb_rows) {
    int mb_col = -1;

    while (++mb_col < c->mb_cols) {
      const int ym = m->mbmi.mode;

      if (cpi->mb.e_mbd.update_mb_segmentation_map) {
        write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
      }

      if (c->mb_no_coeff_skip) {
        vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
      }

      kfwrite_ymode(bc, ym, vp8_kf_ymode_prob);

      if (ym == B_PRED) {
        const int mis = c->mode_info_stride;
        int i = 0;

        do {
          const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
          const B_PREDICTION_MODE L = left_block_mode(m, i);
          const int bm = m->bmi[i].as_mode;

          write_bmode(bc, bm, vp8_kf_bmode_prob[A][L]);
        } while (++i < 16);
      }

      write_uv_mode(bc, (m++)->mbmi.uv_mode, vp8_kf_uv_mode_prob);
    }

    m++; /* skip L prediction border */
  }
}

#if 0
/* This function is used for debugging probability trees. */
static void print_prob_tree(vp8_prob
     coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES])
{
    /* print coef probability tree */
    int i,j,k,l;
    FILE* f = fopen("enc_tree_probs.txt", "a");
    fprintf(f, "{\n");
    for (i = 0; i < BLOCK_TYPES; ++i)
    {
        fprintf(f, "  {\n");
        for (j = 0; j < COEF_BANDS; ++j)
        {
            fprintf(f, "    {\n");
            for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
            {
                fprintf(f, "      {");
                for (l = 0; l < ENTROPY_NODES; ++l)
                {
                    fprintf(f, "%3u, ",
                            (unsigned int)(coef_probs [i][j][k][l]));
                }
                fprintf(f, " }\n");
            }
            fprintf(f, "    }\n");
        }
        fprintf(f, "  }\n");
    }
    fprintf(f, "}\n");
    fclose(f);
}
#endif

static void sum_probs_over_prev_coef_context(
    const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],
    unsigned int *out) {
  int i, j;
  for (i = 0; i < MAX_ENTROPY_TOKENS; ++i) {
    for (j = 0; j < PREV_COEF_CONTEXTS; ++j) {
      const unsigned int tmp = out[i];
      out[i] += probs[j][i];
      /* check for wrap */
      if (out[i] < tmp) out[i] = UINT_MAX;
    }
  }
}

static int prob_update_savings(const unsigned int *ct, const vp8_prob oldp,
                               const vp8_prob newp, const vp8_prob upd) {
  const int old_b = vp8_cost_branch(ct, oldp);
  const int new_b = vp8_cost_branch(ct, newp);
  const int update_b = 8 + ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);

  return old_b - new_b - update_b;
}

static int independent_coef_context_savings(VP8_COMP *cpi) {
  MACROBLOCK *const x = &cpi->mb;
  int savings = 0;
  int i = 0;
  do {
    int j = 0;
    do {
      int k = 0;
      unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = { 0 };
      int prev_coef_savings[MAX_ENTROPY_TOKENS] = { 0 };
      const unsigned int(*probs)[MAX_ENTROPY_TOKENS];
      /* Calculate new probabilities given the constraint that
       * they must be equal over the prev coef contexts
       */

      probs = (const unsigned int(*)[MAX_ENTROPY_TOKENS])x->coef_counts[i][j];

      /* Reset to default probabilities at key frames */
      if (cpi->common.frame_type == KEY_FRAME) {
        probs = default_coef_counts[i][j];
      }

      sum_probs_over_prev_coef_context(probs, prev_coef_count_sum);

      do {
        /* at every context */

        /* calc probs and branch cts for this frame only */
        int t = 0; /* token/prob index */

        vp8_tree_probs_from_distribution(
            MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
            cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
            prev_coef_count_sum, 256, 1);

        do {
          const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
          const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
          const int s = prob_update_savings(ct, oldp, newp, upd);

          if (cpi->common.frame_type != KEY_FRAME ||
              (cpi->common.frame_type == KEY_FRAME && newp != oldp)) {
            prev_coef_savings[t] += s;
          }
        } while (++t < ENTROPY_NODES);
      } while (++k < PREV_COEF_CONTEXTS);
      k = 0;
      do {
        /* We only update probabilities if we can save bits, except
         * for key frames where we have to update all probabilities
         * to get the equal probabilities across the prev coef
         * contexts.
         */
        if (prev_coef_savings[k] > 0 || cpi->common.frame_type == KEY_FRAME) {
          savings += prev_coef_savings[k];
        }
      } while (++k < ENTROPY_NODES);
    } while (++j < COEF_BANDS);
  } while (++i < BLOCK_TYPES);
  return savings;
}

static int default_coef_context_savings(VP8_COMP *cpi) {
  MACROBLOCK *const x = &cpi->mb;
  int savings = 0;
  int i = 0;
  do {
    int j = 0;
    do {
      int k = 0;
      do {
        /* at every context */

        /* calc probs and branch cts for this frame only */
        int t = 0; /* token/prob index */

        vp8_tree_probs_from_distribution(
            MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
            cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
            x->coef_counts[i][j][k], 256, 1);

        do {
          const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
          const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
          const int s = prob_update_savings(ct, oldp, newp, upd);

          if (s > 0) {
            savings += s;
          }
        } while (++t < ENTROPY_NODES);
      } while (++k < PREV_COEF_CONTEXTS);
    } while (++j < COEF_BANDS);
  } while (++i < BLOCK_TYPES);
  return savings;
}

void vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra,
                              int prob_last, int prob_garf) {
  assert(prob_intra >= 0);
  assert(prob_intra <= 255);
  assert(prob_last >= 0);
  assert(prob_last <= 255);
  assert(prob_garf >= 0);
  assert(prob_garf <= 255);
  ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(prob_intra);
  ref_frame_cost[LAST_FRAME] =
      vp8_cost_one(prob_intra) + vp8_cost_zero(prob_last);
  ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(prob_intra) +
                                 vp8_cost_one(prob_last) +
                                 vp8_cost_zero(prob_garf);
  ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(prob_intra) +
                                 vp8_cost_one(prob_last) +
                                 vp8_cost_one(prob_garf);
}

int vp8_estimate_entropy_savings(VP8_COMP *cpi) {
  int savings = 0;

  const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
  const int rf_intra = rfct[INTRA_FRAME];
  const int rf_inter =
      rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
  int new_intra, new_last, new_garf, oldtotal, newtotal;
  int ref_frame_cost[MAX_REF_FRAMES];

  vpx_clear_system_state();

  if (cpi->common.frame_type != KEY_FRAME) {
    if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter))) new_intra = 1;

    new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;

    new_garf = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
                   ? (rfct[GOLDEN_FRAME] * 255) /
                         (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
                   : 128;

    vp8_calc_ref_frame_costs(ref_frame_cost, new_intra, new_last, new_garf);

    newtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
               rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
               rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
               rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];

    /* old costs */
    vp8_calc_ref_frame_costs(ref_frame_cost, cpi->prob_intra_coded,
                             cpi->prob_last_coded, cpi->prob_gf_coded);

    oldtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
               rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
               rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
               rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];

    savings += (oldtotal - newtotal) / 256;
  }

  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
    savings += independent_coef_context_savings(cpi);
  } else {
    savings += default_coef_context_savings(cpi);
  }

  return savings;
}

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
int vp8_update_coef_context(VP8_COMP *cpi) {
  int savings = 0;

  if (cpi->common.frame_type == KEY_FRAME) {
    /* Reset to default counts/probabilities at key frames */
    vp8_copy(cpi->mb.coef_counts, default_coef_counts);
  }

  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
    savings += independent_coef_context_savings(cpi);
  else
    savings += default_coef_context_savings(cpi);

  return savings;
}
#endif

void vp8_update_coef_probs(VP8_COMP *cpi) {
  int i = 0;
#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
  vp8_writer *const w = cpi->bc;
#endif
  int savings = 0;

  vpx_clear_system_state();

  do {
    int j = 0;

    do {
      int k = 0;
      int prev_coef_savings[ENTROPY_NODES] = { 0 };
      if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
        for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
          int t; /* token/prob index */
          for (t = 0; t < ENTROPY_NODES; ++t) {
            const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
            const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
            const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
            const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];

            prev_coef_savings[t] += prob_update_savings(ct, oldp, newp, upd);
          }
        }
        k = 0;
      }
      do {
        /* note: use result from vp8_estimate_entropy_savings, so no
         * need to call vp8_tree_probs_from_distribution here.
         */

        /* at every context */

        /* calc probs and branch cts for this frame only */
        int t = 0; /* token/prob index */

        do {
          const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];

          vp8_prob *Pold = cpi->common.fc.coef_probs[i][j][k] + t;
          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];

          int s = prev_coef_savings[t];
          int u = 0;

          if (!(cpi->oxcf.error_resilient_mode &
                VPX_ERROR_RESILIENT_PARTITIONS)) {
            s = prob_update_savings(cpi->frame_branch_ct[i][j][k][t], *Pold,
                                    newp, upd);
          }

          if (s > 0) u = 1;

          /* Force updates on key frames if the new is different,
           * so that we can be sure we end up with equal probabilities
           * over the prev coef contexts.
           */
          if ((cpi->oxcf.error_resilient_mode &
               VPX_ERROR_RESILIENT_PARTITIONS) &&
              cpi->common.frame_type == KEY_FRAME && newp != *Pold) {
            u = 1;
          }

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
          cpi->update_probs[i][j][k][t] = u;
#else
          vp8_write(w, u, upd);
#endif

          if (u) {
            /* send/use new probability */

            *Pold = newp;
#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
            vp8_write_literal(w, newp, 8);
#endif

            savings += s;
          }

        } while (++t < ENTROPY_NODES);

      } while (++k < PREV_COEF_CONTEXTS);
    } while (++j < COEF_BANDS);
  } while (++i < BLOCK_TYPES);
}

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
static void pack_coef_probs(VP8_COMP *cpi) {
  int i = 0;
  vp8_writer *const w = cpi->bc;

  do {
    int j = 0;

    do {
      int k = 0;

      do {
        int t = 0; /* token/prob index */

        do {
          const vp8_prob newp = cpi->common.fc.coef_probs[i][j][k][t];
          const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];

          const char u = cpi->update_probs[i][j][k][t];

          vp8_write(w, u, upd);

          if (u) {
            /* send/use new probability */
            vp8_write_literal(w, newp, 8);
          }
        } while (++t < ENTROPY_NODES);
      } while (++k < PREV_COEF_CONTEXTS);
    } while (++j < COEF_BANDS);
  } while (++i < BLOCK_TYPES);
}
#endif

#ifdef PACKET_TESTING
FILE *vpxlogc = 0;
#endif

static void put_delta_q(vp8_writer *bc, int delta_q) {
  if (delta_q != 0) {
    vp8_write_bit(bc, 1);
    vp8_write_literal(bc, abs(delta_q), 4);

    if (delta_q < 0)
      vp8_write_bit(bc, 1);
    else
      vp8_write_bit(bc, 0);
  } else
    vp8_write_bit(bc, 0);
}

void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest,
                        unsigned char *dest_end, size_t *size) {
  int i, j;
  VP8_HEADER oh;
  VP8_COMMON *const pc = &cpi->common;
  vp8_writer *const bc = cpi->bc;
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
  int extra_bytes_packed = 0;

  unsigned char *cx_data = dest;
  unsigned char *cx_data_end = dest_end;
  const int *mb_feature_data_bits;

  oh.show_frame = (int)pc->show_frame;
  oh.type = (int)pc->frame_type;
  oh.version = pc->version;
  oh.first_partition_length_in_bytes = 0;

  mb_feature_data_bits = vp8_mb_feature_data_bits;

  bc[0].error = &pc->error;

  validate_buffer(cx_data, 3, cx_data_end, &cpi->common.error);
  cx_data += 3;

#if defined(SECTIONBITS_OUTPUT)
  Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
#endif

  /* every keyframe send startcode, width, height, scale factor, clamp
   * and color type
   */
  if (oh.type == KEY_FRAME) {
    int v;

    validate_buffer(cx_data, 7, cx_data_end, &cpi->common.error);

    /* Start / synch code */
    cx_data[0] = 0x9D;
    cx_data[1] = 0x01;
    cx_data[2] = 0x2a;

    /* Pack scale and frame size into 16 bits. Store it 8 bits at a time.
     * https://tools.ietf.org/html/rfc6386
     * 9.1. Uncompressed Data Chunk
     * 16 bits      :     (2 bits Horizontal Scale << 14) | Width (14 bits)
     * 16 bits      :     (2 bits Vertical Scale << 14) | Height (14 bits)
     */
    v = (pc->horiz_scale << 14) | pc->Width;
    cx_data[3] = v & 0xff;
    cx_data[4] = v >> 8;

    v = (pc->vert_scale << 14) | pc->Height;
    cx_data[5] = v & 0xff;
    cx_data[6] = v >> 8;

    extra_bytes_packed = 7;
    cx_data += extra_bytes_packed;

    vp8_start_encode(bc, cx_data, cx_data_end);

    /* signal clr type */
    vp8_write_bit(bc, 0);
    vp8_write_bit(bc, pc->clamp_type);

  } else {
    vp8_start_encode(bc, cx_data, cx_data_end);
  }

  /* Signal whether or not Segmentation is enabled */
  vp8_write_bit(bc, xd->segmentation_enabled);

  /*  Indicate which features are enabled */
  if (xd->segmentation_enabled) {
    /* Signal whether or not the segmentation map is being updated. */
    vp8_write_bit(bc, xd->update_mb_segmentation_map);
    vp8_write_bit(bc, xd->update_mb_segmentation_data);

    if (xd->update_mb_segmentation_data) {
      signed char Data;

      vp8_write_bit(bc, xd->mb_segement_abs_delta);

      /* For each segmentation feature (Quant and loop filter level) */
      for (i = 0; i < MB_LVL_MAX; ++i) {
        /* For each of the segments */
        for (j = 0; j < MAX_MB_SEGMENTS; ++j) {
          Data = xd->segment_feature_data[i][j];

          /* Frame level data */
          if (Data) {
            vp8_write_bit(bc, 1);

            if (Data < 0) {
              Data = -Data;
              vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
              vp8_write_bit(bc, 1);
            } else {
              vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
              vp8_write_bit(bc, 0);
            }
          } else
            vp8_write_bit(bc, 0);
        }
      }
    }

    if (xd->update_mb_segmentation_map) {
      /* Write the probs used to decode the segment id for each mb */
      for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) {
        int Data = xd->mb_segment_tree_probs[i];

        if (Data != 255) {
          vp8_write_bit(bc, 1);
          vp8_write_literal(bc, Data, 8);
        } else
          vp8_write_bit(bc, 0);
      }
    }
  }

  vp8_write_bit(bc, pc->filter_type);
  vp8_write_literal(bc, pc->filter_level, 6);
  vp8_write_literal(bc, pc->sharpness_level, 3);

  /* Write out loop filter deltas applied at the MB level based on mode
   * or ref frame (if they are enabled).
   */
  vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled);

  if (xd->mode_ref_lf_delta_enabled) {
    /* Do the deltas need to be updated */
    int send_update =
        xd->mode_ref_lf_delta_update || cpi->oxcf.error_resilient_mode;

    vp8_write_bit(bc, send_update);
    if (send_update) {
      int Data;

      /* Send update */
      for (i = 0; i < MAX_REF_LF_DELTAS; ++i) {
        Data = xd->ref_lf_deltas[i];

        /* Frame level data */
        if (xd->ref_lf_deltas[i] != xd->last_ref_lf_deltas[i] ||
            cpi->oxcf.error_resilient_mode) {
          xd->last_ref_lf_deltas[i] = xd->ref_lf_deltas[i];
          vp8_write_bit(bc, 1);

          if (Data > 0) {
            vp8_write_literal(bc, (Data & 0x3F), 6);
            vp8_write_bit(bc, 0); /* sign */
          } else {
            Data = -Data;
            vp8_write_literal(bc, (Data & 0x3F), 6);
            vp8_write_bit(bc, 1); /* sign */
          }
        } else
          vp8_write_bit(bc, 0);
      }

      /* Send update */
      for (i = 0; i < MAX_MODE_LF_DELTAS; ++i) {
        Data = xd->mode_lf_deltas[i];

        if (xd->mode_lf_deltas[i] != xd->last_mode_lf_deltas[i] ||
            cpi->oxcf.error_resilient_mode) {
          xd->last_mode_lf_deltas[i] = xd->mode_lf_deltas[i];
          vp8_write_bit(bc, 1);

          if (Data > 0) {
            vp8_write_literal(bc, (Data & 0x3F), 6);
            vp8_write_bit(bc, 0); /* sign */
          } else {
            Data = -Data;
            vp8_write_literal(bc, (Data & 0x3F), 6);
            vp8_write_bit(bc, 1); /* sign */
          }
        } else
          vp8_write_bit(bc, 0);
      }
    }
  }

  /* signal here is multi token partition is enabled */
  vp8_write_literal(bc, pc->multi_token_partition, 2);

  /* Frame Qbaseline quantizer index */
  vp8_write_literal(bc, pc->base_qindex, 7);

  /* Transmit Dc, Second order and Uv quantizer delta information */
  put_delta_q(bc, pc->y1dc_delta_q);
  put_delta_q(bc, pc->y2dc_delta_q);
  put_delta_q(bc, pc->y2ac_delta_q);
  put_delta_q(bc, pc->uvdc_delta_q);
  put_delta_q(bc, pc->uvac_delta_q);

  /* When there is a key frame all reference buffers are updated using
   * the new key frame
   */
  if (pc->frame_type != KEY_FRAME) {
    /* Should the GF or ARF be updated using the transmitted frame
     * or buffer
     */
    vp8_write_bit(bc, pc->refresh_golden_frame);
    vp8_write_bit(bc, pc->refresh_alt_ref_frame);

    /* If not being updated from current frame should either GF or ARF
     * be updated from another buffer
     */
    if (!pc->refresh_golden_frame)
      vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);

    if (!pc->refresh_alt_ref_frame)
      vp8_write_literal(bc, pc->copy_buffer_to_arf, 2);

    /* Indicate reference frame sign bias for Golden and ARF frames
     * (always 0 for last frame buffer)
     */
    vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
    vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
  }

#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
  if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
    if (pc->frame_type == KEY_FRAME) {
      pc->refresh_entropy_probs = 1;
    } else {
      pc->refresh_entropy_probs = 0;
    }
  }
#endif

  vp8_write_bit(bc, pc->refresh_entropy_probs);

  if (pc->frame_type != KEY_FRAME) vp8_write_bit(bc, pc->refresh_last_frame);

  vpx_clear_system_state();

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
  pack_coef_probs(cpi);
#else
  if (pc->refresh_entropy_probs == 0) {
    /* save a copy for later refresh */
    memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
  }

  vp8_update_coef_probs(cpi);
#endif

  /* Write out the mb_no_coeff_skip flag */
  vp8_write_bit(bc, pc->mb_no_coeff_skip);

  if (pc->frame_type == KEY_FRAME) {
    write_kfmodes(cpi);
  } else {
    pack_inter_mode_mvs(cpi);
  }

  vp8_stop_encode(bc);

  cx_data += bc->pos;

  oh.first_partition_length_in_bytes = cpi->bc->pos;

  /* update frame tag */
  {
    /* Pack partition size, show frame, version and frame type into to 24 bits.
     * Store it 8 bits at a time.
     * https://tools.ietf.org/html/rfc6386
     * 9.1. Uncompressed Data Chunk
     *    The uncompressed data chunk comprises a common (for key frames and
     *    interframes) 3-byte frame tag that contains four fields, as follows:
     *
     *    1.  A 1-bit frame type (0 for key frames, 1 for interframes).
     *
     *    2.  A 3-bit version number (0 - 3 are defined as four different
     *        profiles with different decoding complexity; other values may be
     *        defined for future variants of the VP8 data format).
     *
     *    3.  A 1-bit show_frame flag (0 when current frame is not for display,
     *        1 when current frame is for display).
     *
     *    4.  A 19-bit field containing the size of the first data partition in
     *        bytes
     */
    int v = (oh.first_partition_length_in_bytes << 5) | (oh.show_frame << 4) |
            (oh.version << 1) | oh.type;

    dest[0] = v & 0xff;
    dest[1] = (v >> 8) & 0xff;
    dest[2] = v >> 16;
  }

  *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc->pos;

  cpi->partition_sz[0] = (unsigned int)*size;

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
  {
    const int num_part = (1 << pc->multi_token_partition);
    unsigned char *dp = cpi->partition_d[0] + cpi->partition_sz[0];

    if (num_part > 1) {
      /* write token part sizes (all but last) if more than 1 */
      validate_buffer(dp, 3 * (num_part - 1), cpi->partition_d_end[0],
                      &pc->error);

      cpi->partition_sz[0] += 3 * (num_part - 1);

      for (i = 1; i < num_part; ++i) {
        write_partition_size(dp, cpi->partition_sz[i]);
        dp += 3;
      }
    }

    if (!cpi->output_partition) {
      /* concatenate partition buffers */
      for (i = 0; i < num_part; ++i) {
        memmove(dp, cpi->partition_d[i + 1], cpi->partition_sz[i + 1]);
        cpi->partition_d[i + 1] = dp;
        dp += cpi->partition_sz[i + 1];
      }
    }

    /* update total size */
    *size = 0;
    for (i = 0; i < num_part + 1; ++i) {
      *size += cpi->partition_sz[i];
    }
  }
#else
  if (pc->multi_token_partition != ONE_PARTITION) {
    int num_part = 1 << pc->multi_token_partition;

    /* partition size table at the end of first partition */
    cpi->partition_sz[0] += 3 * (num_part - 1);
    *size += 3 * (num_part - 1);

    validate_buffer(cx_data, 3 * (num_part - 1), cx_data_end, &pc->error);

    for (i = 1; i < num_part + 1; ++i) {
      cpi->bc[i].error = &pc->error;
    }

    pack_tokens_into_partitions(cpi, cx_data + 3 * (num_part - 1), cx_data_end,
                                num_part);

    for (i = 1; i < num_part; ++i) {
      cpi->partition_sz[i] = cpi->bc[i].pos;
      write_partition_size(cx_data, cpi->partition_sz[i]);
      cx_data += 3;
      *size += cpi->partition_sz[i]; /* add to total */
    }

    /* add last partition to total size */
    cpi->partition_sz[i] = cpi->bc[i].pos;
    *size += cpi->partition_sz[i];
  } else {
    bc[1].error = &pc->error;

    vp8_start_encode(&cpi->bc[1], cx_data, cx_data_end);

#if CONFIG_MULTITHREAD
    if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) {
      pack_mb_row_tokens(cpi, &cpi->bc[1]);
    } else {
      vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
    }
#else
    vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
#endif  // CONFIG_MULTITHREAD

    vp8_stop_encode(&cpi->bc[1]);

    *size += cpi->bc[1].pos;
    cpi->partition_sz[1] = cpi->bc[1].pos;
  }
#endif
}
