Let SessionDescription take ownership of MediaDescription

This documents in the API what is already true in the
implementation - that SessionDescription will eventually
delete MediaDescription objects passed to it.

The old API is preserved for backwards compatibility, but
marked as RTC_DEPRECATED.

Bug: webrtc:10701
Change-Id: I9a822b20cf3e58c5945fa51dbf6082960a332de8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139880
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28144}
This commit is contained in:
Harald Alvestrand 2019-06-03 20:35:45 +02:00 committed by Commit Bot
parent 1fe119f12f
commit 1716d39714
14 changed files with 257 additions and 132 deletions

View File

@ -63,10 +63,12 @@ CreateCricketSessionDescription() {
auto video = absl::make_unique<cricket::VideoContentDescription>();
audio->AddCodec(cricket::AudioCodec(103, "ISAC", 16000, 0, 0));
desc->AddContent(cricket::CN_AUDIO, MediaProtocolType::kRtp, audio.release());
desc->AddContent(cricket::CN_AUDIO, MediaProtocolType::kRtp,
std::move(audio));
video->AddCodec(cricket::VideoCodec(120, "VP8"));
desc->AddContent(cricket::CN_VIDEO, MediaProtocolType::kRtp, video.release());
desc->AddContent(cricket::CN_VIDEO, MediaProtocolType::kRtp,
std::move(video));
desc->AddTransportInfo(cricket::TransportInfo(
cricket::CN_AUDIO,

View File

@ -876,13 +876,12 @@ void JsepTransportController::RemoveTransportForMid(const std::string& mid) {
cricket::JsepTransportDescription
JsepTransportController::CreateJsepTransportDescription(
cricket::ContentInfo content_info,
cricket::TransportInfo transport_info,
const cricket::ContentInfo& content_info,
const cricket::TransportInfo& transport_info,
const std::vector<int>& encrypted_extension_ids,
int rtp_abs_sendtime_extn_id) {
const cricket::MediaContentDescription* content_desc =
static_cast<const cricket::MediaContentDescription*>(
content_info.description);
content_info.media_description();
RTC_DCHECK(content_desc);
bool rtcp_mux_enabled = content_info.type == cricket::MediaProtocolType::kSctp
? true
@ -916,8 +915,7 @@ bool JsepTransportController::ShouldUpdateBundleGroup(
std::vector<int> JsepTransportController::GetEncryptedHeaderExtensionIds(
const cricket::ContentInfo& content_info) {
const cricket::MediaContentDescription* content_desc =
static_cast<const cricket::MediaContentDescription*>(
content_info.description);
content_info.media_description();
if (!config_.crypto_options.srtp.enable_encrypted_rtp_header_extensions) {
return std::vector<int>();
@ -964,8 +962,7 @@ int JsepTransportController::GetRtpAbsSendTimeHeaderExtensionId(
}
const cricket::MediaContentDescription* content_desc =
static_cast<const cricket::MediaContentDescription*>(
content_info.description);
content_info.media_description();
const webrtc::RtpExtension* send_time_extension =
webrtc::RtpExtension::FindHeaderExtensionByUri(
@ -1145,8 +1142,7 @@ RTCError JsepTransportController::MaybeCreateJsepTransport(
}
const cricket::MediaContentDescription* content_desc =
static_cast<const cricket::MediaContentDescription*>(
content_info.description);
content_info.media_description();
if (certificate_ && !content_desc->cryptos().empty()) {
return RTCError(RTCErrorType::INVALID_PARAMETER,
"SDES and DTLS-SRTP cannot be enabled at the same time.");

View File

@ -261,8 +261,8 @@ class JsepTransportController : public sigslot::has_slots<> {
void RemoveTransportForMid(const std::string& mid);
cricket::JsepTransportDescription CreateJsepTransportDescription(
cricket::ContentInfo content_info,
cricket::TransportInfo transport_info,
const cricket::ContentInfo& content_info,
const cricket::TransportInfo& transport_info,
const std::vector<int>& encrypted_extension_ids,
int rtp_abs_sendtime_extn_id);

View File

@ -146,7 +146,7 @@ class JsepTransportControllerTest : public JsepTransportController::Observer,
// Set RTCP-mux to be true because the default policy is "mux required".
audio->set_rtcp_mux(true);
description->AddContent(mid, cricket::MediaProtocolType::kRtp,
/*rejected=*/false, audio.release());
/*rejected=*/false, std::move(audio));
AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
}
@ -162,7 +162,7 @@ class JsepTransportControllerTest : public JsepTransportController::Observer,
// Set RTCP-mux to be true because the default policy is "mux required".
video->set_rtcp_mux(true);
description->AddContent(mid, cricket::MediaProtocolType::kRtp,
/*rejected=*/false, video.release());
/*rejected=*/false, std::move(video));
AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
}
@ -179,7 +179,7 @@ class JsepTransportControllerTest : public JsepTransportController::Observer,
new cricket::SctpDataContentDescription());
data->set_rtcp_mux(true);
description->AddContent(mid, protocol_type,
/*rejected=*/false, data.release());
/*rejected=*/false, std::move(data));
AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
}

View File

@ -2122,7 +2122,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer(
audio->set_direction(media_description_options.direction);
desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp,
media_description_options.stopped, audio.release());
media_description_options.stopped, std::move(audio));
if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
@ -2203,7 +2203,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer(
video->set_direction(media_description_options.direction);
desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp,
media_description_options.stopped, video.release());
media_description_options.stopped, std::move(video));
if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
@ -2249,7 +2249,7 @@ bool MediaSessionDescriptionFactory::AddSctpDataContentForOffer(
}
desc->AddContent(media_description_options.mid, MediaProtocolType::kSctp,
data.release());
std::move(data));
if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
@ -2288,7 +2288,7 @@ bool MediaSessionDescriptionFactory::AddRtpDataContentForOffer(
data->set_bandwidth(kDataMaxBandwidth);
SetMediaProtocol(secure_transport, data.get());
desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp,
media_description_options.stopped, data.release());
media_description_options.stopped, std::move(data));
if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
@ -2443,7 +2443,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
}
answer->AddContent(media_description_options.mid, offer_content->type,
rejected, audio_answer.release());
rejected, std::move(audio_answer));
return true;
}
@ -2544,7 +2544,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer(
<< "' being rejected in answer.";
}
answer->AddContent(media_description_options.mid, offer_content->type,
rejected, video_answer.release());
rejected, std::move(video_answer));
return true;
}
@ -2646,7 +2646,7 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer(
RTC_LOG(LS_INFO) << "Data is not supported in the answer.";
}
answer->AddContent(media_description_options.mid, offer_content->type,
rejected, data_answer.release());
rejected, std::move(data_answer));
return true;
}

View File

@ -11,6 +11,7 @@
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
@ -3268,14 +3269,22 @@ TEST(MediaSessionDescription, CopySessionDescription) {
SessionDescription source;
cricket::ContentGroup group(cricket::CN_AUDIO);
source.AddGroup(group);
AudioContentDescription* acd(new AudioContentDescription());
std::unique_ptr<AudioContentDescription> acd =
absl::make_unique<AudioContentDescription>();
acd->set_codecs(MAKE_VECTOR(kAudioCodecs1));
acd->AddLegacyStream(1);
source.AddContent(cricket::CN_AUDIO, MediaProtocolType::kRtp, acd);
VideoContentDescription* vcd(new VideoContentDescription());
std::unique_ptr<AudioContentDescription> acd_passed =
absl::WrapUnique(acd->Copy());
source.AddContent(cricket::CN_AUDIO, MediaProtocolType::kRtp,
std::move(acd_passed));
std::unique_ptr<VideoContentDescription> vcd =
absl::make_unique<VideoContentDescription>();
vcd->set_codecs(MAKE_VECTOR(kVideoCodecs1));
vcd->AddLegacyStream(2);
source.AddContent(cricket::CN_VIDEO, MediaProtocolType::kRtp, vcd);
std::unique_ptr<VideoContentDescription> vcd_passed =
absl::WrapUnique(vcd->Copy());
source.AddContent(cricket::CN_VIDEO, MediaProtocolType::kRtp,
std::move(vcd_passed));
std::unique_ptr<SessionDescription> copy = source.Clone();
ASSERT_TRUE(copy.get() != NULL);
@ -4184,7 +4193,7 @@ TEST_P(MediaProtocolTest, TestAudioVideoAcceptance) {
std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
ASSERT_TRUE(offer.get() != nullptr);
// Set the protocol for all the contents.
for (auto content : offer.get()->contents()) {
for (auto& content : offer.get()->contents()) {
content.media_description()->set_protocol(GetParam());
}
std::unique_ptr<SessionDescription> answer =

View File

@ -652,11 +652,11 @@ void ReportSimulcastApiVersion(const char* name,
bool has_legacy = false;
bool has_spec_compliant = false;
for (const ContentInfo& content : session.contents()) {
if (!content.description) {
if (!content.media_description()) {
continue;
}
has_spec_compliant |= content.description->HasSimulcast();
for (const StreamParams& sp : content.description->streams()) {
has_spec_compliant |= content.media_description()->HasSimulcast();
for (const StreamParams& sp : content.media_description()->streams()) {
has_legacy |= sp.has_ssrc_group(cricket::kSimSsrcGroupSemantics);
}
}
@ -2435,12 +2435,13 @@ static absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) {
void PeerConnection::FillInMissingRemoteMids(
cricket::SessionDescription* new_remote_description) {
RTC_DCHECK(new_remote_description);
const cricket::ContentInfos no_infos;
const cricket::ContentInfos& local_contents =
(local_description() ? local_description()->description()->contents()
: cricket::ContentInfos());
: no_infos);
const cricket::ContentInfos& remote_contents =
(remote_description() ? remote_description()->description()->contents()
: cricket::ContentInfos());
: no_infos);
for (size_t i = 0; i < new_remote_description->contents().size(); ++i) {
cricket::ContentInfo& content = new_remote_description->contents()[i];
if (!content.name.empty()) {
@ -4469,12 +4470,13 @@ void PeerConnection::GetOptionsForUnifiedPlanOffer(
// Rules for generating an offer are dictated by JSEP sections 5.2.1 (Initial
// Offers) and 5.2.2 (Subsequent Offers).
RTC_DCHECK_EQ(session_options->media_description_options.size(), 0);
const ContentInfos no_infos;
const ContentInfos& local_contents =
(local_description() ? local_description()->description()->contents()
: ContentInfos());
: no_infos);
const ContentInfos& remote_contents =
(remote_description() ? remote_description()->description()->contents()
: ContentInfos());
: no_infos);
// The mline indices that can be recycled. New transceivers should reuse these
// slots first.
std::queue<size_t> recycleable_mline_indices;
@ -6725,7 +6727,7 @@ RTCError PeerConnection::ValidateSessionDescription(
// same type. With Unified Plan, there can only be at most one track per
// media section.
for (const ContentInfo& content : sdesc->description()->contents()) {
const MediaContentDescription& desc = *content.description;
const MediaContentDescription& desc = *content.media_description();
if ((desc.type() == cricket::MEDIA_TYPE_AUDIO ||
desc.type() == cricket::MEDIA_TYPE_VIDEO) &&
desc.streams().size() > 1u) {

View File

@ -687,11 +687,13 @@ TEST_P(PeerConnectionBundleTest,
ASSERT_GE(offer->description()->contents().size(), 2U);
offer->description()
->contents()[0]
.description->mutable_streams()[0]
.media_description()
->mutable_streams()[0]
.ssrcs[0] = 1111222;
offer->description()
->contents()[1]
.description->mutable_streams()[0]
.media_description()
->mutable_streams()[0]
.ssrcs[0] = 1111222;
EXPECT_TRUE(
caller->SetLocalDescription(CloneSessionDescription(offer.get())));

View File

@ -845,7 +845,7 @@ void ChangeMediaTypeAudioToVideo(cricket::SessionDescription* desc) {
desc->RemoveContentByName(audio_mid);
auto* video_content = cricket::GetFirstVideoContent(desc);
desc->AddContent(audio_mid, video_content->type,
video_content->media_description()->Copy());
video_content->media_description()->Clone());
}
constexpr char kMLinesOutOfOrder[] =

View File

@ -91,21 +91,12 @@ SessionDescription::SessionDescription() = default;
SessionDescription::SessionDescription(const SessionDescription&) = default;
SessionDescription::~SessionDescription() {
for (ContentInfos::iterator content = contents_.begin();
content != contents_.end(); ++content) {
delete content->description;
}
}
std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
// Copy the non-special portions using the private copy constructor.
auto copy = absl::WrapUnique(new SessionDescription(*this));
// Copy all ContentDescriptions.
for (ContentInfos::iterator content = copy->contents_.begin();
content != copy->contents().end(); ++content) {
content->description = content->description->Copy();
}
return copy;
// Copy using the private copy constructor.
// This will clone the descriptions using ContentInfo's copy constructor.
return absl::WrapUnique(new SessionDescription(*this));
}
SessionDescription* SessionDescription::Copy() const {
@ -150,71 +141,79 @@ const ContentInfo* SessionDescription::FirstContent() const {
return (contents_.empty()) ? NULL : &(*contents_.begin());
}
void SessionDescription::AddContent(const std::string& name,
MediaProtocolType type,
MediaContentDescription* description) {
void SessionDescription::AddContent(
const std::string& name,
MediaProtocolType type,
std::unique_ptr<MediaContentDescription> description) {
ContentInfo content(type);
content.name = name;
content.description = description;
AddContent(&content);
content.set_media_description(std::move(description));
AddContent(std::move(content));
}
void SessionDescription::AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
MediaContentDescription* description) {
void SessionDescription::AddContent(
const std::string& name,
MediaProtocolType type,
bool rejected,
std::unique_ptr<MediaContentDescription> description) {
ContentInfo content(type);
content.name = name;
content.rejected = rejected;
content.description = description;
AddContent(&content);
content.set_media_description(std::move(description));
AddContent(std::move(content));
}
void SessionDescription::AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
bool bundle_only,
MediaContentDescription* description) {
void SessionDescription::AddContent(
const std::string& name,
MediaProtocolType type,
bool rejected,
bool bundle_only,
std::unique_ptr<MediaContentDescription> description) {
ContentInfo content(type);
content.name = name;
content.rejected = rejected;
content.bundle_only = bundle_only;
content.description = description;
AddContent(&content);
content.set_media_description(std::move(description));
AddContent(std::move(content));
}
void SessionDescription::AddContent(ContentInfo* content) {
void SessionDescription::AddContent(ContentInfo&& content) {
// Unwrap the as_data shim layer before using.
auto* description = content->media_description();
auto* description = content.media_description();
bool should_delete = false;
if (description->as_rtp_data()) {
if (description->as_rtp_data() != description) {
content->set_media_description(
description->deprecated_as_data()->Unshim(&should_delete));
auto* media_description =
description->deprecated_as_data()->Unshim(&should_delete);
// If should_delete was false, the media description passed to
// AddContent is referenced from elsewhere, and double deletion
// is going to result. Don't allow this.
RTC_CHECK(should_delete)
<< "Non-owned shim description passed to AddContent";
// Setting the media description will delete the old description.
content.set_media_description(absl::WrapUnique(media_description));
}
}
if (description->as_sctp()) {
} else if (description->as_sctp()) {
if (description->as_sctp() != description) {
content->set_media_description(
description->deprecated_as_data()->Unshim(&should_delete));
auto* media_description =
description->deprecated_as_data()->Unshim(&should_delete);
RTC_CHECK(should_delete)
<< "Non-owned shim description passed to AddContent";
content.set_media_description(absl::WrapUnique(media_description));
}
}
if (should_delete) {
delete description;
}
if (extmap_allow_mixed()) {
// Mixed support on session level overrides setting on media level.
content->description->set_extmap_allow_mixed_enum(
content.media_description()->set_extmap_allow_mixed_enum(
MediaContentDescription::kSession);
}
contents_.push_back(std::move(*content));
contents_.push_back(std::move(content));
}
bool SessionDescription::RemoveContentByName(const std::string& name) {
for (ContentInfos::iterator content = contents_.begin();
content != contents_.end(); ++content) {
if (content->name == name) {
delete content->description;
contents_.erase(content);
return true;
}
@ -701,4 +700,55 @@ void DataContentDescription::AddCodecs(const std::vector<DataCodec>& codecs) {
}
}
ContentInfo::~ContentInfo() {
if (description_ && description_.get() != description) {
// If description_ is null, we assume that a move operator
// has been applied.
RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
<< "assignment. This usage is deprecated.";
description_.reset(description); // ensure that it is destroyed.
}
}
// Copy operator.
ContentInfo::ContentInfo(const ContentInfo& o)
: name(o.name),
type(o.type),
rejected(o.rejected),
bundle_only(o.bundle_only),
description_(o.description_->Clone()),
description(description_.get()) {}
ContentInfo& ContentInfo::operator=(const ContentInfo& o) {
name = o.name;
type = o.type;
rejected = o.rejected;
bundle_only = o.bundle_only;
description_ = o.description_->Clone();
description = description_.get();
return *this;
}
const MediaContentDescription* ContentInfo::media_description() const {
if (description_.get() != description) {
// Someone's updated |description|, or used a move operator
// on the record.
RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
<< "assignment. This usage is deprecated.";
const_cast<ContentInfo*>(this)->description_.reset(description);
}
return description_.get();
}
MediaContentDescription* ContentInfo::media_description() {
if (description_.get() != description) {
// Someone's updated |description|, or used a move operator
// on the record.
RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
<< "assignment. This usage is deprecated.";
description_.reset(description);
}
return description_.get();
}
} // namespace cricket

View File

@ -16,6 +16,7 @@
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
@ -96,6 +97,9 @@ class MediaContentDescription {
virtual bool has_codecs() const = 0;
virtual MediaContentDescription* Copy() const = 0;
virtual std::unique_ptr<MediaContentDescription> Clone() const {
return absl::WrapUnique(Copy());
}
// |protocol| is the expected media transport protocol, such as RTP/AVPF,
// RTP/SAVPF or SCTP/DTLS.
@ -526,22 +530,29 @@ constexpr MediaProtocolType NS_JINGLE_DRAFT_SCTP = MediaProtocolType::kSctp;
// Represents a session description section. Most information about the section
// is stored in the description, which is a subclass of MediaContentDescription.
struct ContentInfo {
friend class SessionDescription;
// Owns the description.
class ContentInfo {
public:
explicit ContentInfo(MediaProtocolType type) : type(type) {}
~ContentInfo();
// Copy
ContentInfo(const ContentInfo& o);
ContentInfo& operator=(const ContentInfo& o);
ContentInfo(ContentInfo&& o) = default;
ContentInfo& operator=(ContentInfo&& o) = default;
// Alias for |name|.
std::string mid() const { return name; }
void set_mid(const std::string& mid) { this->name = mid; }
// Alias for |description|.
MediaContentDescription* media_description() { return description; }
const MediaContentDescription* media_description() const {
return description;
}
void set_media_description(MediaContentDescription* desc) {
description = desc;
MediaContentDescription* media_description();
const MediaContentDescription* media_description() const;
void set_media_description(std::unique_ptr<MediaContentDescription> desc) {
description_ = std::move(desc);
// For backwards compatibility only.
description = description_.get();
}
// TODO(bugs.webrtc.org/8620): Rename this to mid.
@ -549,8 +560,13 @@ struct ContentInfo {
MediaProtocolType type;
bool rejected = false;
bool bundle_only = false;
// TODO(bugs.webrtc.org/8620): Switch to the getter and setter, and make this
// private.
private:
friend class SessionDescription;
std::unique_ptr<MediaContentDescription> description_;
public:
// Kept for backwards compatibility only.
MediaContentDescription* description = nullptr;
};
@ -629,17 +645,40 @@ class SessionDescription {
// Adds a content to this description. Takes ownership of ContentDescription*.
void AddContent(const std::string& name,
MediaProtocolType type,
MediaContentDescription* description);
std::unique_ptr<MediaContentDescription> description);
void AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
MediaContentDescription* description);
std::unique_ptr<MediaContentDescription> description);
void AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
bool bundle_only,
MediaContentDescription* description);
void AddContent(ContentInfo* content);
std::unique_ptr<MediaContentDescription> description);
void AddContent(ContentInfo&& content);
RTC_DEPRECATED void AddContent(const std::string& name,
MediaProtocolType type,
MediaContentDescription* description) {
AddContent(name, type, absl::WrapUnique(description));
}
RTC_DEPRECATED void AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
MediaContentDescription* description) {
AddContent(name, type, rejected, absl::WrapUnique(description));
}
RTC_DEPRECATED void AddContent(const std::string& name,
MediaProtocolType type,
bool rejected,
bool bundle_only,
MediaContentDescription* description) {
AddContent(name, type, rejected, bundle_only,
absl::WrapUnique(description));
}
RTC_DEPRECATED void AddContent(ContentInfo* content) {
AddContent(std::move(*content));
}
bool RemoveContentByName(const std::string& name);

View File

@ -65,8 +65,10 @@ TEST(SessionDescriptionTest, SetExtmapAllowMixed) {
TEST(SessionDescriptionTest, SetExtmapAllowMixedPropagatesToMediaLevel) {
SessionDescription session_desc;
MediaContentDescription* video_desc = new VideoContentDescription();
session_desc.AddContent("video", MediaProtocolType::kRtp, video_desc);
session_desc.AddContent("video", MediaProtocolType::kRtp,
absl::make_unique<VideoContentDescription>());
MediaContentDescription* video_desc =
session_desc.GetContentDescriptionByName("video");
// Setting true on session level propagates to media level.
session_desc.set_extmap_allow_mixed(true);
@ -104,29 +106,38 @@ TEST(SessionDescriptionTest, SetExtmapAllowMixedPropagatesToMediaLevel) {
TEST(SessionDescriptionTest, AddContentTransfersExtmapAllowMixedSetting) {
SessionDescription session_desc;
session_desc.set_extmap_allow_mixed(false);
MediaContentDescription* audio_desc = new AudioContentDescription();
std::unique_ptr<MediaContentDescription> audio_desc =
absl::make_unique<AudioContentDescription>();
audio_desc->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
// If session setting is false, media level setting is preserved when new
// content is added.
session_desc.AddContent("audio", MediaProtocolType::kRtp, audio_desc);
session_desc.AddContent("audio", MediaProtocolType::kRtp,
std::move(audio_desc));
EXPECT_EQ(MediaContentDescription::kMedia,
audio_desc->extmap_allow_mixed_enum());
session_desc.GetContentDescriptionByName("audio")
->extmap_allow_mixed_enum());
// If session setting is true, it's transferred to media level when new
// content is added.
session_desc.set_extmap_allow_mixed(true);
MediaContentDescription* video_desc = new VideoContentDescription();
session_desc.AddContent("video", MediaProtocolType::kRtp, video_desc);
std::unique_ptr<MediaContentDescription> video_desc =
absl::make_unique<VideoContentDescription>();
session_desc.AddContent("video", MediaProtocolType::kRtp,
std::move(video_desc));
EXPECT_EQ(MediaContentDescription::kSession,
video_desc->extmap_allow_mixed_enum());
session_desc.GetContentDescriptionByName("video")
->extmap_allow_mixed_enum());
// Session level setting overrides media level when new content is added.
MediaContentDescription* data_desc = new RtpDataContentDescription;
std::unique_ptr<MediaContentDescription> data_desc =
absl::make_unique<RtpDataContentDescription>();
data_desc->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
session_desc.AddContent("data", MediaProtocolType::kRtp, data_desc);
session_desc.AddContent("data", MediaProtocolType::kRtp,
std::move(data_desc));
EXPECT_EQ(MediaContentDescription::kSession,
data_desc->extmap_allow_mixed_enum());
session_desc.GetContentDescriptionByName("data")
->extmap_allow_mixed_enum());
}
// The tests for DataContentDescription will be deleted soon.
@ -165,7 +176,7 @@ TEST(SessionDescriptionTest, DataContentDesriptionInSessionIsUnwrapped) {
// Create a DTLS object behind the shim.
description->set_protocol(kMediaProtocolUdpDtlsSctp);
SessionDescription session;
session.AddContent("name", MediaProtocolType::kSctp, description.release());
session.AddContent("name", MediaProtocolType::kSctp, std::move(description));
ContentInfo* content = &(session.contents()[0]);
ASSERT_TRUE(content);
ASSERT_TRUE(content->media_description()->type() == MEDIA_TYPE_DATA);

View File

@ -2798,7 +2798,7 @@ bool ParseMediaDescription(
desc->AddContent(content_name,
cricket::IsDtlsSctp(protocol) ? MediaProtocolType::kSctp
: MediaProtocolType::kRtp,
content_rejected, bundle_only, content.release());
content_rejected, bundle_only, std::move(content));
// Create TransportInfo with the media level "ice-pwd" and "ice-ufrag".
desc->AddTransportInfo(TransportInfo(content_name, transport));
}

View File

@ -1018,7 +1018,8 @@ class WebRtcSdpTest : public ::testing::Test {
audio_desc_->AddStream(audio_stream);
rtc::SocketAddress audio_addr("74.125.127.126", 2345);
audio_desc_->set_connection_address(audio_addr);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_desc_);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_));
// VideoContentDescription
video_desc_ = CreateVideoContentDescription();
@ -1033,7 +1034,8 @@ class WebRtcSdpTest : public ::testing::Test {
video_desc_->AddStream(video_stream);
rtc::SocketAddress video_addr("74.125.224.39", 3457);
video_desc_->set_connection_address(video_addr);
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, video_desc_);
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp,
absl::WrapUnique(video_desc_));
// TransportInfo
desc_.AddTransportInfo(TransportInfo(
@ -1214,8 +1216,10 @@ class WebRtcSdpTest : public ::testing::Test {
desc_.RemoveContentByName(kAudioContentName);
desc_.RemoveContentByName(kVideoContentName);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_desc_);
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, video_desc_);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_));
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp,
absl::WrapUnique(video_desc_));
ASSERT_TRUE(jdesc_.Initialize(desc_.Clone(), jdesc_.session_id(),
jdesc_.session_version()));
@ -1234,7 +1238,8 @@ class WebRtcSdpTest : public ::testing::Test {
audio_track_2.ssrcs.push_back(kAudioTrack2Ssrc);
}
audio_desc_2->AddStream(audio_track_2);
desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, audio_desc_2);
desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_2));
desc_.AddTransportInfo(TransportInfo(
kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2)));
// Video track 2, in stream 2.
@ -1247,7 +1252,8 @@ class WebRtcSdpTest : public ::testing::Test {
video_track_2.ssrcs.push_back(kVideoTrack2Ssrc);
}
video_desc_2->AddStream(video_track_2);
desc_.AddContent(kVideoContentName2, MediaProtocolType::kRtp, video_desc_2);
desc_.AddContent(kVideoContentName2, MediaProtocolType::kRtp,
absl::WrapUnique(video_desc_2));
desc_.AddTransportInfo(TransportInfo(
kVideoContentName2, TransportDescription(kUfragVideo2, kPwdVideo2)));
@ -1261,7 +1267,8 @@ class WebRtcSdpTest : public ::testing::Test {
video_track_3.ssrcs.push_back(kVideoTrack3Ssrc);
}
video_desc_3->AddStream(video_track_3);
desc_.AddContent(kVideoContentName3, MediaProtocolType::kRtp, video_desc_3);
desc_.AddContent(kVideoContentName3, MediaProtocolType::kRtp,
absl::WrapUnique(video_desc_3));
desc_.AddTransportInfo(TransportInfo(
kVideoContentName3, TransportDescription(kUfragVideo3, kPwdVideo3)));
desc_.set_msid_signaling(cricket::kMsidSignalingMediaSection);
@ -1305,7 +1312,8 @@ class WebRtcSdpTest : public ::testing::Test {
audio_track_2.set_stream_ids({kStreamId1, kStreamId2});
audio_track_2.ssrcs.push_back(kAudioTrack2Ssrc);
audio_desc_2->AddStream(audio_track_2);
desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, audio_desc_2);
desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_2));
desc_.AddTransportInfo(TransportInfo(
kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2)));
@ -1317,7 +1325,8 @@ class WebRtcSdpTest : public ::testing::Test {
audio_track_3.set_stream_ids({});
audio_track_3.ssrcs.push_back(kAudioTrack3Ssrc);
audio_desc_3->AddStream(audio_track_3);
desc_.AddContent(kAudioContentName3, MediaProtocolType::kRtp, audio_desc_3);
desc_.AddContent(kAudioContentName3, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_3));
desc_.AddTransportInfo(TransportInfo(
kAudioContentName3, TransportDescription(kUfragVoice3, kPwdVoice3)));
desc_.set_msid_signaling(msid_signaling);
@ -1339,7 +1348,8 @@ class WebRtcSdpTest : public ::testing::Test {
audio_track.id = kAudioTrackId1;
audio_track.set_stream_ids({kStreamId1});
audio_desc->AddStream(audio_track);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_desc);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc));
// Enable signaling a=msid lines.
desc_.set_msid_signaling(cricket::kMsidSignalingMediaSection);
@ -1363,7 +1373,7 @@ class WebRtcSdpTest : public ::testing::Test {
template <class MCD>
void CompareMediaContentDescription(const MCD* cd1, const MCD* cd2) {
// type
EXPECT_EQ(cd1->type(), cd1->type());
EXPECT_EQ(cd1->type(), cd2->type());
// content direction
EXPECT_EQ(cd1->direction(), cd2->direction());
@ -1685,8 +1695,10 @@ class WebRtcSdpTest : public ::testing::Test {
RtpExtension(kExtmapUri, kExtmapId, encrypted));
desc_.RemoveContentByName(kAudioContentName);
desc_.RemoveContentByName(kVideoContentName);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_desc_);
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, video_desc_);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp,
absl::WrapUnique(audio_desc_));
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp,
absl::WrapUnique(video_desc_));
}
void RemoveCryptos() {
@ -1697,7 +1709,8 @@ class WebRtcSdpTest : public ::testing::Test {
// Removes everything in StreamParams from the session description that is
// used for a=ssrc lines.
void RemoveSsrcSignalingFromStreamParams() {
for (cricket::ContentInfo content_info : jdesc_.description()->contents()) {
for (cricket::ContentInfo& content_info :
jdesc_.description()->contents()) {
// With Unified Plan there should be one StreamParams per m= section.
StreamParams& stream =
content_info.media_description()->mutable_streams()[0];
@ -1761,9 +1774,9 @@ class WebRtcSdpTest : public ::testing::Test {
desc_.RemoveContentByName(kAudioContentName);
desc_.RemoveContentByName(kVideoContentName);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_rejected,
audio_desc_);
absl::WrapUnique(audio_desc_));
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, video_rejected,
video_desc_);
absl::WrapUnique(video_desc_));
SetIceUfragPwd(kAudioContentName, audio_rejected ? "" : kUfragVoice,
audio_rejected ? "" : kPwdVoice);
SetIceUfragPwd(kVideoContentName, video_rejected ? "" : kUfragVideo,
@ -1787,7 +1800,7 @@ class WebRtcSdpTest : public ::testing::Test {
sctp_desc_->set_protocol(cricket::kMediaProtocolUdpDtlsSctp);
sctp_desc_->set_port(kDefaultSctpPort);
desc_.AddContent(kDataContentName, MediaProtocolType::kSctp,
data.release());
std::move(data));
desc_.AddTransportInfo(TransportInfo(
kDataContentName, TransportDescription(kUfragData, kPwdData)));
}
@ -1808,7 +1821,8 @@ class WebRtcSdpTest : public ::testing::Test {
CryptoParams(1, "AES_CM_128_HMAC_SHA1_80",
"inline:FvLcvU2P3ZWmQxgPAgcDu7Zl9vftYElFOjEzhWs5", ""));
data_desc_->set_protocol(cricket::kMediaProtocolSavpf);
desc_.AddContent(kDataContentName, MediaProtocolType::kRtp, data.release());
desc_.AddContent(kDataContentName, MediaProtocolType::kRtp,
std::move(data));
desc_.AddTransportInfo(TransportInfo(
kDataContentName, TransportDescription(kUfragData, kPwdData)));
}
@ -1841,9 +1855,9 @@ class WebRtcSdpTest : public ::testing::Test {
desc_.RemoveContentByName(kAudioContentName);
desc_.RemoveContentByName(kVideoContentName);
desc_.AddContent(kAudioContentName, MediaProtocolType::kRtp, audio_rejected,
audio_desc_);
absl::WrapUnique(audio_desc_));
desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, video_rejected,
video_desc_);
absl::WrapUnique(video_desc_));
SetIceUfragPwd(kAudioContentName, audio_rejected ? "" : kUfragVoice,
audio_rejected ? "" : kPwdVoice);
SetIceUfragPwd(kVideoContentName, video_rejected ? "" : kUfragVideo,