Split FlexFEC field trial in two.

- The "flexfec-03" codec is advertised in the SDP whenever the
  "WebRTC-FlexFEC-03-Advertised" field trial is enabled.
- Sending FlexFEC packets is enabled whenever the "flexfec-03" codec is
  negotiated, and the "WebRTC-FlexFEC-03" field trial is enabled.

After this CL, the number of calls to
WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec during renegotiation
will be reduced for cases when only one endpoint has the "WebRTC-FlexFEC-03"
field trial enabled.

BUG=webrtc:5654

Review-Url: https://codereview.webrtc.org/2716733005
Cr-Original-Commit-Position: refs/heads/master@{#16925}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 340e3fd59f2af4b13e5ffb8430cf87e15f334066
diff --git a/media/engine/internalencoderfactory.cc b/media/engine/internalencoderfactory.cc
index 65c1ba9..544070f 100644
--- a/media/engine/internalencoderfactory.cc
+++ b/media/engine/internalencoderfactory.cc
@@ -21,10 +21,13 @@
 
 namespace {
 
-const char kFlexfecFieldTrialName[] = "WebRTC-FlexFEC-03";
-
-bool IsFlexfecFieldTrialEnabled() {
-  return webrtc::field_trial::IsEnabled(kFlexfecFieldTrialName);
+// If this field trial is enabled, the "flexfec-03" codec will be advertised
+// as being supported by the InternalEncoderFactory. This means that
+// "flexfec-03" will appear in the default local SDP, and we therefore need to
+// be ready to receive FlexFEC packets from the remote.
+bool IsFlexfecAdvertisedFieldTrialEnabled() {
+  return webrtc::field_trial::FindFullName("WebRTC-FlexFEC-03-Advertised") ==
+         "Enabled";
 }
 
 }  // namespace
@@ -46,7 +49,7 @@
   supported_codecs_.push_back(cricket::VideoCodec(kRedCodecName));
   supported_codecs_.push_back(cricket::VideoCodec(kUlpfecCodecName));
 
-  if (IsFlexfecFieldTrialEnabled()) {
+  if (IsFlexfecAdvertisedFieldTrialEnabled()) {
     cricket::VideoCodec flexfec_codec(kFlexfecCodecName);
     // This value is currently arbitrarily set to 10 seconds. (The unit
     // is microseconds.) This parameter MUST be present in the SDP, but
diff --git a/media/engine/webrtcvideoengine2.cc b/media/engine/webrtcvideoengine2.cc
index 9f37f33..8b4c5df 100644
--- a/media/engine/webrtcvideoengine2.cc
+++ b/media/engine/webrtcvideoengine2.cc
@@ -41,16 +41,11 @@
 namespace cricket {
 namespace {
 
-// Three things happen when the FlexFEC field trial is enabled:
-// 1) FlexFEC is exposed in the default codec list, eventually showing up
-//    in the default SDP. (See InternalEncoderFactory ctor.)
-// 2) FlexFEC send parameters are set in the VideoSendStream config.
-// 3) FlexFEC receive parameters are set in the FlexfecReceiveStream config,
-//    and the corresponding object is instantiated.
-const char kFlexfecFieldTrialName[] = "WebRTC-FlexFEC-03";
-
+// If this field trial is enabled, we will enable sending FlexFEC and disable
+// sending ULPFEC whenever the former has been negotiated. Receiving FlexFEC
+// is enabled whenever FlexFEC has been negotiated.
 bool IsFlexfecFieldTrialEnabled() {
-  return webrtc::field_trial::IsEnabled(kFlexfecFieldTrialName);
+  return webrtc::field_trial::FindFullName("WebRTC-FlexFEC-03") == "Enabled";
 }
 
 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory.
@@ -1556,7 +1551,7 @@
   sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
                  &parameters_.config.rtp.rtx.ssrcs);
 
-  // FlexFEC.
+  // FlexFEC SSRCs.
   // TODO(brandtr): This code needs to be generalized when we add support for
   // multistream protection.
   if (IsFlexfecFieldTrialEnabled()) {
@@ -1731,8 +1726,10 @@
     parameters_.config.encoder_settings.internal_source = false;
   }
   parameters_.config.rtp.ulpfec = codec_settings.ulpfec;
-  parameters_.config.rtp.flexfec.payload_type =
-      codec_settings.flexfec_payload_type;
+  if (IsFlexfecFieldTrialEnabled()) {
+    parameters_.config.rtp.flexfec.payload_type =
+        codec_settings.flexfec_payload_type;
+  }
 
   // Set RTX payload type if RTX is enabled.
   if (!parameters_.config.rtp.rtx.ssrcs.empty()) {
@@ -2313,7 +2310,7 @@
     call_->DestroyFlexfecReceiveStream(flexfec_stream_);
     flexfec_stream_ = nullptr;
   }
-  if (IsFlexfecFieldTrialEnabled() && flexfec_config_.IsCompleteAndEnabled()) {
+  if (flexfec_config_.IsCompleteAndEnabled()) {
     flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_);
     flexfec_stream_->Start();
   }
diff --git a/media/engine/webrtcvideoengine2_unittest.cc b/media/engine/webrtcvideoengine2_unittest.cc
index 57ba5d2..ddfa52c 100644
--- a/media/engine/webrtcvideoengine2_unittest.cc
+++ b/media/engine/webrtcvideoengine2_unittest.cc
@@ -781,7 +781,7 @@
 
   // FlexFEC is active with field trial.
   webrtc::test::ScopedFieldTrials override_field_trials_(
-      "WebRTC-FlexFEC-03/Enabled/");
+      "WebRTC-FlexFEC-03-Advertised/Enabled/");
   const std::vector<VideoCodec> codecs_after = engine_.codecs();
   EXPECT_NE(codecs_after.end(),
             std::find_if(codecs_after.begin(), codecs_after.end(), is_flexfec));
@@ -2400,7 +2400,9 @@
 class WebRtcVideoChannel2FlexfecTest : public WebRtcVideoChannel2Test {
  public:
   WebRtcVideoChannel2FlexfecTest()
-      : WebRtcVideoChannel2Test("WebRTC-FlexFEC-03/Enabled/") {}
+      : WebRtcVideoChannel2Test(
+            "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
+  }
 };
 
 // TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
diff --git a/sdk/objc/Framework/Classes/RTCFieldTrials.mm b/sdk/objc/Framework/Classes/RTCFieldTrials.mm
index 297bb11..5e1ee0a 100644
--- a/sdk/objc/Framework/Classes/RTCFieldTrials.mm
+++ b/sdk/objc/Framework/Classes/RTCFieldTrials.mm
@@ -18,6 +18,7 @@
 
 NSString * const kRTCFieldTrialAudioSendSideBweKey = @"WebRTC-Audio-SendSideBwe";
 NSString * const kRTCFieldTrialSendSideBweWithOverheadKey = @"WebRTC-SendSideBwe-WithOverhead";
+NSString * const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised";
 NSString * const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03";
 NSString * const kRTCFieldTrialImprovedBitrateEstimateKey = @"WebRTC-ImprovedBitrateEstimate";
 NSString * const kRTCFieldTrialMedianSlopeFilterKey = @"WebRTC-BweMedianSlopeFilter";
diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h b/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h
index 1f60b5c..a9d6806 100644
--- a/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h
+++ b/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h
@@ -15,6 +15,7 @@
 /** The only valid value for the following if set is kRTCFieldTrialEnabledValue. */
 RTC_EXTERN NSString * const kRTCFieldTrialAudioSendSideBweKey;
 RTC_EXTERN NSString * const kRTCFieldTrialSendSideBweWithOverheadKey;
+RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03AdvertisedKey;
 RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03Key;
 RTC_EXTERN NSString * const kRTCFieldTrialImprovedBitrateEstimateKey;
 RTC_EXTERN NSString * const kRTCFieldTrialH264HighProfileKey;