Decide Av1 num of threads on frame size and available cores.

Change-Id: I65c40a123ad848bc175311f9d9e4d2bd28734aa2
Bug: None
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196681
Commit-Queue: Jerome Jiang <jianj@google.com>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32850}
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
index c1accad..925e41b 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
@@ -84,6 +84,9 @@
   EncoderInfo GetEncoderInfo() const override;
 
  private:
+  // Determine number of encoder threads to use.
+  int NumberOfThreads(int width, int height, int number_of_cores);
+
   bool SvcEnabled() const { return svc_params_.has_value(); }
   // Fills svc_params_ memeber value. Returns false on error.
   bool SetSvcParams(ScalableVideoController::StreamLayersConfig svc_config);
@@ -197,7 +200,8 @@
   // Overwrite default config with input encoder settings & RTC-relevant values.
   cfg_.g_w = encoder_settings_.width;
   cfg_.g_h = encoder_settings_.height;
-  cfg_.g_threads = settings.number_of_cores;
+  cfg_.g_threads =
+      NumberOfThreads(cfg_.g_w, cfg_.g_h, settings.number_of_cores);
   cfg_.g_timebase.num = 1;
   cfg_.g_timebase.den = kRtpTicksPerSecond;
   cfg_.rc_target_bitrate = encoder_settings_.maxBitrate;  // kilobits/sec.
@@ -303,9 +307,45 @@
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
+  ret = aom_codec_control(&ctx_, AV1E_SET_TILE_COLUMNS, cfg_.g_threads >> 1);
+  if (ret != AOM_CODEC_OK) {
+    RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret
+                        << " on control AV1E_SET_TILE_COLUMNS.";
+    return WEBRTC_VIDEO_CODEC_ERROR;
+  }
+
+  ret = aom_codec_control(&ctx_, AV1E_SET_ROW_MT, 1);
+  if (ret != AOM_CODEC_OK) {
+    RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret
+                        << " on control AV1E_SET_ROW_MT.";
+    return WEBRTC_VIDEO_CODEC_ERROR;
+  }
+
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
+int LibaomAv1Encoder::NumberOfThreads(int width,
+                                      int height,
+                                      int number_of_cores) {
+  // Keep the number of encoder threads equal to the possible number of column
+  // tiles, which is (1, 2, 4, 8). See comments below for AV1E_SET_TILE_COLUMNS.
+  if (width * height >= 1280 * 720 && number_of_cores > 4) {
+    return 4;
+  } else if (width * height >= 640 * 360 && number_of_cores > 2) {
+    return 2;
+  } else {
+// Use 2 threads for low res on ARM.
+#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || \
+    defined(WEBRTC_ANDROID)
+    if (width * height >= 320 * 180 && number_of_cores > 2) {
+      return 2;
+    }
+#endif
+    // 1 thread less than VGA.
+    return 1;
+  }
+}
+
 bool LibaomAv1Encoder::SetSvcParams(
     ScalableVideoController::StreamLayersConfig svc_config) {
   bool svc_enabled =