[Unified Plan] Support multiple BUNDLE groups.

In this CL, JsepTransportController and MediaSessionDescriptionFactory
are updated not to assume that there only exists at most a single BUNDLE
group but a list of N groups. This makes it possible to create multiple
BUNDLE groups by having multiple "a=group:BUNDLE" lines in the SDP.

This makes it possible to have some m= sections in one group and some
other m= sections in another group. For example, you could group all
audio m= sections in one group and all video m= sections in another
group. This enables "send all audio tracks on one transport and all
video tracks on another transport" in Unified Plan. This is something
that was possible in Plan B because all ssrcs in the same m= section
were implicitly bundled together forming a group of audio m= section and
video m= section (even without use of the BUNDLE tag).

PeerConnection will never create multiple BUNDLE groups by default, but
upon setting SDP with multiple BUNDLE groups the PeerConnection will
accept them if configured to accept BUNDLE. This makes it possible to
accept an SFU's BUNDLE offer without having to SDP munge the answer.

C++ unit tests are added. This fix has also been verified manually on:
https://jsfiddle.net/henbos/to89L6ce/43/

Without fix: 0+2 get bundled, 1+3 don't get bundled.
With fix: 0+2 get bundled in first group, 1+3 get bundled in second
group.

Bug: webrtc:10208
Change-Id: Iaf451fa5459c484730c8018274166ef154b19af8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/214487
Reviewed-by: Taylor <deadbeef@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33838}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 9793336..7177764 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -2413,21 +2413,20 @@
 }
 
 // Returns false if bundle is enabled and rtcp_mux is disabled.
-bool PeerConnection::ValidateBundleSettings(const SessionDescription* desc) {
-  bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
-  if (!bundle_enabled)
+bool PeerConnection::ValidateBundleSettings(
+    const SessionDescription* desc,
+    const std::map<std::string, const cricket::ContentGroup*>&
+        bundle_groups_by_mid) {
+  if (bundle_groups_by_mid.empty())
     return true;
 
-  const cricket::ContentGroup* bundle_group =
-      desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
-  RTC_DCHECK(bundle_group != NULL);
-
   const cricket::ContentInfos& contents = desc->contents();
   for (cricket::ContentInfos::const_iterator citer = contents.begin();
        citer != contents.end(); ++citer) {
     const cricket::ContentInfo* content = (&*citer);
     RTC_DCHECK(content != NULL);
-    if (bundle_group->HasContentName(content->name) && !content->rejected &&
+    auto it = bundle_groups_by_mid.find(content->name);
+    if (it != bundle_groups_by_mid.end() && !content->rejected &&
         content->type == MediaProtocolType::kRtp) {
       if (!HasRtcpMuxEnabled(content))
         return false;