Add field trial for forced software decoder fallback.

Bug: none
Change-Id: Ibd8564fc243105274c2778ccfc99d38049c826b1
Reviewed-on: https://webrtc-review.googlesource.com/c/121720
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26596}
diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
index 5b414e7..06b893c 100644
--- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
+++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
@@ -22,6 +22,7 @@
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/include/video_error_codes.h"
 #include "rtc_base/checks.h"
+#include "test/field_trial.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -29,7 +30,11 @@
 class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
  protected:
   VideoDecoderSoftwareFallbackWrapperTest()
-      : fake_decoder_(new CountingFakeDecoder()),
+      : VideoDecoderSoftwareFallbackWrapperTest("") {}
+  explicit VideoDecoderSoftwareFallbackWrapperTest(
+      const std::string& field_trials)
+      : override_field_trials_(field_trials),
+        fake_decoder_(new CountingFakeDecoder()),
         fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper(
             std::unique_ptr<VideoDecoder>(VP8Decoder::Create()),
             std::unique_ptr<VideoDecoder>(fake_decoder_))) {}
@@ -71,6 +76,7 @@
     int release_count_ = 0;
     int reset_count_ = 0;
   };
+  test::ScopedFieldTrials override_field_trials_;
   // |fake_decoder_| is owned and released by |fallback_wrapper_|.
   CountingFakeDecoder* fake_decoder_;
   std::unique_ptr<VideoDecoder> fallback_wrapper_;
@@ -214,4 +220,40 @@
   fallback_wrapper_->Release();
 }
 
+class ForcedSoftwareDecoderFallbackTest
+    : public VideoDecoderSoftwareFallbackWrapperTest {
+ public:
+  ForcedSoftwareDecoderFallbackTest()
+      : VideoDecoderSoftwareFallbackWrapperTest(
+            "WebRTC-Video-ForcedSwDecoderFallback/Enabled/") {
+    fake_decoder_ = new CountingFakeDecoder();
+    sw_fallback_decoder_ = new CountingFakeDecoder();
+    fallback_wrapper_ = CreateVideoDecoderSoftwareFallbackWrapper(
+        std::unique_ptr<VideoDecoder>(sw_fallback_decoder_),
+        std::unique_ptr<VideoDecoder>(fake_decoder_));
+  }
+
+  CountingFakeDecoder* sw_fallback_decoder_;
+};
+
+TEST_F(ForcedSoftwareDecoderFallbackTest, UsesForcedFallback) {
+  VideoCodec codec = {};
+  fallback_wrapper_->InitDecode(&codec, 2);
+  EXPECT_EQ(1, sw_fallback_decoder_->init_decode_count_);
+
+  EncodedImage encoded_image;
+  encoded_image._frameType = kVideoFrameKey;
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
+  EXPECT_EQ(1, sw_fallback_decoder_->init_decode_count_);
+  EXPECT_EQ(1, sw_fallback_decoder_->decode_count_);
+
+  fallback_wrapper_->Release();
+  EXPECT_EQ(1, sw_fallback_decoder_->release_count_);
+
+  // Only fallback decoder should have been used.
+  EXPECT_EQ(0, fake_decoder_->init_decode_count_);
+  EXPECT_EQ(0, fake_decoder_->decode_count_);
+  EXPECT_EQ(0, fake_decoder_->release_count_);
+}
+
 }  // namespace webrtc
diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
index 920eb0b..0bbce3e 100644
--- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
@@ -22,6 +22,7 @@
 #include "rtc_base/logging.h"
 #include "rtc_base/system/fallthrough.h"
 #include "rtc_base/trace_event.h"
+#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -90,6 +91,12 @@
   codec_settings_ = *codec_settings;
   number_of_cores_ = number_of_cores;
 
+  if (webrtc::field_trial::IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")) {
+    RTC_LOG(LS_INFO) << "Forced software decoder fallback enabled.";
+    RTC_DCHECK(decoder_type_ == DecoderType::kNone);
+    return InitFallbackDecoder() ? WEBRTC_VIDEO_CODEC_OK
+                                 : WEBRTC_VIDEO_CODEC_ERROR;
+  }
   int32_t status = InitHwDecoder();
   if (status == WEBRTC_VIDEO_CODEC_OK) {
     return WEBRTC_VIDEO_CODEC_OK;