| Index: webrtc/api/webrtcsdp.cc
|
| diff --git a/webrtc/api/webrtcsdp.cc b/webrtc/api/webrtcsdp.cc
|
| index 90e0007628ff5d9b94d2bc4063f37cea71d38a52..8497f4c5fa9bbc5f79e16b85d26079963e55cd89 100644
|
| --- a/webrtc/api/webrtcsdp.cc
|
| +++ b/webrtc/api/webrtcsdp.cc
|
| @@ -15,6 +15,7 @@
|
| #include <stdio.h>
|
| #include <algorithm>
|
| #include <string>
|
| +#include <unordered_map>
|
| #include <vector>
|
|
|
| #include "webrtc/api/jsepicecandidate.h"
|
| @@ -269,7 +270,7 @@ static bool ParseContent(const std::string& message,
|
| const MediaType media_type,
|
| int mline_index,
|
| const std::string& protocol,
|
| - const std::vector<int>& codec_preference,
|
| + const std::vector<int>& payload_types,
|
| size_t* pos,
|
| std::string* content_name,
|
| MediaContentDescription* media_desc,
|
| @@ -287,7 +288,7 @@ static bool ParseCryptoAttribute(const std::string& line,
|
| SdpParseError* error);
|
| static bool ParseRtpmapAttribute(const std::string& line,
|
| const MediaType media_type,
|
| - const std::vector<int>& codec_preference,
|
| + const std::vector<int>& payload_types,
|
| MediaContentDescription* media_desc,
|
| SdpParseError* error);
|
| static bool ParseFmtpAttributes(const std::string& line,
|
| @@ -1651,9 +1652,8 @@ bool AddSctpDataCodec(DataContentDescription* media_desc,
|
| NULL);
|
| }
|
| // Add the SCTP Port number as a pseudo-codec "port" parameter
|
| - cricket::DataCodec codec_port(
|
| - cricket::kGoogleSctpDataCodecId, cricket::kGoogleSctpDataCodecName,
|
| - 0);
|
| + cricket::DataCodec codec_port(cricket::kGoogleSctpDataCodecId,
|
| + cricket::kGoogleSctpDataCodecName);
|
| codec_port.SetParam(cricket::kCodecParamPort, sctp_port);
|
| LOG(INFO) << "AddSctpDataCodec: Got SCTP Port Number "
|
| << sctp_port;
|
| @@ -2179,9 +2179,8 @@ void MaybeCreateStaticPayloadAudioCodecs(
|
| if (!media_desc) {
|
| return;
|
| }
|
| - int preference = static_cast<int>(fmts.size());
|
| + RTC_DCHECK(media_desc->codecs().empty());
|
| std::vector<int>::const_iterator it = fmts.begin();
|
| - bool add_new_codec = false;
|
| for (; it != fmts.end(); ++it) {
|
| int payload_type = *it;
|
| if (!media_desc->HasCodec(payload_type) &&
|
| @@ -2191,14 +2190,8 @@ void MaybeCreateStaticPayloadAudioCodecs(
|
| int clock_rate = kStaticPayloadAudioCodecs[payload_type].clockrate;
|
| size_t channels = kStaticPayloadAudioCodecs[payload_type].channels;
|
| media_desc->AddCodec(cricket::AudioCodec(payload_type, encoding_name,
|
| - clock_rate, 0, channels,
|
| - preference));
|
| - add_new_codec = true;
|
| + clock_rate, 0, channels));
|
| }
|
| - --preference;
|
| - }
|
| - if (add_new_codec) {
|
| - media_desc->SortCodecs();
|
| }
|
| }
|
|
|
| @@ -2207,7 +2200,7 @@ static C* ParseContentDescription(const std::string& message,
|
| const MediaType media_type,
|
| int mline_index,
|
| const std::string& protocol,
|
| - const std::vector<int>& codec_preference,
|
| + const std::vector<int>& payload_types,
|
| size_t* pos,
|
| std::string* content_name,
|
| TransportDescription* transport,
|
| @@ -2228,14 +2221,28 @@ static C* ParseContentDescription(const std::string& message,
|
| ASSERT(false);
|
| break;
|
| }
|
| - if (!ParseContent(message, media_type, mline_index, protocol,
|
| - codec_preference, pos, content_name,
|
| - media_desc, transport, candidates, error)) {
|
| + if (!ParseContent(message, media_type, mline_index, protocol, payload_types,
|
| + pos, content_name, media_desc, transport, candidates,
|
| + error)) {
|
| delete media_desc;
|
| return NULL;
|
| }
|
| // Sort the codecs according to the m-line fmt list.
|
| - media_desc->SortCodecs();
|
| + std::unordered_map<int, int> payload_type_preferences;
|
| + // "size + 1" so that the lowest preference payload type has a preference of
|
| + // 1, which is greater than the default (0) for payload types not in the fmt
|
| + // list.
|
| + int preference = static_cast<int>(payload_types.size() + 1);
|
| + for (int pt : payload_types) {
|
| + payload_type_preferences[pt] = preference--;
|
| + }
|
| + std::vector<typename C::CodecType> codecs = media_desc->codecs();
|
| + std::sort(codecs.begin(), codecs.end(), [&payload_type_preferences](
|
| + const typename C::CodecType& a,
|
| + const typename C::CodecType& b) {
|
| + return payload_type_preferences[a.id] > payload_type_preferences[b.id];
|
| + });
|
| + media_desc->set_codecs(codecs);
|
| return media_desc;
|
| }
|
|
|
| @@ -2274,7 +2281,7 @@ bool ParseMediaDescription(const std::string& message,
|
| std::string protocol = fields[2];
|
|
|
| // <fmt>
|
| - std::vector<int> codec_preference;
|
| + std::vector<int> payload_types;
|
| if (IsRtp(protocol)) {
|
| for (size_t j = 3 ; j < fields.size(); ++j) {
|
| // TODO(wu): Remove when below bug is fixed.
|
| @@ -2287,7 +2294,7 @@ bool ParseMediaDescription(const std::string& message,
|
| if (!GetPayloadTypeFromString(line, fields[j], &pl, error)) {
|
| return false;
|
| }
|
| - codec_preference.push_back(pl);
|
| + payload_types.push_back(pl);
|
| }
|
| }
|
|
|
| @@ -2302,20 +2309,17 @@ bool ParseMediaDescription(const std::string& message,
|
| std::string content_name;
|
| if (HasAttribute(line, kMediaTypeVideo)) {
|
| content.reset(ParseContentDescription<VideoContentDescription>(
|
| - message, cricket::MEDIA_TYPE_VIDEO, mline_index, protocol,
|
| - codec_preference, pos, &content_name,
|
| - &transport, candidates, error));
|
| + message, cricket::MEDIA_TYPE_VIDEO, mline_index, protocol,
|
| + payload_types, pos, &content_name, &transport, candidates, error));
|
| } else if (HasAttribute(line, kMediaTypeAudio)) {
|
| content.reset(ParseContentDescription<AudioContentDescription>(
|
| - message, cricket::MEDIA_TYPE_AUDIO, mline_index, protocol,
|
| - codec_preference, pos, &content_name,
|
| - &transport, candidates, error));
|
| + message, cricket::MEDIA_TYPE_AUDIO, mline_index, protocol,
|
| + payload_types, pos, &content_name, &transport, candidates, error));
|
| } else if (HasAttribute(line, kMediaTypeData)) {
|
| DataContentDescription* data_desc =
|
| ParseContentDescription<DataContentDescription>(
|
| - message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
|
| - codec_preference, pos, &content_name,
|
| - &transport, candidates, error);
|
| + message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
|
| + payload_types, pos, &content_name, &transport, candidates, error);
|
| content.reset(data_desc);
|
|
|
| int p;
|
| @@ -2522,7 +2526,7 @@ bool ParseContent(const std::string& message,
|
| const MediaType media_type,
|
| int mline_index,
|
| const std::string& protocol,
|
| - const std::vector<int>& codec_preference,
|
| + const std::vector<int>& payload_types,
|
| size_t* pos,
|
| std::string* content_name,
|
| MediaContentDescription* media_desc,
|
| @@ -2535,7 +2539,7 @@ bool ParseContent(const std::string& message,
|
|
|
| if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
| MaybeCreateStaticPayloadAudioCodecs(
|
| - codec_preference, static_cast<AudioContentDescription*>(media_desc));
|
| + payload_types, static_cast<AudioContentDescription*>(media_desc));
|
| }
|
|
|
| // The media level "ice-ufrag" and "ice-pwd".
|
| @@ -2670,8 +2674,8 @@ bool ParseContent(const std::string& message,
|
| return false;
|
| }
|
| } else if (HasAttribute(line, kAttributeRtpmap)) {
|
| - if (!ParseRtpmapAttribute(line, media_type, codec_preference,
|
| - media_desc, error)) {
|
| + if (!ParseRtpmapAttribute(line, media_type, payload_types, media_desc,
|
| + error)) {
|
| return false;
|
| }
|
| } else if (HasAttribute(line, kCodecParamMaxPTime)) {
|
| @@ -2927,9 +2931,12 @@ bool ParseCryptoAttribute(const std::string& line,
|
| }
|
|
|
| // Updates or creates a new codec entry in the audio description with according
|
| -// to |name|, |clockrate|, |bitrate|, |channels| and |preference|.
|
| -void UpdateCodec(int payload_type, const std::string& name, int clockrate,
|
| - int bitrate, size_t channels, int preference,
|
| +// to |name|, |clockrate|, |bitrate|, and |channels|.
|
| +void UpdateCodec(int payload_type,
|
| + const std::string& name,
|
| + int clockrate,
|
| + int bitrate,
|
| + size_t channels,
|
| AudioContentDescription* audio_desc) {
|
| // Codec may already be populated with (only) optional parameters
|
| // (from an fmtp).
|
| @@ -2939,15 +2946,17 @@ void UpdateCodec(int payload_type, const std::string& name, int clockrate,
|
| codec.clockrate = clockrate;
|
| codec.bitrate = bitrate;
|
| codec.channels = channels;
|
| - codec.preference = preference;
|
| AddOrReplaceCodec<AudioContentDescription, cricket::AudioCodec>(audio_desc,
|
| codec);
|
| }
|
|
|
| // Updates or creates a new codec entry in the video description according to
|
| -// |name|, |width|, |height|, |framerate| and |preference|.
|
| -void UpdateCodec(int payload_type, const std::string& name, int width,
|
| - int height, int framerate, int preference,
|
| +// |name|, |width|, |height|, and |framerate|.
|
| +void UpdateCodec(int payload_type,
|
| + const std::string& name,
|
| + int width,
|
| + int height,
|
| + int framerate,
|
| VideoContentDescription* video_desc) {
|
| // Codec may already be populated with (only) optional parameters
|
| // (from an fmtp).
|
| @@ -2957,14 +2966,13 @@ void UpdateCodec(int payload_type, const std::string& name, int width,
|
| codec.width = width;
|
| codec.height = height;
|
| codec.framerate = framerate;
|
| - codec.preference = preference;
|
| AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
|
| codec);
|
| }
|
|
|
| bool ParseRtpmapAttribute(const std::string& line,
|
| const MediaType media_type,
|
| - const std::vector<int>& codec_preference,
|
| + const std::vector<int>& payload_types,
|
| MediaContentDescription* media_desc,
|
| SdpParseError* error) {
|
| std::vector<std::string> fields;
|
| @@ -2986,12 +2994,8 @@ bool ParseRtpmapAttribute(const std::string& line,
|
| return false;
|
| }
|
|
|
| - // Set the preference order depending on the order of the pl type in the
|
| - // <fmt> of the m-line.
|
| - const int preference = codec_preference.end() -
|
| - std::find(codec_preference.begin(), codec_preference.end(),
|
| - payload_type);
|
| - if (preference == 0) {
|
| + if (std::find(payload_types.begin(), payload_types.end(), payload_type) ==
|
| + payload_types.end()) {
|
| LOG(LS_WARNING) << "Ignore rtpmap line that did not appear in the "
|
| << "<fmt> of the m-line: " << line;
|
| return true;
|
| @@ -3021,7 +3025,7 @@ bool ParseRtpmapAttribute(const std::string& line,
|
| JsepSessionDescription::kMaxVideoCodecWidth,
|
| JsepSessionDescription::kMaxVideoCodecHeight,
|
| JsepSessionDescription::kDefaultVideoCodecFramerate,
|
| - preference, video_desc);
|
| + video_desc);
|
| } else if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
| // RFC 4566
|
| // For audio streams, <encoding parameters> indicates the number
|
| @@ -3049,12 +3053,11 @@ bool ParseRtpmapAttribute(const std::string& line,
|
| AudioContentDescription* audio_desc =
|
| static_cast<AudioContentDescription*>(media_desc);
|
| UpdateCodec(payload_type, encoding_name, clock_rate, bitrate, channels,
|
| - preference, audio_desc);
|
| + audio_desc);
|
| } else if (media_type == cricket::MEDIA_TYPE_DATA) {
|
| DataContentDescription* data_desc =
|
| static_cast<DataContentDescription*>(media_desc);
|
| - data_desc->AddCodec(cricket::DataCodec(payload_type, encoding_name,
|
| - preference));
|
| + data_desc->AddCodec(cricket::DataCodec(payload_type, encoding_name));
|
| }
|
| return true;
|
| }
|
|
|