Reland "Version 2 "Refactoring DataContentDescription class""

This is a reland of 14b2758726879d21671a21291dfed8fb4fd5c21c

Original change's description:
> Version 2 "Refactoring DataContentDescription class"
> 
> (substantial changes since version 1)
> 
> This CL splits the cricket::DataContentDescription class into
> two classes: cricket::RtpDataContentDescription (used for RTP data)
> and cricket::SctpDataContentDescription (used for SCTP only).
> 
> SctpDataContentDescription no longer inherits from
> MediaContentDescriptionImpl, and no longer contains "codecs".
> 
> Due to usage of internal interfaces by consumers, shimming the old
> DataContentDescription API is needed.
> 
> A new cricket::DataContentDescription class is defined, which is
> a shim over RtpDataContentDescription and SctpDataContentDescription.
> It exposes as little functionality as possible, but supports the
> concerned consumer's usage
> 
> Design document:
> https://docs.google.com/document/d/1H5LfQxJA2ikMWTQ8FZ3_GAmaXM7knfVQWiSz6ph8VQ0/edit#
> 
> Version 1 reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132700
> 
> Bug: webrtc:10358
> Change-Id: Icf95fb7308244d6f2ebfdb403aaffc544e358580
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133900
> Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27853}

Bug: webrtc:10358
Change-Id: Iff45c4694167f0b31b34ff2167c1f4ffa650bcc4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135281
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27896}
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 984a1e1..f8c9e70 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -54,29 +54,31 @@
 using cricket::ContentInfo;
 using cricket::CryptoParams;
 using cricket::DataContentDescription;
-using cricket::ICE_CANDIDATE_COMPONENT_RTP;
 using cricket::ICE_CANDIDATE_COMPONENT_RTCP;
+using cricket::ICE_CANDIDATE_COMPONENT_RTP;
+using cricket::kCodecParamAssociatedPayloadType;
+using cricket::kCodecParamMaxAverageBitrate;
 using cricket::kCodecParamMaxBitrate;
+using cricket::kCodecParamMaxPlaybackRate;
 using cricket::kCodecParamMaxPTime;
 using cricket::kCodecParamMaxQuantization;
 using cricket::kCodecParamMinBitrate;
 using cricket::kCodecParamMinPTime;
 using cricket::kCodecParamPTime;
+using cricket::kCodecParamSctpProtocol;
+using cricket::kCodecParamSctpStreams;
 using cricket::kCodecParamSPropStereo;
 using cricket::kCodecParamStartBitrate;
 using cricket::kCodecParamStereo;
-using cricket::kCodecParamUseInbandFec;
 using cricket::kCodecParamUseDtx;
-using cricket::kCodecParamSctpProtocol;
-using cricket::kCodecParamSctpStreams;
-using cricket::kCodecParamMaxAverageBitrate;
-using cricket::kCodecParamMaxPlaybackRate;
-using cricket::kCodecParamAssociatedPayloadType;
+using cricket::kCodecParamUseInbandFec;
 using cricket::MediaContentDescription;
-using cricket::MediaType;
-using cricket::RtpHeaderExtensions;
 using cricket::MediaProtocolType;
+using cricket::MediaType;
 using cricket::RidDescription;
+using cricket::RtpDataContentDescription;
+using cricket::RtpHeaderExtensions;
+using cricket::SctpDataContentDescription;
 using cricket::SimulcastDescription;
 using cricket::SimulcastLayer;
 using cricket::SimulcastLayerList;
@@ -1337,8 +1339,6 @@
   const MediaContentDescription* media_desc = content_info->media_description();
   RTC_DCHECK(media_desc);
 
-  int sctp_port = cricket::kSctpDefaultPort;
-
   // RFC 4566
   // m=<media> <port> <proto> <fmt>
   // fmt is a list of payload type numbers that MAY be used in the session.
@@ -1366,25 +1366,20 @@
       fmt.append(rtc::ToString(codec.id));
     }
   } else if (media_type == cricket::MEDIA_TYPE_DATA) {
-    const DataContentDescription* data_desc = media_desc->as_data();
-    if (IsDtlsSctp(media_desc->protocol())) {
+    const cricket::SctpDataContentDescription* sctp_data_desc =
+        media_desc->as_sctp();
+    if (sctp_data_desc) {
       fmt.append(" ");
 
-      if (data_desc->use_sctpmap()) {
-        for (const cricket::DataCodec& codec : data_desc->codecs()) {
-          if (absl::EqualsIgnoreCase(codec.name,
-                                     cricket::kGoogleSctpDataCodecName) &&
-              codec.GetParam(cricket::kCodecParamPort, &sctp_port)) {
-            break;
-          }
-        }
-
-        fmt.append(rtc::ToString(sctp_port));
+      if (sctp_data_desc->use_sctpmap()) {
+        fmt.append(rtc::ToString(sctp_data_desc->port()));
       } else {
         fmt.append(kDefaultSctpmapProtocol);
       }
     } else {
-      for (const cricket::DataCodec& codec : data_desc->codecs()) {
+      const RtpDataContentDescription* rtp_data_desc =
+          media_desc->as_rtp_data();
+      for (const cricket::RtpDataCodec& codec : rtp_data_desc->codecs()) {
         fmt.append(" ");
         fmt.append(rtc::ToString(codec.id));
       }
@@ -1523,9 +1518,10 @@
   AddLine(os.str(), message);
 
   if (IsDtlsSctp(media_desc->protocol())) {
-    const DataContentDescription* data_desc = media_desc->as_data();
+    const cricket::SctpDataContentDescription* data_desc =
+        media_desc->as_sctp();
     bool use_sctpmap = data_desc->use_sctpmap();
-    BuildSctpContentAttributes(message, sctp_port, use_sctpmap);
+    BuildSctpContentAttributes(message, data_desc->port(), use_sctpmap);
   } else if (IsRtp(media_desc->protocol())) {
     BuildRtpContentAttributes(media_desc, media_type, msid_signaling, message);
   }
@@ -1834,43 +1830,6 @@
   }
 }
 
-cricket::DataCodec FindOrMakeSctpDataCodec(DataContentDescription* media_desc) {
-  for (const auto& codec : media_desc->codecs()) {
-    if (absl::EqualsIgnoreCase(codec.name, cricket::kGoogleSctpDataCodecName)) {
-      return codec;
-    }
-  }
-  cricket::DataCodec codec_port(cricket::kGoogleSctpDataCodecPlType,
-                                cricket::kGoogleSctpDataCodecName);
-  return codec_port;
-}
-
-bool AddOrModifySctpDataCodecPort(DataContentDescription* media_desc,
-                                  int sctp_port) {
-  // Add the SCTP Port number as a pseudo-codec "port" parameter
-  auto codec = FindOrMakeSctpDataCodec(media_desc);
-  int dummy;
-  if (codec.GetParam(cricket::kCodecParamPort, &dummy)) {
-    return false;
-  }
-  codec.SetParam(cricket::kCodecParamPort, sctp_port);
-  media_desc->AddOrReplaceCodec(codec);
-  return true;
-}
-
-bool AddOrModifySctpDataMaxMessageSize(DataContentDescription* media_desc,
-                                       int max_message_size) {
-  // Add the SCTP Max Message Size as a pseudo-parameter to the codec
-  auto codec = FindOrMakeSctpDataCodec(media_desc);
-  int dummy;
-  if (codec.GetParam(cricket::kCodecParamMaxMessageSize, &dummy)) {
-    return false;
-  }
-  codec.SetParam(cricket::kCodecParamMaxMessageSize, max_message_size);
-  media_desc->AddOrReplaceCodec(codec);
-  return true;
-}
-
 bool GetMinValue(const std::vector<int>& values, int* value) {
   if (values.empty()) {
     return false;
@@ -1960,14 +1919,17 @@
       AddAttributeLine(kCodecParamPTime, ptime, message);
     }
   } else if (media_type == cricket::MEDIA_TYPE_DATA) {
-    for (const cricket::DataCodec& codec : media_desc->as_data()->codecs()) {
-      // RFC 4566
-      // a=rtpmap:<payload type> <encoding name>/<clock rate>
-      // [/<encodingparameters>]
-      InitAttrLine(kAttributeRtpmap, &os);
-      os << kSdpDelimiterColon << codec.id << " " << codec.name << "/"
-         << codec.clockrate;
-      AddLine(os.str(), message);
+    if (media_desc->as_rtp_data()) {
+      for (const cricket::RtpDataCodec& codec :
+           media_desc->as_rtp_data()->codecs()) {
+        // RFC 4566
+        // a=rtpmap:<payload type> <encoding name>/<clock rate>
+        // [/<encodingparameters>]
+        InitAttrLine(kAttributeRtpmap, &os);
+        os << kSdpDelimiterColon << codec.id << " " << codec.name << "/"
+           << codec.clockrate;
+        AddLine(os.str(), message);
+      }
     }
   }
 }
@@ -2748,24 +2710,36 @@
           payload_types, pos, &content_name, &bundle_only,
           &section_msid_signaling, &transport, candidates, error);
     } else if (HasAttribute(line, kMediaTypeData)) {
-      std::unique_ptr<DataContentDescription> data_desc =
-          ParseContentDescription<DataContentDescription>(
-              message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
-              payload_types, pos, &content_name, &bundle_only,
-              &section_msid_signaling, &transport, candidates, error);
-
-      if (data_desc && IsDtlsSctp(protocol)) {
+      if (IsDtlsSctp(protocol)) {
+        // The draft-03 format is:
+        // m=application <port> DTLS/SCTP <sctp-port>...
+        // use_sctpmap should be false.
+        // The draft-26 format is:
+        // m=application <port> UDP/DTLS/SCTP webrtc-datachannel
+        // use_sctpmap should be false.
+        auto data_desc = absl::make_unique<SctpDataContentDescription>();
         int p;
         if (rtc::FromString(fields[3], &p)) {
-          if (!AddOrModifySctpDataCodecPort(data_desc.get(), p)) {
-            return false;
-          }
+          data_desc->set_port(p);
         } else if (fields[3] == kDefaultSctpmapProtocol) {
           data_desc->set_use_sctpmap(false);
         }
+        if (!ParseContent(message, cricket::MEDIA_TYPE_DATA, mline_index,
+                          protocol, payload_types, pos, &content_name,
+                          &bundle_only, &section_msid_signaling,
+                          data_desc.get(), &transport, candidates, error)) {
+          return false;
+        }
+        content = std::move(data_desc);
+      } else {
+        // RTP
+        std::unique_ptr<RtpDataContentDescription> data_desc =
+            ParseContentDescription<RtpDataContentDescription>(
+                message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
+                payload_types, pos, &content_name, &bundle_only,
+                &section_msid_signaling, &transport, candidates, error);
+        content = std::move(data_desc);
       }
-
-      content = std::move(data_desc);
     } else {
       RTC_LOG(LS_WARNING) << "Unsupported media type: " << line;
       continue;
@@ -3138,13 +3112,15 @@
             line, "sctp-port attribute found in non-data media description.",
             error);
       }
+      if (media_desc->as_sctp()->use_sctpmap()) {
+        return ParseFailed(
+            line, "sctp-port attribute can't be used with sctpmap.", error);
+      }
       int sctp_port;
       if (!ParseSctpPort(line, &sctp_port, error)) {
         return false;
       }
-      if (!AddOrModifySctpDataCodecPort(media_desc->as_data(), sctp_port)) {
-        return false;
-      }
+      media_desc->as_sctp()->set_port(sctp_port);
     } else if (IsDtlsSctp(protocol) &&
                HasAttribute(line, kAttributeMaxMessageSize)) {
       if (media_type != cricket::MEDIA_TYPE_DATA) {
@@ -3157,10 +3133,7 @@
       if (!ParseSctpMaxMessageSize(line, &max_message_size, error)) {
         return false;
       }
-      if (!AddOrModifySctpDataMaxMessageSize(media_desc->as_data(),
-                                             max_message_size)) {
-        return false;
-      }
+      media_desc->as_sctp()->set_max_message_size(max_message_size);
     } else if (IsRtp(protocol)) {
       //
       // RTP specific attrubtes
@@ -3621,8 +3594,8 @@
     UpdateCodec(payload_type, encoding_name, clock_rate, 0, channels,
                 audio_desc);
   } else if (media_type == cricket::MEDIA_TYPE_DATA) {
-    DataContentDescription* data_desc = media_desc->as_data();
-    data_desc->AddCodec(cricket::DataCodec(payload_type, encoding_name));
+    RtpDataContentDescription* data_desc = media_desc->as_rtp_data();
+    data_desc->AddCodec(cricket::RtpDataCodec(payload_type, encoding_name));
   }
   return true;
 }