1 /* 2 * libjingle 3 * Copyright 2011 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/media/base/streamparams.h" 29 30 #include <sstream> 31 32 namespace cricket { 33 34 const char kFecSsrcGroupSemantics[] = "FEC"; 35 const char kFidSsrcGroupSemantics[] = "FID"; 36 37 static std::string SsrcsToString(const std::vector<uint32>& ssrcs) { 38 std::ostringstream ost; 39 ost << "ssrcs:["; 40 for (std::vector<uint32>::const_iterator it = ssrcs.begin(); 41 it != ssrcs.end(); ++it) { 42 if (it != ssrcs.begin()) { 43 ost << ","; 44 } 45 ost << *it; 46 } 47 ost << "]"; 48 return ost.str(); 49 } 50 51 bool SsrcGroup::has_semantics(const std::string& semantics_in) const { 52 return (semantics == semantics_in && ssrcs.size() > 0); 53 } 54 55 std::string SsrcGroup::ToString() const { 56 std::ostringstream ost; 57 ost << "{"; 58 ost << "semantics:" << semantics << ";"; 59 ost << SsrcsToString(ssrcs); 60 ost << "}"; 61 return ost.str(); 62 } 63 64 std::string StreamParams::ToString() const { 65 std::ostringstream ost; 66 ost << "{"; 67 if (!groupid.empty()) { 68 ost << "groupid:" << groupid << ";"; 69 } 70 if (!id.empty()) { 71 ost << "id:" << id << ";"; 72 } 73 ost << SsrcsToString(ssrcs) << ";"; 74 ost << "ssrc_groups:"; 75 for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin(); 76 it != ssrc_groups.end(); ++it) { 77 if (it != ssrc_groups.begin()) { 78 ost << ","; 79 } 80 ost << it->ToString(); 81 } 82 ost << ";"; 83 if (!type.empty()) { 84 ost << "type:" << type << ";"; 85 } 86 if (!display.empty()) { 87 ost << "display:" << display << ";"; 88 } 89 if (!cname.empty()) { 90 ost << "cname:" << cname << ";"; 91 } 92 if (!sync_label.empty()) { 93 ost << "sync_label:" << sync_label; 94 } 95 ost << "}"; 96 return ost.str(); 97 } 98 99 bool StreamParams::AddSecondarySsrc(const std::string& semantics, 100 uint32 primary_ssrc, 101 uint32 secondary_ssrc) { 102 if (!has_ssrc(primary_ssrc)) { 103 return false; 104 } 105 106 ssrcs.push_back(secondary_ssrc); 107 std::vector<uint32> ssrc_vector; 108 ssrc_vector.push_back(primary_ssrc); 109 ssrc_vector.push_back(secondary_ssrc); 110 SsrcGroup ssrc_group = SsrcGroup(semantics, ssrc_vector); 111 ssrc_groups.push_back(ssrc_group); 112 return true; 113 } 114 115 bool StreamParams::GetSecondarySsrc(const std::string& semantics, 116 uint32 primary_ssrc, 117 uint32* secondary_ssrc) const { 118 for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin(); 119 it != ssrc_groups.end(); ++it) { 120 if (it->has_semantics(semantics) && 121 it->ssrcs.size() >= 2 && 122 it->ssrcs[0] == primary_ssrc) { 123 *secondary_ssrc = it->ssrcs[1]; 124 return true; 125 } 126 } 127 return false; 128 } 129 130 bool GetStream(const StreamParamsVec& streams, 131 const StreamSelector& selector, 132 StreamParams* stream_out) { 133 for (StreamParamsVec::const_iterator stream = streams.begin(); 134 stream != streams.end(); ++stream) { 135 if (selector.Matches(*stream)) { 136 if (stream_out != NULL) { 137 *stream_out = *stream; 138 } 139 return true; 140 } 141 } 142 return false; 143 } 144 145 bool GetStreamBySsrc(const StreamParamsVec& streams, uint32 ssrc, 146 StreamParams* stream_out) { 147 return GetStream(streams, StreamSelector(ssrc), stream_out); 148 } 149 150 bool GetStreamByIds(const StreamParamsVec& streams, 151 const std::string& groupid, 152 const std::string& id, 153 StreamParams* stream_out) { 154 return GetStream(streams, StreamSelector(groupid, id), stream_out); 155 } 156 157 bool RemoveStream(StreamParamsVec* streams, 158 const StreamSelector& selector) { 159 bool ret = false; 160 for (StreamParamsVec::iterator stream = streams->begin(); 161 stream != streams->end(); ) { 162 if (selector.Matches(*stream)) { 163 stream = streams->erase(stream); 164 ret = true; 165 } else { 166 ++stream; 167 } 168 } 169 return ret; 170 } 171 172 bool RemoveStreamBySsrc(StreamParamsVec* streams, uint32 ssrc) { 173 return RemoveStream(streams, StreamSelector(ssrc)); 174 } 175 176 bool RemoveStreamByIds(StreamParamsVec* streams, 177 const std::string& groupid, 178 const std::string& id) { 179 return RemoveStream(streams, StreamSelector(groupid, id)); 180 } 181 182 } // namespace cricket 183