Automatically turn on/off screen content tools

Turn "allow_screen_content_tools" on when the source video has many blocks
with only few different colors. The automatic detection is enabled by
defualt (or with command line flag "--tune-content=default"). With
"--tune-content=screen", the screen content tools are always turned on.

On the screen_content test set, the "default" setting is less than 0.3%
worse than the "screen" setting on keyframe encoding.

Change-Id: Iac7ab8952c96531d1fae84da1823291f5987519c
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index ec9e410..00cb1a2 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -5011,6 +5011,28 @@
 }
 #endif  // CONFIG_GLOBAL_MOTION
 
+#if CONFIG_PALETTE
+// Estimate if the source frame is screen content, based on the portion of
+// blocks that have no more than 4 (experimentally selected) luma colors.
+static int is_screen_content(const uint8_t *src, int stride, int width,
+                             int height) {
+  assert(src != NULL);
+  int counts = 0;
+  const int blk_w = 16;
+  const int blk_h = 16;
+  const int limit = 4;
+  for (int r = 0; r + blk_h <= height; r += blk_h) {
+    for (int c = 0; c + blk_w <= width; c += blk_w) {
+      const int n_colors =
+          av1_count_colors(src + r * stride + c, stride, blk_w, blk_h);
+      if (n_colors > 1 && n_colors <= limit) counts++;
+    }
+  }
+  // The threshold is 10%.
+  return counts * blk_h * blk_w * 10 > width * height;
+}
+#endif  // CONFIG_PALETTE
+
 static void encode_frame_internal(AV1_COMP *cpi) {
   ThreadData *const td = &cpi->td;
   MACROBLOCK *const x = &td->mb;
@@ -5037,6 +5059,14 @@
   av1_zero(rdc->coef_counts);
   av1_zero(rdc->comp_pred_diff);
 
+#if CONFIG_PALETTE
+  if (cpi->auto_tune_content && frame_is_intra_only(cm)) {
+    cm->allow_screen_content_tools =
+        is_screen_content(cpi->source->y_buffer, cpi->source->y_stride,
+                          cpi->source->y_width, cpi->source->y_height);
+  }
+#endif  // CONFIG_PALETTE
+
 #if CONFIG_GLOBAL_MOTION
   av1_zero(rdc->global_motion_used);
   av1_zero(cpi->gmparams_cost);