Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: webrtc/api/webrtcsdp.cc

Issue 1845673002: Removing `preference` field from `cricket::Codec`. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing sort order (got reversed when optimizations were made) Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/jsepsessiondescription_unittest.cc ('k') | webrtc/api/webrtcsdp_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2011 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/api/webrtcsdp.h" 11 #include "webrtc/api/webrtcsdp.h"
12 12
13 #include <ctype.h> 13 #include <ctype.h>
14 #include <limits.h> 14 #include <limits.h>
15 #include <stdio.h> 15 #include <stdio.h>
16 #include <algorithm> 16 #include <algorithm>
17 #include <string> 17 #include <string>
18 #include <unordered_map>
18 #include <vector> 19 #include <vector>
19 20
20 #include "webrtc/api/jsepicecandidate.h" 21 #include "webrtc/api/jsepicecandidate.h"
21 #include "webrtc/api/jsepsessiondescription.h" 22 #include "webrtc/api/jsepsessiondescription.h"
22 #include "webrtc/base/arraysize.h" 23 #include "webrtc/base/arraysize.h"
23 #include "webrtc/base/common.h" 24 #include "webrtc/base/common.h"
24 #include "webrtc/base/logging.h" 25 #include "webrtc/base/logging.h"
25 #include "webrtc/base/messagedigest.h" 26 #include "webrtc/base/messagedigest.h"
26 #include "webrtc/base/stringutils.h" 27 #include "webrtc/base/stringutils.h"
27 #include "webrtc/media/base/codec.h" 28 #include "webrtc/media/base/codec.h"
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 const std::string& message, 263 const std::string& message,
263 const TransportDescription& session_td, 264 const TransportDescription& session_td,
264 const RtpHeaderExtensions& session_extmaps, 265 const RtpHeaderExtensions& session_extmaps,
265 size_t* pos, cricket::SessionDescription* desc, 266 size_t* pos, cricket::SessionDescription* desc,
266 std::vector<JsepIceCandidate*>* candidates, 267 std::vector<JsepIceCandidate*>* candidates,
267 SdpParseError* error); 268 SdpParseError* error);
268 static bool ParseContent(const std::string& message, 269 static bool ParseContent(const std::string& message,
269 const MediaType media_type, 270 const MediaType media_type,
270 int mline_index, 271 int mline_index,
271 const std::string& protocol, 272 const std::string& protocol,
272 const std::vector<int>& codec_preference, 273 const std::vector<int>& payload_types,
273 size_t* pos, 274 size_t* pos,
274 std::string* content_name, 275 std::string* content_name,
275 MediaContentDescription* media_desc, 276 MediaContentDescription* media_desc,
276 TransportDescription* transport, 277 TransportDescription* transport,
277 std::vector<JsepIceCandidate*>* candidates, 278 std::vector<JsepIceCandidate*>* candidates,
278 SdpParseError* error); 279 SdpParseError* error);
279 static bool ParseSsrcAttribute(const std::string& line, 280 static bool ParseSsrcAttribute(const std::string& line,
280 SsrcInfoVec* ssrc_infos, 281 SsrcInfoVec* ssrc_infos,
281 SdpParseError* error); 282 SdpParseError* error);
282 static bool ParseSsrcGroupAttribute(const std::string& line, 283 static bool ParseSsrcGroupAttribute(const std::string& line,
283 SsrcGroupVec* ssrc_groups, 284 SsrcGroupVec* ssrc_groups,
284 SdpParseError* error); 285 SdpParseError* error);
285 static bool ParseCryptoAttribute(const std::string& line, 286 static bool ParseCryptoAttribute(const std::string& line,
286 MediaContentDescription* media_desc, 287 MediaContentDescription* media_desc,
287 SdpParseError* error); 288 SdpParseError* error);
288 static bool ParseRtpmapAttribute(const std::string& line, 289 static bool ParseRtpmapAttribute(const std::string& line,
289 const MediaType media_type, 290 const MediaType media_type,
290 const std::vector<int>& codec_preference, 291 const std::vector<int>& payload_types,
291 MediaContentDescription* media_desc, 292 MediaContentDescription* media_desc,
292 SdpParseError* error); 293 SdpParseError* error);
293 static bool ParseFmtpAttributes(const std::string& line, 294 static bool ParseFmtpAttributes(const std::string& line,
294 const MediaType media_type, 295 const MediaType media_type,
295 MediaContentDescription* media_desc, 296 MediaContentDescription* media_desc,
296 SdpParseError* error); 297 SdpParseError* error);
297 static bool ParseFmtpParam(const std::string& line, std::string* parameter, 298 static bool ParseFmtpParam(const std::string& line, std::string* parameter,
298 std::string* value, SdpParseError* error); 299 std::string* value, SdpParseError* error);
299 static bool ParseCandidate(const std::string& message, Candidate* candidate, 300 static bool ParseCandidate(const std::string& message, Candidate* candidate,
300 SdpParseError* error, bool is_raw); 301 SdpParseError* error, bool is_raw);
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 } 1645 }
1645 1646
1646 bool AddSctpDataCodec(DataContentDescription* media_desc, 1647 bool AddSctpDataCodec(DataContentDescription* media_desc,
1647 int sctp_port) { 1648 int sctp_port) {
1648 if (media_desc->HasCodec(cricket::kGoogleSctpDataCodecId)) { 1649 if (media_desc->HasCodec(cricket::kGoogleSctpDataCodecId)) {
1649 return ParseFailed("", 1650 return ParseFailed("",
1650 "Can't have multiple sctp port attributes.", 1651 "Can't have multiple sctp port attributes.",
1651 NULL); 1652 NULL);
1652 } 1653 }
1653 // Add the SCTP Port number as a pseudo-codec "port" parameter 1654 // Add the SCTP Port number as a pseudo-codec "port" parameter
1654 cricket::DataCodec codec_port( 1655 cricket::DataCodec codec_port(cricket::kGoogleSctpDataCodecId,
1655 cricket::kGoogleSctpDataCodecId, cricket::kGoogleSctpDataCodecName, 1656 cricket::kGoogleSctpDataCodecName);
1656 0);
1657 codec_port.SetParam(cricket::kCodecParamPort, sctp_port); 1657 codec_port.SetParam(cricket::kCodecParamPort, sctp_port);
1658 LOG(INFO) << "AddSctpDataCodec: Got SCTP Port Number " 1658 LOG(INFO) << "AddSctpDataCodec: Got SCTP Port Number "
1659 << sctp_port; 1659 << sctp_port;
1660 media_desc->AddCodec(codec_port); 1660 media_desc->AddCodec(codec_port);
1661 return true; 1661 return true;
1662 } 1662 }
1663 1663
1664 bool GetMinValue(const std::vector<int>& values, int* value) { 1664 bool GetMinValue(const std::vector<int>& values, int* value) {
1665 if (values.empty()) { 1665 if (values.empty()) {
1666 return false; 1666 return false;
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2172 { "DVI4", 11025, 1 }, 2172 { "DVI4", 11025, 1 },
2173 { "DVI4", 22050, 1 }, 2173 { "DVI4", 22050, 1 },
2174 { "G729", 8000, 1 }, 2174 { "G729", 8000, 1 },
2175 }; 2175 };
2176 2176
2177 void MaybeCreateStaticPayloadAudioCodecs( 2177 void MaybeCreateStaticPayloadAudioCodecs(
2178 const std::vector<int>& fmts, AudioContentDescription* media_desc) { 2178 const std::vector<int>& fmts, AudioContentDescription* media_desc) {
2179 if (!media_desc) { 2179 if (!media_desc) {
2180 return; 2180 return;
2181 } 2181 }
2182 int preference = static_cast<int>(fmts.size()); 2182 RTC_DCHECK(media_desc->codecs().empty());
2183 std::vector<int>::const_iterator it = fmts.begin(); 2183 std::vector<int>::const_iterator it = fmts.begin();
2184 bool add_new_codec = false;
2185 for (; it != fmts.end(); ++it) { 2184 for (; it != fmts.end(); ++it) {
2186 int payload_type = *it; 2185 int payload_type = *it;
2187 if (!media_desc->HasCodec(payload_type) && 2186 if (!media_desc->HasCodec(payload_type) &&
2188 payload_type >= 0 && 2187 payload_type >= 0 &&
2189 payload_type < arraysize(kStaticPayloadAudioCodecs)) { 2188 payload_type < arraysize(kStaticPayloadAudioCodecs)) {
2190 std::string encoding_name = kStaticPayloadAudioCodecs[payload_type].name; 2189 std::string encoding_name = kStaticPayloadAudioCodecs[payload_type].name;
2191 int clock_rate = kStaticPayloadAudioCodecs[payload_type].clockrate; 2190 int clock_rate = kStaticPayloadAudioCodecs[payload_type].clockrate;
2192 size_t channels = kStaticPayloadAudioCodecs[payload_type].channels; 2191 size_t channels = kStaticPayloadAudioCodecs[payload_type].channels;
2193 media_desc->AddCodec(cricket::AudioCodec(payload_type, encoding_name, 2192 media_desc->AddCodec(cricket::AudioCodec(payload_type, encoding_name,
2194 clock_rate, 0, channels, 2193 clock_rate, 0, channels));
2195 preference));
2196 add_new_codec = true;
2197 } 2194 }
2198 --preference;
2199 }
2200 if (add_new_codec) {
2201 media_desc->SortCodecs();
2202 } 2195 }
2203 } 2196 }
2204 2197
2205 template <class C> 2198 template <class C>
2206 static C* ParseContentDescription(const std::string& message, 2199 static C* ParseContentDescription(const std::string& message,
2207 const MediaType media_type, 2200 const MediaType media_type,
2208 int mline_index, 2201 int mline_index,
2209 const std::string& protocol, 2202 const std::string& protocol,
2210 const std::vector<int>& codec_preference, 2203 const std::vector<int>& payload_types,
2211 size_t* pos, 2204 size_t* pos,
2212 std::string* content_name, 2205 std::string* content_name,
2213 TransportDescription* transport, 2206 TransportDescription* transport,
2214 std::vector<JsepIceCandidate*>* candidates, 2207 std::vector<JsepIceCandidate*>* candidates,
2215 webrtc::SdpParseError* error) { 2208 webrtc::SdpParseError* error) {
2216 C* media_desc = new C(); 2209 C* media_desc = new C();
2217 switch (media_type) { 2210 switch (media_type) {
2218 case cricket::MEDIA_TYPE_AUDIO: 2211 case cricket::MEDIA_TYPE_AUDIO:
2219 *content_name = cricket::CN_AUDIO; 2212 *content_name = cricket::CN_AUDIO;
2220 break; 2213 break;
2221 case cricket::MEDIA_TYPE_VIDEO: 2214 case cricket::MEDIA_TYPE_VIDEO:
2222 *content_name = cricket::CN_VIDEO; 2215 *content_name = cricket::CN_VIDEO;
2223 break; 2216 break;
2224 case cricket::MEDIA_TYPE_DATA: 2217 case cricket::MEDIA_TYPE_DATA:
2225 *content_name = cricket::CN_DATA; 2218 *content_name = cricket::CN_DATA;
2226 break; 2219 break;
2227 default: 2220 default:
2228 ASSERT(false); 2221 ASSERT(false);
2229 break; 2222 break;
2230 } 2223 }
2231 if (!ParseContent(message, media_type, mline_index, protocol, 2224 if (!ParseContent(message, media_type, mline_index, protocol, payload_types,
2232 codec_preference, pos, content_name, 2225 pos, content_name, media_desc, transport, candidates,
2233 media_desc, transport, candidates, error)) { 2226 error)) {
2234 delete media_desc; 2227 delete media_desc;
2235 return NULL; 2228 return NULL;
2236 } 2229 }
2237 // Sort the codecs according to the m-line fmt list. 2230 // Sort the codecs according to the m-line fmt list.
2238 media_desc->SortCodecs(); 2231 std::unordered_map<int, int> payload_type_preferences;
2232 // "size + 1" so that the lowest preference payload type has a preference of
2233 // 1, which is greater than the default (0) for payload types not in the fmt
2234 // list.
2235 int preference = static_cast<int>(payload_types.size() + 1);
2236 for (int pt : payload_types) {
2237 payload_type_preferences[pt] = preference--;
2238 }
2239 std::vector<typename C::CodecType> codecs = media_desc->codecs();
2240 std::sort(codecs.begin(), codecs.end(), [&payload_type_preferences](
2241 const typename C::CodecType& a,
2242 const typename C::CodecType& b) {
2243 return payload_type_preferences[a.id] > payload_type_preferences[b.id];
2244 });
2245 media_desc->set_codecs(codecs);
2239 return media_desc; 2246 return media_desc;
2240 } 2247 }
2241 2248
2242 bool ParseMediaDescription(const std::string& message, 2249 bool ParseMediaDescription(const std::string& message,
2243 const TransportDescription& session_td, 2250 const TransportDescription& session_td,
2244 const RtpHeaderExtensions& session_extmaps, 2251 const RtpHeaderExtensions& session_extmaps,
2245 size_t* pos, 2252 size_t* pos,
2246 cricket::SessionDescription* desc, 2253 cricket::SessionDescription* desc,
2247 std::vector<JsepIceCandidate*>* candidates, 2254 std::vector<JsepIceCandidate*>* candidates,
2248 SdpParseError* error) { 2255 SdpParseError* error) {
(...skipping 18 matching lines...) Expand all
2267 // RFC 3264 2274 // RFC 3264
2268 // To reject an offered stream, the port number in the corresponding stream 2275 // To reject an offered stream, the port number in the corresponding stream
2269 // in the answer MUST be set to zero. 2276 // in the answer MUST be set to zero.
2270 if (fields[1] == kMediaPortRejected) { 2277 if (fields[1] == kMediaPortRejected) {
2271 rejected = true; 2278 rejected = true;
2272 } 2279 }
2273 2280
2274 std::string protocol = fields[2]; 2281 std::string protocol = fields[2];
2275 2282
2276 // <fmt> 2283 // <fmt>
2277 std::vector<int> codec_preference; 2284 std::vector<int> payload_types;
2278 if (IsRtp(protocol)) { 2285 if (IsRtp(protocol)) {
2279 for (size_t j = 3 ; j < fields.size(); ++j) { 2286 for (size_t j = 3 ; j < fields.size(); ++j) {
2280 // TODO(wu): Remove when below bug is fixed. 2287 // TODO(wu): Remove when below bug is fixed.
2281 // https://bugzilla.mozilla.org/show_bug.cgi?id=996329 2288 // https://bugzilla.mozilla.org/show_bug.cgi?id=996329
2282 if (fields[j].empty() && j == fields.size() - 1) { 2289 if (fields[j].empty() && j == fields.size() - 1) {
2283 continue; 2290 continue;
2284 } 2291 }
2285 2292
2286 int pl = 0; 2293 int pl = 0;
2287 if (!GetPayloadTypeFromString(line, fields[j], &pl, error)) { 2294 if (!GetPayloadTypeFromString(line, fields[j], &pl, error)) {
2288 return false; 2295 return false;
2289 } 2296 }
2290 codec_preference.push_back(pl); 2297 payload_types.push_back(pl);
2291 } 2298 }
2292 } 2299 }
2293 2300
2294 // Make a temporary TransportDescription based on |session_td|. 2301 // Make a temporary TransportDescription based on |session_td|.
2295 // Some of this gets overwritten by ParseContent. 2302 // Some of this gets overwritten by ParseContent.
2296 TransportDescription transport( 2303 TransportDescription transport(
2297 session_td.transport_options, session_td.ice_ufrag, session_td.ice_pwd, 2304 session_td.transport_options, session_td.ice_ufrag, session_td.ice_pwd,
2298 session_td.ice_mode, session_td.connection_role, 2305 session_td.ice_mode, session_td.connection_role,
2299 session_td.identity_fingerprint.get()); 2306 session_td.identity_fingerprint.get());
2300 2307
2301 rtc::scoped_ptr<MediaContentDescription> content; 2308 rtc::scoped_ptr<MediaContentDescription> content;
2302 std::string content_name; 2309 std::string content_name;
2303 if (HasAttribute(line, kMediaTypeVideo)) { 2310 if (HasAttribute(line, kMediaTypeVideo)) {
2304 content.reset(ParseContentDescription<VideoContentDescription>( 2311 content.reset(ParseContentDescription<VideoContentDescription>(
2305 message, cricket::MEDIA_TYPE_VIDEO, mline_index, protocol, 2312 message, cricket::MEDIA_TYPE_VIDEO, mline_index, protocol,
2306 codec_preference, pos, &content_name, 2313 payload_types, pos, &content_name, &transport, candidates, error));
2307 &transport, candidates, error));
2308 } else if (HasAttribute(line, kMediaTypeAudio)) { 2314 } else if (HasAttribute(line, kMediaTypeAudio)) {
2309 content.reset(ParseContentDescription<AudioContentDescription>( 2315 content.reset(ParseContentDescription<AudioContentDescription>(
2310 message, cricket::MEDIA_TYPE_AUDIO, mline_index, protocol, 2316 message, cricket::MEDIA_TYPE_AUDIO, mline_index, protocol,
2311 codec_preference, pos, &content_name, 2317 payload_types, pos, &content_name, &transport, candidates, error));
2312 &transport, candidates, error));
2313 } else if (HasAttribute(line, kMediaTypeData)) { 2318 } else if (HasAttribute(line, kMediaTypeData)) {
2314 DataContentDescription* data_desc = 2319 DataContentDescription* data_desc =
2315 ParseContentDescription<DataContentDescription>( 2320 ParseContentDescription<DataContentDescription>(
2316 message, cricket::MEDIA_TYPE_DATA, mline_index, protocol, 2321 message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
2317 codec_preference, pos, &content_name, 2322 payload_types, pos, &content_name, &transport, candidates, error);
2318 &transport, candidates, error);
2319 content.reset(data_desc); 2323 content.reset(data_desc);
2320 2324
2321 int p; 2325 int p;
2322 if (data_desc && IsDtlsSctp(protocol) && rtc::FromString(fields[3], &p)) { 2326 if (data_desc && IsDtlsSctp(protocol) && rtc::FromString(fields[3], &p)) {
2323 if (!AddSctpDataCodec(data_desc, p)) 2327 if (!AddSctpDataCodec(data_desc, p))
2324 return false; 2328 return false;
2325 } 2329 }
2326 } else { 2330 } else {
2327 LOG(LS_WARNING) << "Unsupported media type: " << line; 2331 LOG(LS_WARNING) << "Unsupported media type: " << line;
2328 continue; 2332 continue;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 iter != codecs.end(); ++iter) { 2519 iter != codecs.end(); ++iter) {
2516 iter->params[name] = value; 2520 iter->params[name] = value;
2517 } 2521 }
2518 audio_desc->set_codecs(codecs); 2522 audio_desc->set_codecs(codecs);
2519 } 2523 }
2520 2524
2521 bool ParseContent(const std::string& message, 2525 bool ParseContent(const std::string& message,
2522 const MediaType media_type, 2526 const MediaType media_type,
2523 int mline_index, 2527 int mline_index,
2524 const std::string& protocol, 2528 const std::string& protocol,
2525 const std::vector<int>& codec_preference, 2529 const std::vector<int>& payload_types,
2526 size_t* pos, 2530 size_t* pos,
2527 std::string* content_name, 2531 std::string* content_name,
2528 MediaContentDescription* media_desc, 2532 MediaContentDescription* media_desc,
2529 TransportDescription* transport, 2533 TransportDescription* transport,
2530 std::vector<JsepIceCandidate*>* candidates, 2534 std::vector<JsepIceCandidate*>* candidates,
2531 SdpParseError* error) { 2535 SdpParseError* error) {
2532 ASSERT(media_desc != NULL); 2536 ASSERT(media_desc != NULL);
2533 ASSERT(content_name != NULL); 2537 ASSERT(content_name != NULL);
2534 ASSERT(transport != NULL); 2538 ASSERT(transport != NULL);
2535 2539
2536 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 2540 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2537 MaybeCreateStaticPayloadAudioCodecs( 2541 MaybeCreateStaticPayloadAudioCodecs(
2538 codec_preference, static_cast<AudioContentDescription*>(media_desc)); 2542 payload_types, static_cast<AudioContentDescription*>(media_desc));
2539 } 2543 }
2540 2544
2541 // The media level "ice-ufrag" and "ice-pwd". 2545 // The media level "ice-ufrag" and "ice-pwd".
2542 // The candidates before update the media level "ice-pwd" and "ice-ufrag". 2546 // The candidates before update the media level "ice-pwd" and "ice-ufrag".
2543 Candidates candidates_orig; 2547 Candidates candidates_orig;
2544 std::string line; 2548 std::string line;
2545 std::string mline_id; 2549 std::string mline_id;
2546 // Tracks created out of the ssrc attributes. 2550 // Tracks created out of the ssrc attributes.
2547 StreamParamsVec tracks; 2551 StreamParamsVec tracks;
2548 SsrcInfoVec ssrc_infos; 2552 SsrcInfoVec ssrc_infos;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 } 2667 }
2664 } else if (HasAttribute(line, kAttributeSsrc)) { 2668 } else if (HasAttribute(line, kAttributeSsrc)) {
2665 if (!ParseSsrcAttribute(line, &ssrc_infos, error)) { 2669 if (!ParseSsrcAttribute(line, &ssrc_infos, error)) {
2666 return false; 2670 return false;
2667 } 2671 }
2668 } else if (HasAttribute(line, kAttributeCrypto)) { 2672 } else if (HasAttribute(line, kAttributeCrypto)) {
2669 if (!ParseCryptoAttribute(line, media_desc, error)) { 2673 if (!ParseCryptoAttribute(line, media_desc, error)) {
2670 return false; 2674 return false;
2671 } 2675 }
2672 } else if (HasAttribute(line, kAttributeRtpmap)) { 2676 } else if (HasAttribute(line, kAttributeRtpmap)) {
2673 if (!ParseRtpmapAttribute(line, media_type, codec_preference, 2677 if (!ParseRtpmapAttribute(line, media_type, payload_types, media_desc,
2674 media_desc, error)) { 2678 error)) {
2675 return false; 2679 return false;
2676 } 2680 }
2677 } else if (HasAttribute(line, kCodecParamMaxPTime)) { 2681 } else if (HasAttribute(line, kCodecParamMaxPTime)) {
2678 if (!GetValue(line, kCodecParamMaxPTime, &maxptime_as_string, error)) { 2682 if (!GetValue(line, kCodecParamMaxPTime, &maxptime_as_string, error)) {
2679 return false; 2683 return false;
2680 } 2684 }
2681 } else if (HasAttribute(line, kAttributeRtcpFb)) { 2685 } else if (HasAttribute(line, kAttributeRtcpFb)) {
2682 if (!ParseRtcpFbAttribute(line, media_type, media_desc, error)) { 2686 if (!ParseRtcpFbAttribute(line, media_type, media_desc, error)) {
2683 return false; 2687 return false;
2684 } 2688 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 std::string session_params; 2924 std::string session_params;
2921 if (fields.size() > 3) { 2925 if (fields.size() > 3) {
2922 session_params = fields[3]; 2926 session_params = fields[3];
2923 } 2927 }
2924 media_desc->AddCrypto(CryptoParams(tag, crypto_suite, key_params, 2928 media_desc->AddCrypto(CryptoParams(tag, crypto_suite, key_params,
2925 session_params)); 2929 session_params));
2926 return true; 2930 return true;
2927 } 2931 }
2928 2932
2929 // Updates or creates a new codec entry in the audio description with according 2933 // Updates or creates a new codec entry in the audio description with according
2930 // to |name|, |clockrate|, |bitrate|, |channels| and |preference|. 2934 // to |name|, |clockrate|, |bitrate|, and |channels|.
2931 void UpdateCodec(int payload_type, const std::string& name, int clockrate, 2935 void UpdateCodec(int payload_type,
2932 int bitrate, size_t channels, int preference, 2936 const std::string& name,
2937 int clockrate,
2938 int bitrate,
2939 size_t channels,
2933 AudioContentDescription* audio_desc) { 2940 AudioContentDescription* audio_desc) {
2934 // Codec may already be populated with (only) optional parameters 2941 // Codec may already be populated with (only) optional parameters
2935 // (from an fmtp). 2942 // (from an fmtp).
2936 cricket::AudioCodec codec = 2943 cricket::AudioCodec codec =
2937 GetCodecWithPayloadType(audio_desc->codecs(), payload_type); 2944 GetCodecWithPayloadType(audio_desc->codecs(), payload_type);
2938 codec.name = name; 2945 codec.name = name;
2939 codec.clockrate = clockrate; 2946 codec.clockrate = clockrate;
2940 codec.bitrate = bitrate; 2947 codec.bitrate = bitrate;
2941 codec.channels = channels; 2948 codec.channels = channels;
2942 codec.preference = preference;
2943 AddOrReplaceCodec<AudioContentDescription, cricket::AudioCodec>(audio_desc, 2949 AddOrReplaceCodec<AudioContentDescription, cricket::AudioCodec>(audio_desc,
2944 codec); 2950 codec);
2945 } 2951 }
2946 2952
2947 // Updates or creates a new codec entry in the video description according to 2953 // Updates or creates a new codec entry in the video description according to
2948 // |name|, |width|, |height|, |framerate| and |preference|. 2954 // |name|, |width|, |height|, and |framerate|.
2949 void UpdateCodec(int payload_type, const std::string& name, int width, 2955 void UpdateCodec(int payload_type,
2950 int height, int framerate, int preference, 2956 const std::string& name,
2957 int width,
2958 int height,
2959 int framerate,
2951 VideoContentDescription* video_desc) { 2960 VideoContentDescription* video_desc) {
2952 // Codec may already be populated with (only) optional parameters 2961 // Codec may already be populated with (only) optional parameters
2953 // (from an fmtp). 2962 // (from an fmtp).
2954 cricket::VideoCodec codec = 2963 cricket::VideoCodec codec =
2955 GetCodecWithPayloadType(video_desc->codecs(), payload_type); 2964 GetCodecWithPayloadType(video_desc->codecs(), payload_type);
2956 codec.name = name; 2965 codec.name = name;
2957 codec.width = width; 2966 codec.width = width;
2958 codec.height = height; 2967 codec.height = height;
2959 codec.framerate = framerate; 2968 codec.framerate = framerate;
2960 codec.preference = preference;
2961 AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc, 2969 AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
2962 codec); 2970 codec);
2963 } 2971 }
2964 2972
2965 bool ParseRtpmapAttribute(const std::string& line, 2973 bool ParseRtpmapAttribute(const std::string& line,
2966 const MediaType media_type, 2974 const MediaType media_type,
2967 const std::vector<int>& codec_preference, 2975 const std::vector<int>& payload_types,
2968 MediaContentDescription* media_desc, 2976 MediaContentDescription* media_desc,
2969 SdpParseError* error) { 2977 SdpParseError* error) {
2970 std::vector<std::string> fields; 2978 std::vector<std::string> fields;
2971 rtc::split(line.substr(kLinePrefixLength), 2979 rtc::split(line.substr(kLinePrefixLength),
2972 kSdpDelimiterSpace, &fields); 2980 kSdpDelimiterSpace, &fields);
2973 // RFC 4566 2981 // RFC 4566
2974 // a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encodingparameters>] 2982 // a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encodingparameters>]
2975 const size_t expected_min_fields = 2; 2983 const size_t expected_min_fields = 2;
2976 if (fields.size() < expected_min_fields) { 2984 if (fields.size() < expected_min_fields) {
2977 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); 2985 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error);
2978 } 2986 }
2979 std::string payload_type_value; 2987 std::string payload_type_value;
2980 if (!GetValue(fields[0], kAttributeRtpmap, &payload_type_value, error)) { 2988 if (!GetValue(fields[0], kAttributeRtpmap, &payload_type_value, error)) {
2981 return false; 2989 return false;
2982 } 2990 }
2983 int payload_type = 0; 2991 int payload_type = 0;
2984 if (!GetPayloadTypeFromString(line, payload_type_value, &payload_type, 2992 if (!GetPayloadTypeFromString(line, payload_type_value, &payload_type,
2985 error)) { 2993 error)) {
2986 return false; 2994 return false;
2987 } 2995 }
2988 2996
2989 // Set the preference order depending on the order of the pl type in the 2997 if (std::find(payload_types.begin(), payload_types.end(), payload_type) ==
2990 // <fmt> of the m-line. 2998 payload_types.end()) {
2991 const int preference = codec_preference.end() -
2992 std::find(codec_preference.begin(), codec_preference.end(),
2993 payload_type);
2994 if (preference == 0) {
2995 LOG(LS_WARNING) << "Ignore rtpmap line that did not appear in the " 2999 LOG(LS_WARNING) << "Ignore rtpmap line that did not appear in the "
2996 << "<fmt> of the m-line: " << line; 3000 << "<fmt> of the m-line: " << line;
2997 return true; 3001 return true;
2998 } 3002 }
2999 const std::string& encoder = fields[1]; 3003 const std::string& encoder = fields[1];
3000 std::vector<std::string> codec_params; 3004 std::vector<std::string> codec_params;
3001 rtc::split(encoder, '/', &codec_params); 3005 rtc::split(encoder, '/', &codec_params);
3002 // <encoding name>/<clock rate>[/<encodingparameters>] 3006 // <encoding name>/<clock rate>[/<encodingparameters>]
3003 // 2 mandatory fields 3007 // 2 mandatory fields
3004 if (codec_params.size() < 2 || codec_params.size() > 3) { 3008 if (codec_params.size() < 2 || codec_params.size() > 3) {
3005 return ParseFailed(line, 3009 return ParseFailed(line,
3006 "Expected format \"<encoding name>/<clock rate>" 3010 "Expected format \"<encoding name>/<clock rate>"
3007 "[/<encodingparameters>]\".", 3011 "[/<encodingparameters>]\".",
3008 error); 3012 error);
3009 } 3013 }
3010 const std::string& encoding_name = codec_params[0]; 3014 const std::string& encoding_name = codec_params[0];
3011 int clock_rate = 0; 3015 int clock_rate = 0;
3012 if (!GetValueFromString(line, codec_params[1], &clock_rate, error)) { 3016 if (!GetValueFromString(line, codec_params[1], &clock_rate, error)) {
3013 return false; 3017 return false;
3014 } 3018 }
3015 if (media_type == cricket::MEDIA_TYPE_VIDEO) { 3019 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
3016 VideoContentDescription* video_desc = 3020 VideoContentDescription* video_desc =
3017 static_cast<VideoContentDescription*>(media_desc); 3021 static_cast<VideoContentDescription*>(media_desc);
3018 // TODO: We will send resolution in SDP. For now use 3022 // TODO: We will send resolution in SDP. For now use
3019 // JsepSessionDescription::kMaxVideoCodecWidth and kMaxVideoCodecHeight. 3023 // JsepSessionDescription::kMaxVideoCodecWidth and kMaxVideoCodecHeight.
3020 UpdateCodec(payload_type, encoding_name, 3024 UpdateCodec(payload_type, encoding_name,
3021 JsepSessionDescription::kMaxVideoCodecWidth, 3025 JsepSessionDescription::kMaxVideoCodecWidth,
3022 JsepSessionDescription::kMaxVideoCodecHeight, 3026 JsepSessionDescription::kMaxVideoCodecHeight,
3023 JsepSessionDescription::kDefaultVideoCodecFramerate, 3027 JsepSessionDescription::kDefaultVideoCodecFramerate,
3024 preference, video_desc); 3028 video_desc);
3025 } else if (media_type == cricket::MEDIA_TYPE_AUDIO) { 3029 } else if (media_type == cricket::MEDIA_TYPE_AUDIO) {
3026 // RFC 4566 3030 // RFC 4566
3027 // For audio streams, <encoding parameters> indicates the number 3031 // For audio streams, <encoding parameters> indicates the number
3028 // of audio channels. This parameter is OPTIONAL and may be 3032 // of audio channels. This parameter is OPTIONAL and may be
3029 // omitted if the number of channels is one, provided that no 3033 // omitted if the number of channels is one, provided that no
3030 // additional parameters are needed. 3034 // additional parameters are needed.
3031 size_t channels = 1; 3035 size_t channels = 1;
3032 if (codec_params.size() == 3) { 3036 if (codec_params.size() == 3) {
3033 if (!GetValueFromString(line, codec_params[2], &channels, error)) { 3037 if (!GetValueFromString(line, codec_params[2], &channels, error)) {
3034 return false; 3038 return false;
3035 } 3039 }
3036 } 3040 }
3037 int bitrate = 0; 3041 int bitrate = 0;
3038 // The default behavior for ISAC (bitrate == 0) in webrtcvoiceengine.cc 3042 // The default behavior for ISAC (bitrate == 0) in webrtcvoiceengine.cc
3039 // (specifically FindWebRtcCodec) is bandwidth-adaptive variable bitrate. 3043 // (specifically FindWebRtcCodec) is bandwidth-adaptive variable bitrate.
3040 // The bandwidth adaptation doesn't always work well, so this code 3044 // The bandwidth adaptation doesn't always work well, so this code
3041 // sets a fixed target bitrate instead. 3045 // sets a fixed target bitrate instead.
3042 if (_stricmp(encoding_name.c_str(), kIsacCodecName) == 0) { 3046 if (_stricmp(encoding_name.c_str(), kIsacCodecName) == 0) {
3043 if (clock_rate <= 16000) { 3047 if (clock_rate <= 16000) {
3044 bitrate = kIsacWbDefaultRate; 3048 bitrate = kIsacWbDefaultRate;
3045 } else { 3049 } else {
3046 bitrate = kIsacSwbDefaultRate; 3050 bitrate = kIsacSwbDefaultRate;
3047 } 3051 }
3048 } 3052 }
3049 AudioContentDescription* audio_desc = 3053 AudioContentDescription* audio_desc =
3050 static_cast<AudioContentDescription*>(media_desc); 3054 static_cast<AudioContentDescription*>(media_desc);
3051 UpdateCodec(payload_type, encoding_name, clock_rate, bitrate, channels, 3055 UpdateCodec(payload_type, encoding_name, clock_rate, bitrate, channels,
3052 preference, audio_desc); 3056 audio_desc);
3053 } else if (media_type == cricket::MEDIA_TYPE_DATA) { 3057 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
3054 DataContentDescription* data_desc = 3058 DataContentDescription* data_desc =
3055 static_cast<DataContentDescription*>(media_desc); 3059 static_cast<DataContentDescription*>(media_desc);
3056 data_desc->AddCodec(cricket::DataCodec(payload_type, encoding_name, 3060 data_desc->AddCodec(cricket::DataCodec(payload_type, encoding_name));
3057 preference));
3058 } 3061 }
3059 return true; 3062 return true;
3060 } 3063 }
3061 3064
3062 bool ParseFmtpParam(const std::string& line, std::string* parameter, 3065 bool ParseFmtpParam(const std::string& line, std::string* parameter,
3063 std::string* value, SdpParseError* error) { 3066 std::string* value, SdpParseError* error) {
3064 if (!rtc::tokenize_first(line, kSdpDelimiterEqual, parameter, value)) { 3067 if (!rtc::tokenize_first(line, kSdpDelimiterEqual, parameter, value)) {
3065 ParseFailed(line, "Unable to parse fmtp parameter. \'=\' missing.", error); 3068 ParseFailed(line, "Unable to parse fmtp parameter. \'=\' missing.", error);
3066 return false; 3069 return false;
3067 } 3070 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3168 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( 3171 UpdateCodec<AudioContentDescription, cricket::AudioCodec>(
3169 media_desc, payload_type, feedback_param); 3172 media_desc, payload_type, feedback_param);
3170 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { 3173 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
3171 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( 3174 UpdateCodec<VideoContentDescription, cricket::VideoCodec>(
3172 media_desc, payload_type, feedback_param); 3175 media_desc, payload_type, feedback_param);
3173 } 3176 }
3174 return true; 3177 return true;
3175 } 3178 }
3176 3179
3177 } // namespace webrtc 3180 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/jsepsessiondescription_unittest.cc ('k') | webrtc/api/webrtcsdp_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698