Add field trial that enables Opus PLC.

Low-Coverage-Reason: EXPERIMENTAL_CODE Code is behind field trial that will only be used for testing.
Bug: webrtc:13322
Change-Id: Ie306be808381b3a20b4e0d58349927bf3524018a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335840
Reviewed-by: Tomas Lundqvist <tomasl@google.com>
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41608}
diff --git a/experiments/field_trials.py b/experiments/field_trials.py
index 4aa9bcb..70e131e 100755
--- a/experiments/field_trials.py
+++ b/experiments/field_trials.py
@@ -50,6 +50,9 @@
     FieldTrial('WebRTC-Audio-OpusSetSignalVoiceWithDtx',
                'webrtc:4559',
                date(2024, 4, 1)),
+    FieldTrial('WebRTC-Audio-OpusGeneratePlc',
+               'webrtc:13322',
+               date(2024, 4, 1)),
     FieldTrial('WebRTC-AV1-OverridePriorityBitrate',
                'webrtc:15763',
                date(2024, 4, 1)),
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
index cff9685..0f53409 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
+++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
@@ -17,12 +17,15 @@
 #include "api/array_view.h"
 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
 #include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
 AudioDecoderOpusImpl::AudioDecoderOpusImpl(size_t num_channels,
                                            int sample_rate_hz)
-    : channels_{num_channels}, sample_rate_hz_{sample_rate_hz} {
+    : channels_(num_channels),
+      sample_rate_hz_(sample_rate_hz),
+      generate_plc_(field_trial::IsEnabled("WebRTC-Audio-OpusGeneratePlc")) {
   RTC_DCHECK(num_channels == 1 || num_channels == 2);
   RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 48000);
   const int error =
@@ -125,4 +128,22 @@
   return channels_;
 }
 
+void AudioDecoderOpusImpl::GeneratePlc(
+    size_t requested_samples_per_channel,
+    rtc::BufferT<int16_t>* concealment_audio) {
+  if (!generate_plc_) {
+    return;
+  }
+  int plc_size = WebRtcOpus_PlcDuration(dec_state_) * channels_;
+  concealment_audio->AppendData(plc_size, [&](rtc::ArrayView<int16_t> decoded) {
+    int16_t temp_type = 1;
+    int ret =
+        WebRtcOpus_Decode(dec_state_, nullptr, 0, decoded.data(), &temp_type);
+    if (ret < 0) {
+      return 0;
+    }
+    return ret;
+  });
+}
+
 }  // namespace webrtc
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.h b/modules/audio_coding/codecs/opus/audio_decoder_opus.h
index e8fd044..2dd62fd 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_opus.h
+++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.h
@@ -40,6 +40,8 @@
   bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override;
   int SampleRateHz() const override;
   size_t Channels() const override;
+  void GeneratePlc(size_t requested_samples_per_channel,
+                   rtc::BufferT<int16_t>* concealment_audio) override;
 
  protected:
   int DecodeInternal(const uint8_t* encoded,
@@ -57,6 +59,7 @@
   OpusDecInst* dec_state_;
   const size_t channels_;
   const int sample_rate_hz_;
+  const bool generate_plc_;
 };
 
 }  // namespace webrtc