Merge "Allow OVERLAY frames to use the show_exsiting_frame flag" into nextgenv2
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h
index 6314e05..4c46cbb 100644
--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -388,6 +388,9 @@
   int corrupted;
 
   struct vpx_internal_error_info *error_info;
+#if CONFIG_GLOBAL_MOTION
+  Global_Motion_Params *global_motion;
+#endif  // CONFIG_GLOBAL_MOTION
 } MACROBLOCKD;
 
 static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h
index 71e79d9..a898038 100644
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -118,6 +118,9 @@
   vpx_prob ext_intra_probs[PLANE_TYPES];
   vpx_prob intra_filter_probs[INTRA_FILTERS + 1][INTRA_FILTERS - 1];
 #endif  // CONFIG_EXT_INTRA
+#if CONFIG_GLOBAL_MOTION
+  vpx_prob global_motion_types_prob[GLOBAL_MOTION_TYPES - 1];
+#endif  // CONFIG_GLOBAL_MOTION
 } FRAME_CONTEXT;
 
 typedef struct FRAME_COUNTS {
diff --git a/vp10/common/entropymv.c b/vp10/common/entropymv.c
index 87c6421..ae6209d 100644
--- a/vp10/common/entropymv.c
+++ b/vp10/common/entropymv.c
@@ -120,6 +120,17 @@
   9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
 };
 
+#if CONFIG_GLOBAL_MOTION
+const vpx_tree_index vp10_global_motion_types_tree
+          [TREE_SIZE(GLOBAL_MOTION_TYPES)] = {
+          -GLOBAL_ZERO, 2,
+          -GLOBAL_TRANSLATION, -GLOBAL_ROTZOOM
+};
+
+static const vpx_prob default_global_motion_types_prob
+                 [GLOBAL_MOTION_TYPES - 1] = {224, 128};
+#endif  // CONFIG_GLOBAL_MOTION
+
 static INLINE int mv_class_base(MV_CLASS_TYPE c) {
   return c ? CLASS0_SIZE << (c + 2) : 0;
 }
@@ -277,4 +288,7 @@
 #else
   cm->fc->nmvc = default_nmv_context;
 #endif
+#if CONFIG_GLOBAL_MOTION
+  vp10_copy(cm->fc->global_motion_types_prob, default_global_motion_types_prob);
+#endif  // CONFIG_GLOBAL_MOTION
 }
diff --git a/vp10/common/entropymv.h b/vp10/common/entropymv.h
index f8ade34..af69a2d 100644
--- a/vp10/common/entropymv.h
+++ b/vp10/common/entropymv.h
@@ -132,6 +132,11 @@
 
 void vp10_inc_mv(const MV *mv, nmv_context_counts *mvctx, const int usehp);
 
+#if CONFIG_GLOBAL_MOTION
+extern const vpx_tree_index vp10_global_motion_types_tree
+                             [TREE_SIZE(GLOBAL_MOTION_TYPES)];
+#endif  // CONFIG_GLOBAL_MOTION
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/vp10/common/mv.h b/vp10/common/mv.h
index 8b9348b..255a724 100644
--- a/vp10/common/mv.h
+++ b/vp10/common/mv.h
@@ -13,6 +13,9 @@
 
 #include "vp10/common/common.h"
 #include "vpx_dsp/vpx_filter.h"
+#if CONFIG_GLOBAL_MOTION
+#include "vp10/common/warped_motion.h"
+#endif  // CONFIG_GLOBAL_MOTION
 
 #ifdef __cplusplus
 extern "C" {
@@ -33,6 +36,64 @@
   int32_t col;
 } MV32;
 
+#if CONFIG_GLOBAL_MOTION
+// ALPHA here refers to parameters a and b in rotzoom model:
+// | a   b|
+// |-b   a|
+//
+// Anything ending in PREC_BITS is the number of bits of precision
+// to maintain when converting from double to integer.
+//
+// The ABS parameters are used to create an upper and lower bound
+// for each parameter. In other words, after a parameter is integerized
+// it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS)
+//
+// XXX_PREC_DIFF and XXX_DECODE_FACTOR are computed once here to
+// prevent repetetive computation on the decoder side. These are
+// to allow the global motion parameters to be encoded in a lower
+// precision than the warped model precision. This means that they
+// need to be changed to warped precision when they are decoded.
+//
+// XX_MIN, XX_MAX are also computed to avoid repeated computation
+
+#define GM_TRANS_PREC_BITS        3
+#define GM_TRANS_PREC_DIFF        (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
+#define GM_TRANS_DECODE_FACTOR    (1 << GM_TRANS_PREC_DIFF)
+
+#define GM_ALPHA_PREC_BITS        5
+#define GM_ALPHA_PREC_DIFF        (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
+#define GM_ALPHA_DECODE_FACTOR    (1 << GM_ALPHA_PREC_DIFF)
+
+#define GM_ABS_ALPHA_BITS         5
+#define GM_ABS_TRANS_BITS         5
+
+#define GM_TRANS_MAX              (1 << GM_ABS_TRANS_BITS)
+#define GM_ALPHA_MAX              (1 << GM_ABS_ALPHA_BITS)
+#define GM_TRANS_MIN              -GM_TRANS_MAX
+#define GM_ALPHA_MIN              -GM_ALPHA_MAX
+
+typedef enum {
+  GLOBAL_ZERO = 0,
+  GLOBAL_TRANSLATION = 1,
+  GLOBAL_ROTZOOM = 2,
+  GLOBAL_MOTION_TYPES
+} GLOBAL_MOTION_TYPE;
+
+typedef struct {
+  GLOBAL_MOTION_TYPE gmtype;
+  WarpedMotionParams motion_params;
+} Global_Motion_Params;
+
+static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) {
+  if (gm->motion_params.wmmat[2] == 0 && gm->motion_params.wmmat[3] == 0) {
+    return ((gm->motion_params.wmmat[0] | gm->motion_params.wmmat[1]) ?
+            GLOBAL_TRANSLATION : GLOBAL_ZERO);
+  } else {
+    return GLOBAL_ROTZOOM;
+  }
+}
+#endif  // CONFIG_GLOBAL_MOTION
+
 #if CONFIG_REF_MV
 typedef struct candidate_mv {
   int_mv this_mv;
diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h
index b2d65b5..37f7631 100644
--- a/vp10/common/onyxc_int.h
+++ b/vp10/common/onyxc_int.h
@@ -350,6 +350,9 @@
   // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
   // each keyframe and not used afterwards
   vpx_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
+#if CONFIG_GLOBAL_MOTION
+  Global_Motion_Params global_motion[MAX_REF_FRAMES];
+#endif
 
   BLOCK_SIZE sb_size;   // Size of the superblock used for this frame
   int mib_size;         // Size of the superblock in units of MI blocks
diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c
index d4c7d5e..66b44a3 100644
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -3443,6 +3443,55 @@
 }
 #endif  // CONFIG_SUPERTX
 
+#if CONFIG_GLOBAL_MOTION
+static void read_global_motion_params(Global_Motion_Params *params,
+                                      vpx_prob *probs,
+                                      vp10_reader *r) {
+  GLOBAL_MOTION_TYPE gmtype = vp10_read_tree(r, vp10_global_motion_types_tree,
+                                             probs);
+  params->gmtype = gmtype;
+  switch (gmtype) {
+    case GLOBAL_ZERO:
+      break;
+    case GLOBAL_TRANSLATION:
+      params->motion_params.wmtype = TRANSLATION;
+      params->motion_params.wmmat[0] =
+          vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
+          GM_TRANS_DECODE_FACTOR;
+      params->motion_params.wmmat[1] =
+          vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
+          GM_TRANS_DECODE_FACTOR;
+      break;
+    case GLOBAL_ROTZOOM:
+      params->motion_params.wmtype = ROTZOOM;
+      params->motion_params.wmmat[2] =
+          vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
+          GM_TRANS_DECODE_FACTOR;
+      params->motion_params.wmmat[3] =
+          vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
+          GM_TRANS_DECODE_FACTOR;
+      params->motion_params.wmmat[0] =
+          (vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+          GM_ALPHA_DECODE_FACTOR) + (1 << WARPEDMODEL_PREC_BITS);
+      params->motion_params.wmmat[1] =
+          vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+          GM_ALPHA_DECODE_FACTOR;
+      break;
+    default:
+      assert(0);
+  }
+}
+
+static void read_global_motion(VP10_COMMON *cm, vp10_reader *r) {
+  int frame;
+  memset(cm->global_motion, 0, sizeof(cm->global_motion));
+  for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
+    read_global_motion_params(
+        &cm->global_motion[frame], cm->fc->global_motion_types_prob, r);
+  }
+}
+#endif  // CONFIG_GLOBAL_MOTION
+
 static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
                                   size_t partition_size) {
   VP10_COMMON *const cm = &pbi->common;
@@ -3585,6 +3634,9 @@
     if (!xd->lossless[0])
       read_supertx_probs(fc, &r);
 #endif
+#if CONFIG_GLOBAL_MOTION
+    read_global_motion(cm, &r);
+#endif  // CONFIG_GLOBAL_MOTION
   }
 
   return vp10_reader_has_error(&r);
@@ -3714,6 +3766,9 @@
       init_read_bit_buffer(pbi, &rb, data, data_end, clear_data));
   YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm);
   xd->cur_buf = new_fb;
+#if CONFIG_GLOBAL_MOTION
+  xd->global_motion = cm->global_motion;
+#endif  // CONFIG_GLOBAL_MOTION
 
   if (!first_partition_size) {
     // showing a frame directly
diff --git a/vp10/decoder/dsubexp.c b/vp10/decoder/dsubexp.c
index 4d53e12..49695cc 100644
--- a/vp10/decoder/dsubexp.c
+++ b/vp10/decoder/dsubexp.c
@@ -74,3 +74,13 @@
     *p = (vpx_prob)inv_remap_prob(delp, *p);
   }
 }
+
+int vp10_read_primitive_symmetric(vp10_reader *r, unsigned int mag_bits) {
+  if (vp10_read_bit(r)) {
+    int s = vp10_read_bit(r);
+    int x = vp10_read_literal(r, mag_bits) + 1;
+    return (s > 0 ? -x : x);
+  } else {
+    return 0;
+  }
+}
diff --git a/vp10/decoder/dsubexp.h b/vp10/decoder/dsubexp.h
index c05ec6e..eaccf1f 100644
--- a/vp10/decoder/dsubexp.h
+++ b/vp10/decoder/dsubexp.h
@@ -24,4 +24,9 @@
 }  // extern "C"
 #endif
 
+// mag_bits is number of bits for magnitude. The alphabet is of size
+// 2 * 2^mag_bits + 1, symmetric around 0, where one bit is used to
+// indicate 0 or non-zero, mag_bits bits are used to indicate magnitide
+// and 1 more bit for the sign if non-zero.
+int vp10_read_primitive_symmetric(vp10_reader *r, unsigned int mag_bits);
 #endif  // VP10_DECODER_DSUBEXP_H_
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index 4ef16a8..6430a710 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -111,6 +111,9 @@
 #else
 static struct vp10_token ext_tx_encodings[TX_TYPES];
 #endif  // CONFIG_EXT_TX
+#if CONFIG_GLOBAL_MOTION
+static struct vp10_token global_motion_types_encodings[GLOBAL_MOTION_TYPES];
+#endif  // CONFIG_GLOBAL_MOTION
 #if CONFIG_EXT_INTRA
 static struct vp10_token intra_filter_encodings[INTRA_FILTERS];
 #endif  // CONFIG_EXT_INTRA
@@ -142,6 +145,10 @@
 #if CONFIG_OBMC || CONFIG_WARPED_MOTION
   vp10_tokens_from_tree(motvar_encodings, vp10_motvar_tree);
 #endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
+#if CONFIG_GLOBAL_MOTION
+  vp10_tokens_from_tree(global_motion_types_encodings,
+                       vp10_global_motion_types_tree);
+#endif  // CONFIG_GLOBAL_MOTION
 }
 
 static void write_intra_mode(vp10_writer *w, PREDICTION_MODE mode,
@@ -3180,6 +3187,50 @@
 
   write_tile_info(cm, wb);
 }
+#if CONFIG_GLOBAL_MOTION
+static void write_global_motion_params(Global_Motion_Params *params,
+                                       vpx_prob *probs,
+                                       vp10_writer *w) {
+  GLOBAL_MOTION_TYPE gmtype = get_gmtype(params);
+  vp10_write_token(w, vp10_global_motion_types_tree, probs,
+                  &global_motion_types_encodings[gmtype]);
+  switch (gmtype) {
+    case GLOBAL_ZERO:
+      break;
+    case GLOBAL_TRANSLATION:
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0],
+                                     GM_ABS_TRANS_BITS);
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1],
+                                     GM_ABS_TRANS_BITS);
+      break;
+    case GLOBAL_ROTZOOM:
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0],
+                                     GM_ABS_TRANS_BITS);
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1],
+                                     GM_ABS_TRANS_BITS);
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[2],
+                                     GM_ABS_ALPHA_BITS);
+      vp10_write_primitive_symmetric(w, params->motion_params.wmmat[3],
+                                     GM_ABS_ALPHA_BITS);
+      break;
+    default:
+      assert(0);
+  }
+}
+
+static void write_global_motion(VP10_COMP *cpi, vp10_writer *w) {
+  VP10_COMMON *const cm = &cpi->common;
+  int frame;
+  for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
+    if (!cpi->global_motion_used[frame]) {
+      memset(&cm->global_motion[frame], 0,
+             sizeof(*cm->global_motion));
+    }
+      write_global_motion_params(
+          &cm->global_motion[frame], cm->fc->global_motion_types_prob, w);
+  }
+}
+#endif
 
 static uint32_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
   VP10_COMMON *const cm = &cpi->common;
@@ -3348,7 +3399,9 @@
       update_supertx_probs(cm, header_bc);
 #endif  // CONFIG_SUPERTX
   }
-
+#if CONFIG_GLOBAL_MOTION
+  write_global_motion(cpi, header_bc);
+#endif  // CONFIG_GLOBAL_MOTION
 #if CONFIG_ANS
   ans_write_init(&header_ans, data);
   buf_ans_flush(header_bc, &header_ans);
diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c
index 3119acf..b91615b 100644
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -4536,6 +4536,78 @@
 }
 #endif
 
+#if CONFIG_GLOBAL_MOTION
+#define MIN_TRANS_THRESH 8
+
+static void convert_translation_to_params(
+    double *H, Global_Motion_Params *model) {
+  model->motion_params.wmmat[0] = (int) floor(H[0] *
+                                              (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model->motion_params.wmmat[1] = (int) floor(H[1] *
+                                              (1 << GM_TRANS_PREC_BITS) + 0.5);
+  if (abs(model->motion_params.wmmat[0]) < MIN_TRANS_THRESH &&
+      abs(model->motion_params.wmmat[1]) < MIN_TRANS_THRESH) {
+    model->motion_params.wmmat[0] = 0;
+    model->motion_params.wmmat[1] = 0;
+  } else {
+    model->motion_params.wmmat[0] =
+        clamp(model->motion_params.wmmat[0],
+              GM_TRANS_MIN, GM_TRANS_MAX);
+    model->motion_params.wmmat[1] =
+        clamp(model->motion_params.wmmat[1],
+              GM_TRANS_MIN, GM_TRANS_MAX);
+  }
+}
+
+static void convert_rotzoom_to_params(double *H, Global_Motion_Params *model) {
+  model->motion_params.wmmat[0] = (int) floor(H[0] *
+                                              (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model->motion_params.wmmat[1] = (int) floor(H[1] *
+                                              (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model->motion_params.wmmat[0] =
+      clamp(model->motion_params.wmmat[0],
+            GM_TRANS_MIN, GM_TRANS_MAX);
+  model->motion_params.wmmat[1] =
+      clamp(model->motion_params.wmmat[1],
+            GM_TRANS_MIN, GM_TRANS_MAX);
+
+  model->motion_params.wmmat[2] = (int) floor(H[2] *
+                                              (1 << GM_ALPHA_PREC_BITS) + 0.5) -
+                                               (1 << GM_ALPHA_PREC_BITS);
+  model->motion_params.wmmat[3] = (int) floor(H[3] *
+                                              (1 << GM_ALPHA_PREC_BITS) + 0.5);
+
+  model->motion_params.wmmat[2] = clamp(model->motion_params.wmmat[2],
+                                        GM_ALPHA_MIN, GM_ALPHA_MAX);
+  model->motion_params.wmmat[3] = clamp(model->motion_params.wmmat[3],
+                                        GM_ALPHA_MIN, GM_ALPHA_MAX);
+
+  if (model->motion_params.wmmat[2] == 0 &&
+      model->motion_params.wmmat[3] == 0) {
+    if (abs(model->motion_params.wmmat[0]) < MIN_TRANS_THRESH &&
+        abs(model->motion_params.wmmat[1]) < MIN_TRANS_THRESH) {
+      model->motion_params.wmmat[0] = 0;
+      model->motion_params.wmmat[1] = 0;
+    }
+  }
+}
+
+static void convert_model_to_params(double *H, TransformationType type,
+                                    Global_Motion_Params *model) {
+  switch (type) {
+    case ROTZOOM:
+      convert_rotzoom_to_params(H, model);
+      break;
+    case TRANSLATION:
+      convert_translation_to_params(H, model);
+      break;
+    default:
+      break;
+  }
+  model->gmtype = get_gmtype(model);
+}
+#endif  // CONFIG_GLOBAL_MOTION
+
 static void encode_frame_internal(VP10_COMP *cpi) {
   ThreadData *const td = &cpi->td;
   MACROBLOCK *const x = &td->mb;
@@ -4556,6 +4628,18 @@
   rdc->m_search_count = 0;   // Count of motion search hits.
   rdc->ex_search_count = 0;  // Exhaustive mesh search hits.
 
+#if CONFIG_GLOBAL_MOTION
+  // TODO(sarahparker) this is a placeholder for gm computation
+  vpx_clear_system_state();
+  vp10_zero(cpi->global_motion_used);
+  if (cpi->common.frame_type == INTER_FRAME && cpi->Source) {
+    int frame;
+    double H[9] = {0, 0, 0, 0, 0, 0, 0, 0, 1};
+    for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame)
+      convert_model_to_params(H, ROTZOOM, &cm->global_motion[frame]);
+  }
+#endif  // CONFIG_GLOBAL_MOTION
+
   for (i = 0; i < MAX_SEGMENTS; ++i) {
     const int qindex = cm->seg.enabled ?
         vp10_get_qindex(&cm->seg, i, cm->base_qindex) : cm->base_qindex;
@@ -4569,7 +4653,6 @@
     x->optimize = 0;
 
   cm->tx_mode = select_tx_mode(cpi, xd);
-
   vp10_frame_init_quantizer(cpi);
 
   vp10_initialize_rd_consts(cpi);
diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h
index c8555f2..63a1669 100644
--- a/vp10/encoder/encoder.h
+++ b/vp10/encoder/encoder.h
@@ -616,6 +616,9 @@
   int existing_fb_idx_to_show;
   int is_arf_filter_off;
 #endif  // CONFIG_EXT_REFS
+#if CONFIG_GLOBAL_MOTION
+  int global_motion_used[MAX_REF_FRAMES];
+#endif
 } VP10_COMP;
 
 void vp10_initialize_enc(void);
diff --git a/vp10/encoder/subexp.c b/vp10/encoder/subexp.c
index 4aaffae..3a2e09f 100644
--- a/vp10/encoder/subexp.c
+++ b/vp10/encoder/subexp.c
@@ -286,3 +286,16 @@
                                                            upd);
   return savings;
 }
+
+void vp10_write_primitive_symmetric(vp10_writer *w, int word,
+                                   unsigned int abs_bits) {
+  if (word == 0) {
+    vp10_write_bit(w, 0);
+  } else {
+    const int x = abs(word);
+    const int s = word < 0;
+    vp10_write_bit(w, 1);
+    vp10_write_bit(w, s);
+    vp10_write_literal(w, x - 1, abs_bits);
+  }
+}
diff --git a/vp10/encoder/subexp.h b/vp10/encoder/subexp.h
index 756b499..dbd48ff 100644
--- a/vp10/encoder/subexp.h
+++ b/vp10/encoder/subexp.h
@@ -50,6 +50,13 @@
                                            int stepsize, int n);
 #endif  // CONFIG_ENTROPY
 
+//
+// mag_bits is number of bits for magnitude. The alphabet is of size
+// 2 * 2^mag_bits + 1, symmetric around 0, where one bit is used to
+// indicate 0 or non-zero, mag_bits bits are used to indicate magnitide
+// and 1 more bit for the sign if non-zero.
+void vp10_write_primitive_symmetric(vp10_writer *w, int word,
+                                   unsigned int mag_bits);
 #ifdef __cplusplus
 }  // extern "C"
 #endif