Generate FMTP parameters for the H.264 codec.

This CL generates FMTP parameters that allow H.264 interoperation
with Firefox for the default codec list.

BUG=chromium:591971

Review URL: https://codereview.webrtc.org/1880963002

Cr-Commit-Position: refs/heads/master@{#12333}
diff --git a/webrtc/api/webrtcsdp.cc b/webrtc/api/webrtcsdp.cc
index 93d4acc..90e0007 100644
--- a/webrtc/api/webrtcsdp.cc
+++ b/webrtc/api/webrtcsdp.cc
@@ -1574,15 +1574,27 @@
 
 bool IsFmtpParam(const std::string& name) {
   const char* kFmtpParams[] = {
-    kCodecParamMinPTime, kCodecParamSPropStereo,
-    kCodecParamStereo, kCodecParamUseInbandFec, kCodecParamUseDtx,
-    kCodecParamStartBitrate, kCodecParamMaxBitrate, kCodecParamMinBitrate,
-    kCodecParamMaxQuantization, kCodecParamSctpProtocol, kCodecParamSctpStreams,
-    kCodecParamMaxAverageBitrate, kCodecParamMaxPlaybackRate,
-    kCodecParamAssociatedPayloadType
-  };
+      // TODO(hta): Split FMTP parameters apart from parameters in general.
+      // FMTP parameters are codec specific, not generic.
+      kCodecParamMinPTime,
+      kCodecParamSPropStereo,
+      kCodecParamStereo,
+      kCodecParamUseInbandFec,
+      kCodecParamUseDtx,
+      kCodecParamStartBitrate,
+      kCodecParamMaxBitrate,
+      kCodecParamMinBitrate,
+      kCodecParamMaxQuantization,
+      kCodecParamSctpProtocol,
+      kCodecParamSctpStreams,
+      kCodecParamMaxAverageBitrate,
+      kCodecParamMaxPlaybackRate,
+      kCodecParamAssociatedPayloadType,
+      cricket::kH264FmtpPacketizationMode,
+      cricket::kH264FmtpLevelAsymmetryAllowed,
+      cricket::kH264FmtpProfileLevelId};
   for (size_t i = 0; i < arraysize(kFmtpParams); ++i) {
-    if (_stricmp(name.c_str(), kFmtpParams[i]) == 0) {
+    if (name.compare(kFmtpParams[i]) == 0) {
       return true;
     }
   }
diff --git a/webrtc/api/webrtcsdp_unittest.cc b/webrtc/api/webrtcsdp_unittest.cc
index c527204..3734ac5 100644
--- a/webrtc/api/webrtcsdp_unittest.cc
+++ b/webrtc/api/webrtcsdp_unittest.cc
@@ -25,6 +25,8 @@
 #include "webrtc/base/stringencode.h"
 #include "webrtc/base/stringutils.h"
 #include "webrtc/media/base/mediaconstants.h"
+#include "webrtc/media/engine/webrtcvideoengine2.h"
+#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
 #include "webrtc/p2p/base/p2pconstants.h"
 #include "webrtc/pc/mediasession.h"
 
@@ -2088,6 +2090,33 @@
   EXPECT_EQ(std::string(kSdpTcpActiveCandidate), message);
 }
 
+TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithH264) {
+  if (!webrtc::H264Encoder::IsSupported())
+    return;
+  for (const auto& codec : cricket::DefaultVideoCodecList()) {
+    video_desc_->AddCodec(codec);
+  }
+  jdesc_.Initialize(desc_.Copy(), kSessionId, kSessionVersion);
+
+  std::string message = webrtc::SdpSerialize(jdesc_, false);
+  size_t after_pt = message.find(" H264/90000");
+  ASSERT_NE(after_pt, std::string::npos);
+  size_t before_pt = message.rfind("a=rtpmap:", after_pt);
+  ASSERT_NE(before_pt, std::string::npos);
+  before_pt += strlen("a=rtpmap:");
+  std::string pt = message.substr(before_pt, after_pt - before_pt);
+  // TODO(hta): Check if payload type |pt| occurs in the m=video line.
+  std::string to_find = "a=fmtp:" + pt + " ";
+  size_t fmtp_pos = message.find(to_find);
+  ASSERT_NE(std::string::npos, fmtp_pos) << "Failed to find " << to_find;
+  size_t fmtp_endpos = message.find("\n", fmtp_pos);
+  ASSERT_NE(std::string::npos, fmtp_endpos);
+  std::string fmtp_value = message.substr(fmtp_pos, fmtp_endpos);
+  EXPECT_NE(std::string::npos, fmtp_value.find("level-asymmetry-allowed=1"));
+  EXPECT_NE(std::string::npos, fmtp_value.find("packetization-mode=1"));
+  EXPECT_NE(std::string::npos, fmtp_value.find("profile-level-id=42e01f"));
+}
+
 TEST_F(WebRtcSdpTest, DeserializeSessionDescription) {
   JsepSessionDescription jdesc(kDummyString);
   // Deserialize
diff --git a/webrtc/media/base/mediaconstants.cc b/webrtc/media/base/mediaconstants.cc
index 2190a54..d6bb7e3 100644
--- a/webrtc/media/base/mediaconstants.cc
+++ b/webrtc/media/base/mediaconstants.cc
@@ -116,6 +116,12 @@
 const char kVp9CodecName[] = "VP9";
 const char kH264CodecName[] = "H264";
 
+// RFC 6184 RTP Payload Format for H.264 video
+const char kH264FmtpProfileLevelId[] = "profile-level-id";
+const char kH264FmtpLevelAsymmetryAllowed[] = "level-asymmetry-allowed";
+const char kH264FmtpPacketizationMode[] = "packetization-mode";
+const char kH264ProfileLevelConstrainedBaseline[] = "42e01f";
+
 const int kDefaultVp8PlType = 100;
 const int kDefaultVp9PlType = 101;
 const int kDefaultH264PlType = 107;
diff --git a/webrtc/media/base/mediaconstants.h b/webrtc/media/base/mediaconstants.h
index 94225de..708ca5b 100644
--- a/webrtc/media/base/mediaconstants.h
+++ b/webrtc/media/base/mediaconstants.h
@@ -149,6 +149,12 @@
 extern const char kVp9CodecName[];
 extern const char kH264CodecName[];
 
+// RFC 6184 RTP Payload Format for H.264 video
+extern const char kH264FmtpProfileLevelId[];
+extern const char kH264FmtpLevelAsymmetryAllowed[];
+extern const char kH264FmtpPacketizationMode[];
+extern const char kH264ProfileLevelConstrainedBaseline[];
+
 extern const int kDefaultVp8PlType;
 extern const int kDefaultVp9PlType;
 extern const int kDefaultH264PlType;
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
index ec6b033..b9dbd66684 100644
--- a/webrtc/media/engine/webrtcvideoengine2.cc
+++ b/webrtc/media/engine/webrtcvideoengine2.cc
@@ -386,8 +386,18 @@
         VideoCodec::CreateRtxCodec(kDefaultRtxVp9PlType, kDefaultVp9PlType));
   }
   if (CodecIsInternallySupported(kH264CodecName)) {
-    codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultH264PlType,
-                                                             kH264CodecName));
+    VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams(
+        kDefaultH264PlType, kH264CodecName);
+    // TODO(hta): Move all parameter generation for SDP into the codec
+    // implementation, for all codecs and parameters.
+    // TODO(hta): Move selection of profile-level-id to H.264 codec
+    // implementation.
+    // TODO(hta): Set FMTP parameters for all codecs of type H264.
+    codec.SetParam(kH264FmtpProfileLevelId,
+                   kH264ProfileLevelConstrainedBaseline);
+    codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
+    codec.SetParam(kH264FmtpPacketizationMode, "1");
+    codecs.push_back(codec);
     codecs.push_back(
         VideoCodec::CreateRtxCodec(kDefaultRtxH264PlType, kDefaultH264PlType));
   }