Move codecs() to MediaContentDescription
allowing for a lot of de-templating BUG=webrtc:15214 Change-Id: Ibe1a5f5d704564566f24c496822a4308ba23c4dd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/319160 Commit-Queue: Philipp Hancke <phancke@microsoft.com> Reviewed-by: Florent Castelli <orphis@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40774}
This commit is contained in:
parent
ae82df718c
commit
f14dfed72a
@ -438,18 +438,9 @@ RTCError ValidateBundledPayloadTypes(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto type = media_description->type();
|
const auto type = media_description->type();
|
||||||
if (type == cricket::MEDIA_TYPE_AUDIO) {
|
if (type == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
RTC_DCHECK(media_description->as_audio());
|
type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
for (const auto& c : media_description->as_audio()->codecs()) {
|
for (const auto& c : media_description->codecs()) {
|
||||||
auto error = FindDuplicateCodecParameters(
|
|
||||||
c.ToCodecParameters(), payload_to_codec_parameters);
|
|
||||||
if (!error.ok()) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type == cricket::MEDIA_TYPE_VIDEO) {
|
|
||||||
RTC_DCHECK(media_description->as_video());
|
|
||||||
for (const auto& c : media_description->as_video()->codecs()) {
|
|
||||||
auto error = FindDuplicateCodecParameters(
|
auto error = FindDuplicateCodecParameters(
|
||||||
c.ToCodecParameters(), payload_to_codec_parameters);
|
c.ToCodecParameters(), payload_to_codec_parameters);
|
||||||
if (!error.ok()) {
|
if (!error.ok()) {
|
||||||
|
|||||||
@ -83,8 +83,6 @@ class MediaContentDescription {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool has_codecs() const = 0;
|
|
||||||
|
|
||||||
// Copy operator that returns an unique_ptr.
|
// Copy operator that returns an unique_ptr.
|
||||||
// Not a virtual function.
|
// Not a virtual function.
|
||||||
// If a type-specific variant of Clone() is desired, override it, or
|
// If a type-specific variant of Clone() is desired, override it, or
|
||||||
@ -234,54 +232,14 @@ class MediaContentDescription {
|
|||||||
receive_rids_ = rids;
|
receive_rids_ = rids;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
bool rtcp_mux_ = false;
|
|
||||||
bool rtcp_reduced_size_ = false;
|
|
||||||
bool remote_estimate_ = false;
|
|
||||||
int bandwidth_ = kAutoBandwidth;
|
|
||||||
std::string bandwidth_type_ = kApplicationSpecificBandwidth;
|
|
||||||
std::string protocol_;
|
|
||||||
std::vector<CryptoParams> cryptos_;
|
|
||||||
std::vector<webrtc::RtpExtension> rtp_header_extensions_;
|
|
||||||
bool rtp_header_extensions_set_ = false;
|
|
||||||
StreamParamsVec send_streams_;
|
|
||||||
bool conference_mode_ = false;
|
|
||||||
webrtc::RtpTransceiverDirection direction_ =
|
|
||||||
webrtc::RtpTransceiverDirection::kSendRecv;
|
|
||||||
rtc::SocketAddress connection_address_;
|
|
||||||
ExtmapAllowMixed extmap_allow_mixed_enum_ = kMedia;
|
|
||||||
|
|
||||||
SimulcastDescription simulcast_;
|
|
||||||
std::vector<RidDescription> receive_rids_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Copy function that returns a raw pointer. Caller will assert ownership.
|
|
||||||
// Should only be called by the Clone() function. Must be implemented
|
|
||||||
// by each final subclass.
|
|
||||||
virtual MediaContentDescription* CloneInternal() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class C>
|
|
||||||
class MediaContentDescriptionImpl : public MediaContentDescription {
|
|
||||||
public:
|
|
||||||
void set_protocol(absl::string_view protocol) override {
|
|
||||||
RTC_DCHECK(IsRtpProtocol(protocol));
|
|
||||||
protocol_ = std::string(protocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Codecs should be in preference order (most preferred codec first).
|
// Codecs should be in preference order (most preferred codec first).
|
||||||
const std::vector<Codec>& codecs() const { return codecs_; }
|
const std::vector<Codec>& codecs() const { return codecs_; }
|
||||||
void set_codecs(const std::vector<Codec>& codecs) { codecs_ = codecs; }
|
void set_codecs(const std::vector<Codec>& codecs) { codecs_ = codecs; }
|
||||||
bool has_codecs() const override { return !codecs_.empty(); }
|
virtual bool has_codecs() const { return !codecs_.empty(); }
|
||||||
bool HasCodec(int id) {
|
bool HasCodec(int id) {
|
||||||
bool found = false;
|
return absl::c_find_if(codecs_, [id](const cricket::Codec codec) {
|
||||||
for (auto it = codecs_.begin(); it != codecs_.end(); ++it) {
|
return codec.id == id;
|
||||||
if (it->id == id) {
|
}) != codecs_.end();
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
void AddCodec(const Codec& codec) { codecs_.push_back(codec); }
|
void AddCodec(const Codec& codec) { codecs_.push_back(codec); }
|
||||||
void AddOrReplaceCodec(const Codec& codec) {
|
void AddOrReplaceCodec(const Codec& codec) {
|
||||||
@ -299,10 +257,48 @@ class MediaContentDescriptionImpl : public MediaContentDescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// TODO(bugs.webrtc.org/15214): move all RTP related things to a subclass that
|
||||||
|
// the SCTP content description does not inherit from.
|
||||||
|
std::string protocol_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool rtcp_mux_ = false;
|
||||||
|
bool rtcp_reduced_size_ = false;
|
||||||
|
bool remote_estimate_ = false;
|
||||||
|
int bandwidth_ = kAutoBandwidth;
|
||||||
|
std::string bandwidth_type_ = kApplicationSpecificBandwidth;
|
||||||
|
|
||||||
|
std::vector<CryptoParams> cryptos_;
|
||||||
|
std::vector<webrtc::RtpExtension> rtp_header_extensions_;
|
||||||
|
bool rtp_header_extensions_set_ = false;
|
||||||
|
StreamParamsVec send_streams_;
|
||||||
|
bool conference_mode_ = false;
|
||||||
|
webrtc::RtpTransceiverDirection direction_ =
|
||||||
|
webrtc::RtpTransceiverDirection::kSendRecv;
|
||||||
|
rtc::SocketAddress connection_address_;
|
||||||
|
ExtmapAllowMixed extmap_allow_mixed_enum_ = kMedia;
|
||||||
|
|
||||||
|
SimulcastDescription simulcast_;
|
||||||
|
std::vector<RidDescription> receive_rids_;
|
||||||
|
|
||||||
|
// Copy function that returns a raw pointer. Caller will assert ownership.
|
||||||
|
// Should only be called by the Clone() function. Must be implemented
|
||||||
|
// by each final subclass.
|
||||||
|
virtual MediaContentDescription* CloneInternal() const = 0;
|
||||||
|
|
||||||
std::vector<Codec> codecs_;
|
std::vector<Codec> codecs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
class MediaContentDescriptionImpl : public MediaContentDescription {
|
||||||
|
public:
|
||||||
|
void set_protocol(absl::string_view protocol) override {
|
||||||
|
RTC_DCHECK(IsRtpProtocol(protocol));
|
||||||
|
protocol_ = std::string(protocol);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class AudioContentDescription : public MediaContentDescriptionImpl<Codec> {
|
class AudioContentDescription : public MediaContentDescriptionImpl<Codec> {
|
||||||
public:
|
public:
|
||||||
AudioContentDescription() {}
|
AudioContentDescription() {}
|
||||||
|
|||||||
171
pc/webrtc_sdp.cc
171
pc/webrtc_sdp.cc
@ -1438,17 +1438,11 @@ void BuildMediaLine(const cricket::MediaType media_type,
|
|||||||
// fmt is a list of payload type numbers that MAY be used in the session.
|
// fmt is a list of payload type numbers that MAY be used in the session.
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string fmt;
|
std::string fmt;
|
||||||
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
if (media_type == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
type = kMediaTypeVideo;
|
media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
const VideoContentDescription* video_desc = media_desc->as_video();
|
type = media_type == cricket::MEDIA_TYPE_AUDIO ? kMediaTypeAudio
|
||||||
for (const cricket::VideoCodec& codec : video_desc->codecs()) {
|
: kMediaTypeVideo;
|
||||||
fmt.append(" ");
|
for (const cricket::VideoCodec& codec : media_desc->codecs()) {
|
||||||
fmt.append(rtc::ToString(codec.id));
|
|
||||||
}
|
|
||||||
} else if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
|
||||||
type = kMediaTypeAudio;
|
|
||||||
const AudioContentDescription* audio_desc = media_desc->as_audio();
|
|
||||||
for (const cricket::AudioCodec& codec : audio_desc->codecs()) {
|
|
||||||
fmt.append(" ");
|
fmt.append(" ");
|
||||||
fmt.append(rtc::ToString(codec.id));
|
fmt.append(rtc::ToString(codec.id));
|
||||||
}
|
}
|
||||||
@ -1867,8 +1861,7 @@ bool WriteFmtpParameters(const cricket::CodecParameterMap& parameters,
|
|||||||
return !empty;
|
return !empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
void AddFmtpLine(const cricket::Codec& codec, std::string* message) {
|
||||||
void AddFmtpLine(const T& codec, std::string* message) {
|
|
||||||
rtc::StringBuilder os;
|
rtc::StringBuilder os;
|
||||||
WriteFmtpHeader(codec.id, &os);
|
WriteFmtpHeader(codec.id, &os);
|
||||||
os << kSdpDelimiterSpace;
|
os << kSdpDelimiterSpace;
|
||||||
@ -1879,8 +1872,7 @@ void AddFmtpLine(const T& codec, std::string* message) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
void AddPacketizationLine(const cricket::Codec& codec, std::string* message) {
|
||||||
void AddPacketizationLine(const T& codec, std::string* message) {
|
|
||||||
if (!codec.packetization) {
|
if (!codec.packetization) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1890,8 +1882,7 @@ void AddPacketizationLine(const T& codec, std::string* message) {
|
|||||||
AddLine(os.str(), message);
|
AddLine(os.str(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
void AddRtcpFbLines(const cricket::Codec& codec, std::string* message) {
|
||||||
void AddRtcpFbLines(const T& codec, std::string* message) {
|
|
||||||
for (const cricket::FeedbackParam& param : codec.feedback_params.params()) {
|
for (const cricket::FeedbackParam& param : codec.feedback_params.params()) {
|
||||||
rtc::StringBuilder os;
|
rtc::StringBuilder os;
|
||||||
WriteRtcpFbHeader(codec.id, &os);
|
WriteRtcpFbHeader(codec.id, &os);
|
||||||
@ -1932,7 +1923,7 @@ void BuildRtpmap(const MediaContentDescription* media_desc,
|
|||||||
RTC_DCHECK(media_desc != NULL);
|
RTC_DCHECK(media_desc != NULL);
|
||||||
rtc::StringBuilder os;
|
rtc::StringBuilder os;
|
||||||
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
for (const cricket::VideoCodec& codec : media_desc->as_video()->codecs()) {
|
for (const cricket::Codec& codec : media_desc->codecs()) {
|
||||||
// RFC 4566
|
// RFC 4566
|
||||||
// a=rtpmap:<payload type> <encoding name>/<clock rate>
|
// a=rtpmap:<payload type> <encoding name>/<clock rate>
|
||||||
// [/<encodingparameters>]
|
// [/<encodingparameters>]
|
||||||
@ -1950,7 +1941,7 @@ void BuildRtpmap(const MediaContentDescription* media_desc,
|
|||||||
std::vector<int> ptimes;
|
std::vector<int> ptimes;
|
||||||
std::vector<int> maxptimes;
|
std::vector<int> maxptimes;
|
||||||
int max_minptime = 0;
|
int max_minptime = 0;
|
||||||
for (const cricket::AudioCodec& codec : media_desc->as_audio()->codecs()) {
|
for (const cricket::Codec& codec : media_desc->codecs()) {
|
||||||
RTC_DCHECK(!codec.name.empty());
|
RTC_DCHECK(!codec.name.empty());
|
||||||
// RFC 4566
|
// RFC 4566
|
||||||
// a=rtpmap:<payload type> <encoding name>/<clock rate>
|
// a=rtpmap:<payload type> <encoding name>/<clock rate>
|
||||||
@ -2857,21 +2848,6 @@ bool ParseMediaDescription(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyCodec(const cricket::Codec& codec) {
|
|
||||||
// Codec has not been populated correctly unless the name has been set. This
|
|
||||||
// can happen if an SDP has an fmtp or rtcp-fb with a payload type but doesn't
|
|
||||||
// have a corresponding "rtpmap" line.
|
|
||||||
return !codec.name.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyAudioCodecs(const AudioContentDescription* audio_desc) {
|
|
||||||
return absl::c_all_of(audio_desc->codecs(), &VerifyCodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyVideoCodecs(const VideoContentDescription* video_desc) {
|
|
||||||
return absl::c_all_of(video_desc->codecs(), &VerifyCodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddParameters(const cricket::CodecParameterMap& parameters,
|
void AddParameters(const cricket::CodecParameterMap& parameters,
|
||||||
cricket::Codec* codec) {
|
cricket::Codec* codec) {
|
||||||
for (const auto& entry : parameters) {
|
for (const auto& entry : parameters) {
|
||||||
@ -2896,11 +2872,11 @@ void AddFeedbackParameters(const cricket::FeedbackParams& feedback_params,
|
|||||||
// Gets the current codec setting associated with `payload_type`. If there
|
// Gets the current codec setting associated with `payload_type`. If there
|
||||||
// is no Codec associated with that payload type it returns an empty codec
|
// is no Codec associated with that payload type it returns an empty codec
|
||||||
// with that payload type.
|
// with that payload type.
|
||||||
template <class T>
|
cricket::Codec GetCodecWithPayloadType(
|
||||||
T GetCodecWithPayloadType(cricket::MediaType type,
|
cricket::MediaType type,
|
||||||
const std::vector<T>& codecs,
|
const std::vector<cricket::Codec>& codecs,
|
||||||
int payload_type) {
|
int payload_type) {
|
||||||
const T* codec = FindCodecById(codecs, payload_type);
|
const cricket::Codec* codec = FindCodecById(codecs, payload_type);
|
||||||
if (codec)
|
if (codec)
|
||||||
return *codec;
|
return *codec;
|
||||||
// Return empty codec with `payload_type`.
|
// Return empty codec with `payload_type`.
|
||||||
@ -2912,12 +2888,11 @@ T GetCodecWithPayloadType(cricket::MediaType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Updates or creates a new codec entry in the media description.
|
// Updates or creates a new codec entry in the media description.
|
||||||
template <class T, class U>
|
void AddOrReplaceCodec(MediaContentDescription* content_desc,
|
||||||
void AddOrReplaceCodec(MediaContentDescription* content_desc, const U& codec) {
|
const cricket::Codec& codec) {
|
||||||
T* desc = static_cast<T*>(content_desc);
|
std::vector<cricket::Codec> codecs = content_desc->codecs();
|
||||||
std::vector<U> codecs = desc->codecs();
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (U& existing_codec : codecs) {
|
for (cricket::Codec& existing_codec : codecs) {
|
||||||
if (codec.id == existing_codec.id) {
|
if (codec.id == existing_codec.id) {
|
||||||
// Overwrite existing codec with the new codec.
|
// Overwrite existing codec with the new codec.
|
||||||
existing_codec = codec;
|
existing_codec = codec;
|
||||||
@ -2926,38 +2901,34 @@ void AddOrReplaceCodec(MediaContentDescription* content_desc, const U& codec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
desc->AddCodec(codec);
|
content_desc->AddCodec(codec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
desc->set_codecs(codecs);
|
content_desc->set_codecs(codecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds or updates existing codec corresponding to `payload_type` according
|
// Adds or updates existing codec corresponding to `payload_type` according
|
||||||
// to `parameters`.
|
// to `parameters`.
|
||||||
template <class T, class U>
|
|
||||||
void UpdateCodec(MediaContentDescription* content_desc,
|
void UpdateCodec(MediaContentDescription* content_desc,
|
||||||
int payload_type,
|
int payload_type,
|
||||||
const cricket::CodecParameterMap& parameters) {
|
const cricket::CodecParameterMap& parameters) {
|
||||||
// Codec might already have been populated (from rtpmap).
|
// Codec might already have been populated (from rtpmap).
|
||||||
U new_codec = GetCodecWithPayloadType(content_desc->type(),
|
cricket::Codec new_codec = GetCodecWithPayloadType(
|
||||||
static_cast<T*>(content_desc)->codecs(),
|
content_desc->type(), content_desc->codecs(), payload_type);
|
||||||
payload_type);
|
|
||||||
AddParameters(parameters, &new_codec);
|
AddParameters(parameters, &new_codec);
|
||||||
AddOrReplaceCodec<T, U>(content_desc, new_codec);
|
AddOrReplaceCodec(content_desc, new_codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds or updates existing codec corresponding to `payload_type` according
|
// Adds or updates existing codec corresponding to `payload_type` according
|
||||||
// to `feedback_param`.
|
// to `feedback_param`.
|
||||||
template <class T, class U>
|
|
||||||
void UpdateCodec(MediaContentDescription* content_desc,
|
void UpdateCodec(MediaContentDescription* content_desc,
|
||||||
int payload_type,
|
int payload_type,
|
||||||
const cricket::FeedbackParam& feedback_param) {
|
const cricket::FeedbackParam& feedback_param) {
|
||||||
// Codec might already have been populated (from rtpmap).
|
// Codec might already have been populated (from rtpmap).
|
||||||
U new_codec = GetCodecWithPayloadType(content_desc->type(),
|
cricket::Codec new_codec = GetCodecWithPayloadType(
|
||||||
static_cast<T*>(content_desc)->codecs(),
|
content_desc->type(), content_desc->codecs(), payload_type);
|
||||||
payload_type);
|
|
||||||
AddFeedbackParameter(feedback_param, &new_codec);
|
AddFeedbackParameter(feedback_param, &new_codec);
|
||||||
AddOrReplaceCodec<T, U>(content_desc, new_codec);
|
AddOrReplaceCodec(content_desc, new_codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds or updates existing video codec corresponding to `payload_type`
|
// Adds or updates existing video codec corresponding to `payload_type`
|
||||||
@ -2974,15 +2945,15 @@ void UpdateVideoCodecPacketization(VideoContentDescription* video_desc,
|
|||||||
cricket::VideoCodec codec = GetCodecWithPayloadType(
|
cricket::VideoCodec codec = GetCodecWithPayloadType(
|
||||||
video_desc->type(), video_desc->codecs(), payload_type);
|
video_desc->type(), video_desc->codecs(), payload_type);
|
||||||
codec.packetization = std::string(packetization);
|
codec.packetization = std::string(packetization);
|
||||||
AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
|
AddOrReplaceCodec(video_desc, codec);
|
||||||
codec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
absl::optional<cricket::Codec> PopWildcardCodec(
|
||||||
absl::optional<T> PopWildcardCodec(std::vector<T>* codecs) {
|
std::vector<cricket::Codec>* codecs) {
|
||||||
|
RTC_DCHECK(codecs);
|
||||||
for (auto iter = codecs->begin(); iter != codecs->end(); ++iter) {
|
for (auto iter = codecs->begin(); iter != codecs->end(); ++iter) {
|
||||||
if (iter->id == kWildcardPayloadType) {
|
if (iter->id == kWildcardPayloadType) {
|
||||||
T wildcard_codec = *iter;
|
cricket::Codec wildcard_codec = *iter;
|
||||||
codecs->erase(iter);
|
codecs->erase(iter);
|
||||||
return wildcard_codec;
|
return wildcard_codec;
|
||||||
}
|
}
|
||||||
@ -2990,10 +2961,10 @@ absl::optional<T> PopWildcardCodec(std::vector<T>* codecs) {
|
|||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
void UpdateFromWildcardCodecs(cricket::MediaContentDescription* desc) {
|
||||||
void UpdateFromWildcardCodecs(cricket::MediaContentDescriptionImpl<T>* desc) {
|
RTC_DCHECK(desc);
|
||||||
auto codecs = desc->codecs();
|
auto codecs = desc->codecs();
|
||||||
absl::optional<T> wildcard_codec = PopWildcardCodec(&codecs);
|
absl::optional<cricket::Codec> wildcard_codec = PopWildcardCodec(&codecs);
|
||||||
if (!wildcard_codec) {
|
if (!wildcard_codec) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3006,6 +2977,7 @@ void UpdateFromWildcardCodecs(cricket::MediaContentDescriptionImpl<T>* desc) {
|
|||||||
void AddAudioAttribute(const std::string& name,
|
void AddAudioAttribute(const std::string& name,
|
||||||
absl::string_view value,
|
absl::string_view value,
|
||||||
AudioContentDescription* audio_desc) {
|
AudioContentDescription* audio_desc) {
|
||||||
|
RTC_DCHECK(audio_desc);
|
||||||
if (value.empty()) {
|
if (value.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3415,27 +3387,20 @@ bool ParseContent(absl::string_view message,
|
|||||||
media_desc->AddStream(track);
|
media_desc->AddStream(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
UpdateFromWildcardCodecs(media_desc);
|
||||||
AudioContentDescription* audio_desc = media_desc->as_audio();
|
// Codec has not been populated correctly unless the name has been set. This
|
||||||
UpdateFromWildcardCodecs(audio_desc);
|
// can happen if an SDP has an fmtp or rtcp-fb with a payload type but doesn't
|
||||||
|
// have a corresponding "rtpmap" line. This should lead to a parse error.
|
||||||
// Verify audio codec ensures that no audio codec has been populated with
|
if (!absl::c_all_of(media_desc->codecs(), [](const cricket::Codec codec) {
|
||||||
// only fmtp.
|
return !codec.name.empty();
|
||||||
if (!VerifyAudioCodecs(audio_desc)) {
|
})) {
|
||||||
return ParseFailed("Failed to parse audio codecs correctly.", error);
|
return ParseFailed("Failed to parse codecs correctly.", error);
|
||||||
}
|
|
||||||
AddAudioAttribute(kCodecParamMaxPTime, maxptime_as_string, audio_desc);
|
|
||||||
AddAudioAttribute(kCodecParamPTime, ptime_as_string, audio_desc);
|
|
||||||
}
|
}
|
||||||
|
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
||||||
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
AddAudioAttribute(kCodecParamMaxPTime, maxptime_as_string,
|
||||||
VideoContentDescription* video_desc = media_desc->as_video();
|
media_desc->as_audio());
|
||||||
UpdateFromWildcardCodecs(video_desc);
|
AddAudioAttribute(kCodecParamPTime, ptime_as_string,
|
||||||
// Verify video codec ensures that no video codec has been populated with
|
media_desc->as_audio());
|
||||||
// only rtcp-fb.
|
|
||||||
if (!VerifyVideoCodecs(video_desc)) {
|
|
||||||
return ParseFailed("Failed to parse video codecs correctly.", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC 5245
|
// RFC 5245
|
||||||
@ -3601,14 +3566,13 @@ void UpdateCodec(int payload_type,
|
|||||||
AudioContentDescription* audio_desc) {
|
AudioContentDescription* audio_desc) {
|
||||||
// Codec may already be populated with (only) optional parameters
|
// Codec may already be populated with (only) optional parameters
|
||||||
// (from an fmtp).
|
// (from an fmtp).
|
||||||
cricket::AudioCodec codec = GetCodecWithPayloadType(
|
cricket::Codec codec = GetCodecWithPayloadType(
|
||||||
audio_desc->type(), audio_desc->codecs(), payload_type);
|
audio_desc->type(), audio_desc->codecs(), payload_type);
|
||||||
codec.name = std::string(name);
|
codec.name = std::string(name);
|
||||||
codec.clockrate = clockrate;
|
codec.clockrate = clockrate;
|
||||||
codec.bitrate = bitrate;
|
codec.bitrate = bitrate;
|
||||||
codec.channels = channels;
|
codec.channels = channels;
|
||||||
AddOrReplaceCodec<AudioContentDescription, cricket::AudioCodec>(audio_desc,
|
AddOrReplaceCodec(audio_desc, codec);
|
||||||
codec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates or creates a new codec entry in the video description according to
|
// Updates or creates a new codec entry in the video description according to
|
||||||
@ -3618,11 +3582,10 @@ void UpdateCodec(int payload_type,
|
|||||||
VideoContentDescription* video_desc) {
|
VideoContentDescription* video_desc) {
|
||||||
// Codec may already be populated with (only) optional parameters
|
// Codec may already be populated with (only) optional parameters
|
||||||
// (from an fmtp).
|
// (from an fmtp).
|
||||||
cricket::VideoCodec codec = GetCodecWithPayloadType(
|
cricket::Codec codec = GetCodecWithPayloadType(
|
||||||
video_desc->type(), video_desc->codecs(), payload_type);
|
video_desc->type(), video_desc->codecs(), payload_type);
|
||||||
codec.name = std::string(name);
|
codec.name = std::string(name);
|
||||||
AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
|
AddOrReplaceCodec(video_desc, codec);
|
||||||
codec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseRtpmapAttribute(absl::string_view line,
|
bool ParseRtpmapAttribute(absl::string_view line,
|
||||||
@ -3671,8 +3634,7 @@ bool ParseRtpmapAttribute(absl::string_view line,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
VideoContentDescription* video_desc = media_desc->as_video();
|
for (const cricket::VideoCodec& existing_codec : media_desc->codecs()) {
|
||||||
for (const cricket::VideoCodec& existing_codec : video_desc->codecs()) {
|
|
||||||
if (!existing_codec.name.empty() && payload_type == existing_codec.id &&
|
if (!existing_codec.name.empty() && payload_type == existing_codec.id &&
|
||||||
(!absl::EqualsIgnoreCase(encoding_name, existing_codec.name) ||
|
(!absl::EqualsIgnoreCase(encoding_name, existing_codec.name) ||
|
||||||
clock_rate != existing_codec.clockrate)) {
|
clock_rate != existing_codec.clockrate)) {
|
||||||
@ -3686,7 +3648,7 @@ bool ParseRtpmapAttribute(absl::string_view line,
|
|||||||
return ParseFailed(line, description.Release(), error);
|
return ParseFailed(line, description.Release(), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateCodec(payload_type, encoding_name, video_desc);
|
UpdateCodec(payload_type, encoding_name, media_desc->as_video());
|
||||||
} else if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
} else if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
||||||
// RFC 4566
|
// RFC 4566
|
||||||
// For audio streams, <encoding parameters> indicates the number
|
// For audio streams, <encoding parameters> indicates the number
|
||||||
@ -3703,8 +3665,7 @@ bool ParseRtpmapAttribute(absl::string_view line,
|
|||||||
return ParseFailed(line, "At most 24 channels are supported.", error);
|
return ParseFailed(line, "At most 24 channels are supported.", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioContentDescription* audio_desc = media_desc->as_audio();
|
for (const cricket::AudioCodec& existing_codec : media_desc->codecs()) {
|
||||||
for (const cricket::AudioCodec& existing_codec : audio_desc->codecs()) {
|
|
||||||
// TODO(crbug.com/1338902) re-add checks for clockrate and number of
|
// TODO(crbug.com/1338902) re-add checks for clockrate and number of
|
||||||
// channels.
|
// channels.
|
||||||
if (!existing_codec.name.empty() && payload_type == existing_codec.id &&
|
if (!existing_codec.name.empty() && payload_type == existing_codec.id &&
|
||||||
@ -3720,7 +3681,7 @@ bool ParseRtpmapAttribute(absl::string_view line,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateCodec(payload_type, encoding_name, clock_rate, 0, channels,
|
UpdateCodec(payload_type, encoding_name, clock_rate, 0, channels,
|
||||||
audio_desc);
|
media_desc->as_audio());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3791,12 +3752,9 @@ bool ParseFmtpAttributes(absl::string_view line,
|
|||||||
codec_params[name] = value;
|
codec_params[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
if (media_type == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
UpdateCodec<AudioContentDescription, cricket::AudioCodec>(
|
media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
media_desc, payload_type, codec_params);
|
UpdateCodec(media_desc, payload_type, codec_params);
|
||||||
} else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
|
||||||
UpdateCodec<VideoContentDescription, cricket::VideoCodec>(
|
|
||||||
media_desc, payload_type, codec_params);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3862,12 +3820,9 @@ bool ParseRtcpFbAttribute(absl::string_view line,
|
|||||||
}
|
}
|
||||||
const cricket::FeedbackParam feedback_param(id, param);
|
const cricket::FeedbackParam feedback_param(id, param);
|
||||||
|
|
||||||
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
if (media_type == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
UpdateCodec<AudioContentDescription, cricket::AudioCodec>(
|
media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
media_desc, payload_type, feedback_param);
|
UpdateCodec(media_desc, payload_type, feedback_param);
|
||||||
} else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
|
||||||
UpdateCodec<VideoContentDescription, cricket::VideoCodec>(
|
|
||||||
media_desc, payload_type, feedback_param);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user