rtc: Fixes for lossless mode real-time mode

The rtc temporal filter feature must be kept off
for lossless mode. And the accurate_bit_estimate
feature causes division by zero in lossless mode
so disable it.

Also force skip_txfm and blk_skip to 0 for
lossless mode in nonrd_pick_intra.

Add lossless test for VGA clip, which fails without
the fixes in the patch.

Bug: aomedia:3412

Change-Id: I1fe32eacd0bd222c4705e98a68fb90a34a34304e
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 6113a10..ad3f4b5 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -1664,6 +1664,15 @@
   mi->uv_mode = UV_DC_PRED;
   *rd_cost = best_rdc;
 
+  // For lossless: always force the skip flags off.
+  // Even though the blk_skip is set to 0 above in the rdcost comparison,
+  // do it here again in case the above logic changes.
+  if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
+    x->txfm_search_info.skip_txfm = 0;
+    memset(ctx->blk_skip, 0,
+           sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
+  }
+
 #if CONFIG_INTERNAL_STATS
   store_coding_context_nonrd(x, ctx, mi->mode);
 #else
@@ -3311,8 +3320,8 @@
   mi->mode = best_pickmode->best_mode;
   mi->ref_frame[0] = best_pickmode->best_ref_frame;
   mi->ref_frame[1] = best_pickmode->best_second_ref_frame;
-  // For lossless/Q=0: always force the skip flags off.
-  if (cm->quant_params.base_qindex == 0) {
+  // For lossless: always force the skip flags off.
+  if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
     txfm_info->skip_txfm = 0;
     memset(ctx->blk_skip, 0, sizeof(ctx->blk_skip[0]) * ctx->num_4x4_blk);
   } else {
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 1f23fb2..73e1967 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1537,6 +1537,12 @@
       sf->rt_sf.estimate_motion_for_var_based_partition = 1;
     if (speed >= 9) sf->rt_sf.estimate_motion_for_var_based_partition = 0;
   }
+  if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
+    sf->rt_sf.use_rtc_tf = 0;
+    // TODO(aomedia:3412): The setting accurate_bit_estimate = 0
+    // can be removed once it's fixed for lossless mode.
+    sf->hl_sf.accurate_bit_estimate = 0;
+  }
 }
 
 // TODO(kyslov): now this is very similar to
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 819cb12..e4c7c70 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1628,6 +1628,7 @@
 
   // Temporal filtering
   // The value can be 1 or 2, which indicates the threshold to use.
+  // Must be off for lossless mode.
   int use_rtc_tf;
 
   // Prune the use of the identity transform in nonrd_pickmode,
diff --git a/test/lossless_test.cc b/test/lossless_test.cc
index d4eab51..ef4e19f 100644
--- a/test/lossless_test.cc
+++ b/test/lossless_test.cc
@@ -77,6 +77,7 @@
   }
 
   void TestLosslessEncoding();
+  void TestLosslessEncodingVGALag0();
   void TestLosslessEncoding444();
   void TestLosslessEncodingCtrl();
 
@@ -107,6 +108,23 @@
   EXPECT_GE(psnr_lossless, kMaxPsnr);
 }
 
+void LosslessTestLarge::TestLosslessEncodingVGALag0() {
+  const aom_rational timebase = { 33333333, 1000000000 };
+  cfg_.g_timebase = timebase;
+  cfg_.rc_target_bitrate = 2000;
+  cfg_.g_lag_in_frames = 0;
+  cfg_.rc_min_quantizer = 0;
+  cfg_.rc_max_quantizer = 0;
+
+  init_flags_ = AOM_CODEC_USE_PSNR;
+
+  libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480,
+                                     timebase.den, timebase.num, 0, 30);
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+  const double psnr_lossless = GetMinPsnr();
+  EXPECT_GE(psnr_lossless, kMaxPsnr);
+}
+
 void LosslessTestLarge::TestLosslessEncoding444() {
   libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 5);
 
@@ -145,6 +163,10 @@
 
 TEST_P(LosslessTestLarge, TestLosslessEncoding) { TestLosslessEncoding(); }
 
+TEST_P(LosslessTestLarge, TestLosslessEncodingVGALag0) {
+  TestLosslessEncodingVGALag0();
+}
+
 TEST_P(LosslessTestLarge, TestLosslessEncoding444) {
   TestLosslessEncoding444();
 }
@@ -178,6 +200,10 @@
   TestLosslessEncoding();
 }
 
+TEST_P(LosslessRealtimeTestLarge, TestLosslessEncodingVGALag0) {
+  TestLosslessEncodingVGALag0();
+}
+
 TEST_P(LosslessRealtimeTestLarge, TestLosslessEncoding444) {
   TestLosslessEncoding444();
 }