red: change default redundancy level to 1

BUG=webrtc:11640

Change-Id: Ide66ae4803349ebb908d372e811efd9ef93d51e5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228424
Commit-Queue: Philipp Hancke <philipp.hancke@googlemail.com>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34720}
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
index b88dbbf..0667962 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
@@ -32,7 +32,7 @@
     1;  // reduced size for last RED header.
 
 static constexpr size_t kRedNumberOfRedundantEncodings =
-    2;  // The level of redundancy we support.
+    1;  // The level of redundancy we support.
 
 AudioEncoderCopyRed::Config::Config() = default;
 AudioEncoderCopyRed::Config::Config(Config&&) = default;
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
index bb57a90..f8e3437 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
@@ -169,16 +169,8 @@
 }
 
 // Checks that the correct payload sizes are populated into the redundancy
-// information. Variant with a redundancy level of 1.
-TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizesSingle) {
-  webrtc::test::ScopedFieldTrials field_trials(
-      "WebRTC-Audio-Red-For-Opus/Enabled-1/");
-  // Recreate the RED encoder to take the new field trial setting into account.
-  AudioEncoderCopyRed::Config config;
-  config.payload_type = red_payload_type_;
-  config.speech_encoder = std::move(red_->ReclaimContainedEncoders()[0]);
-  red_.reset(new AudioEncoderCopyRed(std::move(config)));
-
+// information for a redundancy level of 1.
+TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes1) {
   // Let the mock encoder return payload sizes 1, 2, 3, ..., 10 for the sequence
   // of calls.
   static const int kNumPackets = 10;
@@ -204,8 +196,16 @@
 }
 
 // Checks that the correct payload sizes are populated into the redundancy
-// information.
-TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes) {
+// information for a redundancy level of 2.
+TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes2) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-Audio-Red-For-Opus/Enabled-2/");
+  // Recreate the RED encoder to take the new field trial setting into account.
+  AudioEncoderCopyRed::Config config;
+  config.payload_type = red_payload_type_;
+  config.speech_encoder = std::move(red_->ReclaimContainedEncoders()[0]);
+  red_.reset(new AudioEncoderCopyRed(std::move(config)));
+
   // Let the mock encoder return payload sizes 1, 2, 3, ..., 10 for the sequence
   // of calls.
   static const int kNumPackets = 10;
@@ -238,8 +238,8 @@
 }
 
 // Checks that the correct payload sizes are populated into the redundancy
-// information. Variant with a redundancy level of 3.
-TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizesTriple) {
+// information for a redundancy level of 3.
+TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes3) {
   webrtc::test::ScopedFieldTrials field_trials(
       "WebRTC-Audio-Red-For-Opus/Enabled-3/");
   // Recreate the RED encoder to take the new field trial setting into account.
@@ -418,7 +418,68 @@
              // redundancy.
 
   EXPECT_EQ(encoded_.size(),
-            9u + 3 * 10u);  // header size + two encoded payloads.
+            5u + 2 * 10u);  // header size + two encoded payloads.
+  EXPECT_EQ(encoded_[0], primary_payload_type | 0x80);
+
+  timestamp_delta = encoded_info_.encoded_timestamp -
+                    encoded_info_.redundant[0].encoded_timestamp;
+  // Timestamp delta is encoded as a 14 bit value.
+  EXPECT_EQ(encoded_[1], timestamp_delta >> 6);
+  EXPECT_EQ(static_cast<uint8_t>(encoded_[2] >> 2), timestamp_delta & 0x3f);
+  // Redundant length is encoded as 10 bit value.
+  EXPECT_EQ(encoded_[2] & 0x3u, encoded_info_.redundant[1].encoded_bytes >> 8);
+  EXPECT_EQ(encoded_[3], encoded_info_.redundant[1].encoded_bytes & 0xff);
+
+  EXPECT_EQ(encoded_[4], primary_payload_type | 0x80);
+  timestamp_delta = encoded_info_.encoded_timestamp -
+                    encoded_info_.redundant[1].encoded_timestamp;
+}
+
+// Variant with a redundancy of 2.
+TEST_F(AudioEncoderCopyRedTest, CheckRFC2198Header2) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-Audio-Red-For-Opus/Enabled-2/");
+  // Recreate the RED encoder to take the new field trial setting into account.
+  AudioEncoderCopyRed::Config config;
+  config.payload_type = red_payload_type_;
+  config.speech_encoder = std::move(red_->ReclaimContainedEncoders()[0]);
+  red_.reset(new AudioEncoderCopyRed(std::move(config)));
+
+  const int primary_payload_type = red_payload_type_ + 1;
+  AudioEncoder::EncodedInfo info;
+  info.encoded_bytes = 10;
+  info.encoded_timestamp = timestamp_;
+  info.payload_type = primary_payload_type;
+
+  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
+      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
+  Encode();
+  info.encoded_timestamp = timestamp_;  // update timestamp.
+  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
+      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
+  Encode();  // Second call will produce a redundant encoding.
+
+  EXPECT_EQ(encoded_.size(),
+            5u + 2 * 10u);  // header size + two encoded payloads.
+  EXPECT_EQ(encoded_[0], primary_payload_type | 0x80);
+
+  uint32_t timestamp_delta = encoded_info_.encoded_timestamp -
+                             encoded_info_.redundant[0].encoded_timestamp;
+  // Timestamp delta is encoded as a 14 bit value.
+  EXPECT_EQ(encoded_[1], timestamp_delta >> 6);
+  EXPECT_EQ(static_cast<uint8_t>(encoded_[2] >> 2), timestamp_delta & 0x3f);
+  // Redundant length is encoded as 10 bit value.
+  EXPECT_EQ(encoded_[2] & 0x3u, encoded_info_.redundant[1].encoded_bytes >> 8);
+  EXPECT_EQ(encoded_[3], encoded_info_.redundant[1].encoded_bytes & 0xff);
+  EXPECT_EQ(encoded_[4], primary_payload_type);
+
+  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
+      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
+  Encode();  // Third call will produce a redundant encoding with double
+             // redundancy.
+
+  EXPECT_EQ(encoded_.size(),
+            9u + 3 * 10u);  // header size + three encoded payloads.
   EXPECT_EQ(encoded_[0], primary_payload_type | 0x80);
 
   timestamp_delta = encoded_info_.encoded_timestamp -