Adds support for signaling a=msid lines without a=ssrc lines.

Currently in the SDP we require an a=ssrc line in the m= section in
order for a StreamParams object to be created with that
MediaContentDescription. This change creates a StreamParams object
without ssrcs in the case that a=msid lines are signaled, but ssrcs
are not. When the remote description is set, this allows us to store
the "unsignaled" StreamParams object in the media channel to later
be used when the first packet is received and we create the
receive stream.

Bug: webrtc:7932, webrtc:7933
Change-Id: Ib6734abeee62b8ed688a8208722c402134c074ef
Reviewed-on: https://webrtc-review.googlesource.com/63141
Commit-Queue: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22712}
diff --git a/pc/channel.cc b/pc/channel.cc
index 2aab718..a1869c4 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -555,7 +555,7 @@
   bool ret = true;
   for (StreamParamsVec::const_iterator it = local_streams_.begin();
        it != local_streams_.end(); ++it) {
-    if (!GetStreamBySsrc(streams, it->first_ssrc())) {
+    if (it->has_ssrcs() && !GetStreamBySsrc(streams, it->first_ssrc())) {
       if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
         std::ostringstream desc;
         desc << "Failed to remove send stream with ssrc "
@@ -568,7 +568,7 @@
   // Check for new streams.
   for (StreamParamsVec::const_iterator it = streams.begin();
        it != streams.end(); ++it) {
-    if (!GetStreamBySsrc(local_streams_, it->first_ssrc())) {
+    if (it->has_ssrcs() && !GetStreamBySsrc(local_streams_, it->first_ssrc())) {
       if (media_channel()->AddSendStream(*it)) {
         RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
       } else {
@@ -591,7 +591,10 @@
   bool ret = true;
   for (StreamParamsVec::const_iterator it = remote_streams_.begin();
        it != remote_streams_.end(); ++it) {
-    if (!GetStreamBySsrc(streams, it->first_ssrc())) {
+    // If we no longer have an unsignaled stream, we would like to remove
+    // the unsignaled stream params that are cached.
+    if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(streams)) ||
+        !GetStreamBySsrc(streams, it->first_ssrc())) {
       if (!RemoveRecvStream_w(it->first_ssrc())) {
         std::ostringstream desc;
         desc << "Failed to remove remote stream with ssrc "
@@ -604,9 +607,13 @@
   // Check for new streams.
   for (StreamParamsVec::const_iterator it = streams.begin();
       it != streams.end(); ++it) {
-    if (!GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
+    // We allow a StreamParams with an empty list of SSRCs, in which case the
+    // MediaChannel will cache the parameters and use them for any unsignaled
+    // stream received later.
+    if ((!it->has_ssrcs() && !HasStreamWithNoSsrcs(remote_streams_)) ||
+        !GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
       if (AddRecvStream_w(*it)) {
-        RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
+        RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->first_ssrc();
       } else {
         std::ostringstream desc;
         desc << "Failed to add remote stream ssrc: " << it->first_ssrc();