Add support for JSEP offer/answer with transceivers

This change adds support to PeerConnection's CreateOffer/
CreateAnswer/SetLocalDescription/SetRemoteDescription for
Unified Plan SDP mapping to/from RtpTransceivers. This behavior
is enabled using the kUnifiedPlan SDP semantics in the
PeerConnection configuration.

Bug: webrtc:7600
Change-Id: I4b44f5d3690887d387bf9c47eac00db8ec974571
Reviewed-on: https://webrtc-review.googlesource.com/28341
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21442}
diff --git a/pc/peerconnection.h b/pc/peerconnection.h
index b1a1d9e..b9a86d8 100644
--- a/pc/peerconnection.h
+++ b/pc/peerconnection.h
@@ -412,6 +412,43 @@
   RTCError ApplyRemoteDescription(
       std::unique_ptr<SessionDescriptionInterface> desc);
 
+  // Updates the local RtpTransceivers according to the JSEP rules. Called as
+  // part of setting the local/remote description.
+  RTCError UpdateTransceiversAndDataChannels(
+      cricket::ContentSource source,
+      const SessionDescriptionInterface* old_session,
+      const SessionDescriptionInterface& new_session);
+
+  // Either creates or destroys the transceiver's BaseChannel according to the
+  // given media section.
+  RTCError UpdateTransceiverChannel(
+      rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
+          transceiver,
+      const cricket::ContentInfo& content,
+      const cricket::ContentGroup* bundle_group);
+
+  // Associate the given transceiver according to the JSEP rules.
+  RTCErrorOr<
+      rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
+  AssociateTransceiver(cricket::ContentSource source,
+                       size_t mline_index,
+                       const cricket::ContentInfo& content,
+                       const cricket::ContentInfo* old_content);
+
+  // Returns the RtpTransceiver, if found, that is associated to the given MID.
+  rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
+  GetAssociatedTransceiver(const std::string& mid) const;
+
+  // Returns the RtpTransceiver, if found, that was assigned to the given mline
+  // index in CreateOffer.
+  rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
+  GetTransceiverByMLineIndex(size_t mline_index) const;
+
+  // Returns an RtpTransciever, if available, that can be used to receive the
+  // given media type according to JSEP rules.
+  rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
+  FindAvailableTransceiverToReceive(cricket::MediaType media_type) const;
+
   // Returns the media section in the given session description that is
   // associated with the RtpTransceiver. Returns null if none found or this
   // RtpTransceiver is not associated. Logic varies depending on the
@@ -427,14 +464,30 @@
 
   // Returns a MediaSessionOptions struct with options decided by |options|,
   // the local MediaStreams and DataChannels.
-  void GetOptionsForOffer(
-      const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
+  void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions&
+                              offer_answer_options,
+                          cricket::MediaSessionOptions* session_options);
+  void GetOptionsForPlanBOffer(
+      const PeerConnectionInterface::RTCOfferAnswerOptions&
+          offer_answer_options,
+      cricket::MediaSessionOptions* session_options);
+  void GetOptionsForUnifiedPlanOffer(
+      const PeerConnectionInterface::RTCOfferAnswerOptions&
+          offer_answer_options,
       cricket::MediaSessionOptions* session_options);
 
   // Returns a MediaSessionOptions struct with options decided by
   // |constraints|, the local MediaStreams and DataChannels.
-  void GetOptionsForAnswer(const RTCOfferAnswerOptions& options,
+  void GetOptionsForAnswer(const RTCOfferAnswerOptions& offer_answer_options,
                            cricket::MediaSessionOptions* session_options);
+  void GetOptionsForPlanBAnswer(
+      const PeerConnectionInterface::RTCOfferAnswerOptions&
+          offer_answer_options,
+      cricket::MediaSessionOptions* session_options);
+  void GetOptionsForUnifiedPlanAnswer(
+      const PeerConnectionInterface::RTCOfferAnswerOptions&
+          offer_answer_options,
+      cricket::MediaSessionOptions* session_options);
 
   // Generates MediaDescriptionOptions for the |session_opts| based on existing
   // local description or remote description.
@@ -706,7 +759,15 @@
   // Allocates media channels based on the |desc|. If |desc| doesn't have
   // the BUNDLE option, this method will disable BUNDLE in PortAllocator.
   // This method will also delete any existing media channels before creating.
-  RTCError CreateChannels(const cricket::SessionDescription* desc);
+  RTCError CreateChannels(const cricket::SessionDescription& desc);
+
+  // If the BUNDLE policy is max-bundle, then we know for sure that all
+  // transports will be bundled from the start. This method returns the BUNDLE
+  // group if that's the case, or null if BUNDLE will be negotiated later. An
+  // error is returned if max-bundle is specified but the session description
+  // does not have a BUNDLE group.
+  RTCErrorOr<const cricket::ContentGroup*> GetEarlyBundleGroup(
+      const cricket::SessionDescription& desc) const;
 
   // Helper methods to create media channels.
   cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid,
@@ -859,6 +920,9 @@
   std::vector<
       rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
       transceivers_;
+  // MIDs that have been seen either by SetLocalDescription or
+  // SetRemoteDescription over the life of the PeerConnection.
+  std::set<std::string> seen_mids_;
 
   SessionError session_error_ = SessionError::kNone;
   std::string session_error_desc_;