#include <string>
#include <vector>
-#include "talk/base/gunit.h"
-#include "talk/base/fakesslidentity.h"
-#include "talk/base/messagedigest.h"
#include "talk/media/base/codec.h"
#include "talk/media/base/testutils.h"
#include "talk/p2p/base/constants.h"
#include "talk/p2p/base/transportinfo.h"
#include "talk/session/media/mediasession.h"
#include "talk/session/media/srtpfilter.h"
+#include "webrtc/base/fakesslidentity.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/ssladapter.h"
#ifdef HAVE_SRTP
#define ASSERT_CRYPTO(cd, s, cs) \
static const AudioCodec kAudioCodecs2[] = {
AudioCodec(126, "speex", 16000, 22000, 1, 3),
- AudioCodec(127, "iLBC", 8000, 13300, 1, 2),
- AudioCodec(0, "PCMU", 8000, 64000, 1, 1),
+ AudioCodec(0, "PCMU", 8000, 64000, 1, 2),
+ AudioCodec(127, "iLBC", 8000, 13300, 1, 1),
};
static const AudioCodec kAudioCodecsAnswer[] = {
- AudioCodec(102, "iLBC", 8000, 13300, 1, 2),
- AudioCodec(0, "PCMU", 8000, 64000, 1, 1),
+ AudioCodec(102, "iLBC", 8000, 13300, 1, 5),
+ AudioCodec(0, "PCMU", 8000, 64000, 1, 4),
};
static const VideoCodec kVideoCodecs1[] = {
};
static const VideoCodec kVideoCodecsAnswer[] = {
- VideoCodec(97, "H264", 320, 200, 30, 2)
+ VideoCodec(97, "H264", 320, 200, 30, 1)
};
static const DataCodec kDataCodecs1[] = {
static const char kDataTrack2[] = "data_2";
static const char kDataTrack3[] = "data_3";
+static bool IsMediaContentOfType(const ContentInfo* content,
+ MediaType media_type) {
+ const MediaContentDescription* mdesc =
+ static_cast<const MediaContentDescription*>(content->description);
+ return mdesc && mdesc->type() == media_type;
+}
+
class MediaSessionDescriptionFactoryTest : public testing::Test {
public:
MediaSessionDescriptionFactoryTest()
tdf2_.set_identity(&id2_);
}
+ static void SetUpTestCase() {
+ rtc::InitializeSSL();
+ }
+
+ static void TearDownTestCase() {
+ rtc::CleanupSSL();
+ }
+
// Create a video StreamParamsVec object with:
// - one video stream with 3 simulcast streams and FEC,
StreamParamsVec CreateComplexVideoStreamParamsVec() {
const std::string current_video_pwd = "current_video_pwd";
const std::string current_data_ufrag = "current_data_ufrag";
const std::string current_data_pwd = "current_data_pwd";
- talk_base::scoped_ptr<SessionDescription> current_desc;
- talk_base::scoped_ptr<SessionDescription> desc;
+ rtc::scoped_ptr<SessionDescription> current_desc;
+ rtc::scoped_ptr<SessionDescription> desc;
if (has_current_desc) {
current_desc.reset(new SessionDescription());
EXPECT_TRUE(current_desc->AddTransportInfo(
if (offer) {
desc.reset(f1_.CreateOffer(options, current_desc.get()));
} else {
- talk_base::scoped_ptr<SessionDescription> offer;
+ rtc::scoped_ptr<SessionDescription> offer;
offer.reset(f1_.CreateOffer(options, NULL));
desc.reset(f1_.CreateAnswer(offer.get(), options, current_desc.get()));
}
options.has_audio = true;
options.has_video = true;
options.data_channel_type = cricket::DCT_RTP;
- talk_base::scoped_ptr<SessionDescription> ref_desc;
- talk_base::scoped_ptr<SessionDescription> desc;
+ rtc::scoped_ptr<SessionDescription> ref_desc;
+ rtc::scoped_ptr<SessionDescription> desc;
if (offer) {
options.bundle_enabled = false;
ref_desc.reset(f1_.CreateOffer(options, NULL));
cricket::MediaContentDirection expected_direction_in_answer) {
MediaSessionOptions opts;
opts.has_video = true;
- talk_base::scoped_ptr<SessionDescription> offer(
+ rtc::scoped_ptr<SessionDescription> offer(
f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
ContentInfo* ac_offer= offer->GetContentByName("audio");
static_cast<VideoContentDescription*>(vc_offer->description);
vcd_offer->set_direction(direction_in_offer);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const AudioContentDescription* acd_answer =
GetFirstAudioContentDescription(answer.get());
MediaSessionDescriptionFactory f2_;
TransportDescriptionFactory tdf1_;
TransportDescriptionFactory tdf2_;
- talk_base::FakeSSLIdentity id1_;
- talk_base::FakeSSLIdentity id2_;
+ rtc::FakeSSLIdentity id1_;
+ rtc::FakeSSLIdentity id2_;
};
// Create a typical audio offer, and ensure it matches what we expect.
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) {
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(
+ rtc::scoped_ptr<SessionDescription> offer(
f1_.CreateOffer(MediaSessionOptions(), NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
MediaSessionOptions opts;
opts.has_video = true;
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
opts.has_video = true;
opts.data_channel_type = cricket::DCT_RTP;
opts.bundle_enabled = true;
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f2_.CreateOffer(opts, NULL));
const VideoContentDescription* vcd =
GetFirstVideoContentDescription(offer.get());
opts.has_video = false;
opts.data_channel_type = cricket::DCT_NONE;
opts.bundle_enabled = true;
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
MediaSessionOptions updated_opts;
updated_opts.has_video = true;
updated_opts.data_channel_type = cricket::DCT_RTP;
updated_opts.bundle_enabled = true;
- talk_base::scoped_ptr<SessionDescription> updated_offer(f1_.CreateOffer(
+ rtc::scoped_ptr<SessionDescription> updated_offer(f1_.CreateOffer(
updated_opts, answer.get()));
const AudioContentDescription* acd =
MediaSessionOptions opts;
opts.data_channel_type = cricket::DCT_RTP;
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
opts.bundle_enabled = true;
opts.data_channel_type = cricket::DCT_SCTP;
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
EXPECT_TRUE(offer.get() != NULL);
EXPECT_TRUE(offer->GetContentByName("data") != NULL);
}
MediaSessionOptions opts;
opts.has_video = true;
f1_.set_add_legacy_streams(false);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
EXPECT_FALSE(acd->has_ssrcs()); // No StreamParams.
}
+// Verifies that the order of the media contents in the current
+// SessionDescription is preserved in the new SessionDescription.
+TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) {
+ MediaSessionOptions opts;
+ opts.has_audio = false;
+ opts.has_video = false;
+ opts.data_channel_type = cricket::DCT_SCTP;
+
+ rtc::scoped_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL));
+ ASSERT_TRUE(offer1.get() != NULL);
+ EXPECT_EQ(1u, offer1->contents().size());
+ EXPECT_TRUE(IsMediaContentOfType(&offer1->contents()[0], MEDIA_TYPE_DATA));
+
+ opts.has_video = true;
+ rtc::scoped_ptr<SessionDescription> offer2(
+ f1_.CreateOffer(opts, offer1.get()));
+ ASSERT_TRUE(offer2.get() != NULL);
+ EXPECT_EQ(2u, offer2->contents().size());
+ EXPECT_TRUE(IsMediaContentOfType(&offer2->contents()[0], MEDIA_TYPE_DATA));
+ EXPECT_TRUE(IsMediaContentOfType(&offer2->contents()[1], MEDIA_TYPE_VIDEO));
+
+ opts.has_audio = true;
+ rtc::scoped_ptr<SessionDescription> offer3(
+ f1_.CreateOffer(opts, offer2.get()));
+ ASSERT_TRUE(offer3.get() != NULL);
+ EXPECT_EQ(3u, offer3->contents().size());
+ EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[0], MEDIA_TYPE_DATA));
+ EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[1], MEDIA_TYPE_VIDEO));
+ EXPECT_TRUE(IsMediaContentOfType(&offer3->contents()[2], MEDIA_TYPE_AUDIO));
+
+ // Verifies the default order is audio-video-data, so that the previous checks
+ // didn't pass by accident.
+ rtc::scoped_ptr<SessionDescription> offer4(f1_.CreateOffer(opts, NULL));
+ ASSERT_TRUE(offer4.get() != NULL);
+ EXPECT_EQ(3u, offer4->contents().size());
+ EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[0], MEDIA_TYPE_AUDIO));
+ EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[1], MEDIA_TYPE_VIDEO));
+ EXPECT_TRUE(IsMediaContentOfType(&offer4->contents()[2], MEDIA_TYPE_DATA));
+}
+
// Create a typical audio answer, and ensure it matches what we expect.
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) {
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(
+ rtc::scoped_ptr<SessionDescription> offer(
f1_.CreateOffer(MediaSessionOptions(), NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("video");
opts.has_video = true;
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("video");
opts.data_channel_type = cricket::DCT_RTP;
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("data");
EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol());
}
+// Verifies that the order of the media contents in the offer is preserved in
+// the answer.
+TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) {
+ MediaSessionOptions opts;
+
+ // Creates a data only offer.
+ opts.has_audio = false;
+ opts.data_channel_type = cricket::DCT_SCTP;
+ rtc::scoped_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL));
+ ASSERT_TRUE(offer1.get() != NULL);
+
+ // Appends audio to the offer.
+ opts.has_audio = true;
+ rtc::scoped_ptr<SessionDescription> offer2(
+ f1_.CreateOffer(opts, offer1.get()));
+ ASSERT_TRUE(offer2.get() != NULL);
+
+ // Appends video to the offer.
+ opts.has_video = true;
+ rtc::scoped_ptr<SessionDescription> offer3(
+ f1_.CreateOffer(opts, offer2.get()));
+ ASSERT_TRUE(offer3.get() != NULL);
+
+ rtc::scoped_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer3.get(), opts, NULL));
+ ASSERT_TRUE(answer.get() != NULL);
+ EXPECT_EQ(3u, answer->contents().size());
+ EXPECT_TRUE(IsMediaContentOfType(&answer->contents()[0], MEDIA_TYPE_DATA));
+ EXPECT_TRUE(IsMediaContentOfType(&answer->contents()[1], MEDIA_TYPE_AUDIO));
+ EXPECT_TRUE(IsMediaContentOfType(&answer->contents()[2], MEDIA_TYPE_VIDEO));
+}
+
// This test that the media direction is set to send/receive in an answer if
// the offer is send receive.
TEST_F(MediaSessionDescriptionFactoryTest, CreateAnswerToSendReceiveOffer) {
opts.has_audio = false;
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ContentInfo* dc_offer= offer->GetContentByName("data");
ASSERT_TRUE(dc_offer != NULL);
DataContentDescription* dcd_offer =
std::string protocol = "a weird unknown protocol";
dcd_offer->set_protocol(protocol);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const ContentInfo* dc_answer = answer->GetContentByName("data");
tdf1_.set_secure(SEC_DISABLED);
tdf2_.set_secure(SEC_DISABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
const AudioContentDescription* offer_acd =
GetFirstAudioContentDescription(offer.get());
ASSERT_TRUE(offer_acd != NULL);
EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf), offer_acd->protocol());
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const ContentInfo* ac_answer = answer->GetContentByName("audio");
f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2));
f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2));
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
EXPECT_EQ(MAKE_VECTOR(kAudioRtpExtension1),
opts.data_channel_type = cricket::DCT_RTP;
f1_.set_add_legacy_streams(false);
f2_.set_add_legacy_streams(false);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("video");
opts.has_video = true;
opts.data_channel_type = cricket::DCT_RTP;
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
answer_opts.data_channel_type = cricket::DCT_RTP;
offer_opts.data_channel_type = cricket::DCT_RTP;
- talk_base::scoped_ptr<SessionDescription> offer;
- talk_base::scoped_ptr<SessionDescription> answer;
+ rtc::scoped_ptr<SessionDescription> offer;
+ rtc::scoped_ptr<SessionDescription> answer;
offer_opts.rtcp_mux_enabled = true;
answer_opts.rtcp_mux_enabled = true;
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerToVideo) {
MediaSessionOptions opts;
opts.has_video = true;
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("video");
TEST_F(MediaSessionDescriptionFactoryTest, TestCreateNoDataAnswerToDataOffer) {
MediaSessionOptions opts;
opts.data_channel_type = cricket::DCT_RTP;
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* dc = answer->GetContentByName("data");
MediaSessionOptions opts;
opts.has_video = true;
opts.data_channel_type = cricket::DCT_RTP;
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
ContentInfo* ac = offer->GetContentByName("audio");
ac->rejected = true;
vc->rejected = true;
dc->rejected = true;
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
ac = answer->GetContentByName("audio");
vc = answer->GetContentByName("video");
opts.AddStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1);
f1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* ac = offer->GetContentByName("audio");
opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack3, kMediaStream1);
opts.RemoveStream(MEDIA_TYPE_DATA, kDataTrack2);
opts.AddStream(MEDIA_TYPE_DATA, kDataTrack3, kMediaStream1);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
updated_offer(f1_.CreateOffer(opts, offer.get()));
ASSERT_TRUE(updated_offer.get() != NULL);
MediaSessionOptions opts;
const int num_sim_layers = 3;
opts.AddVideoStream(kVideoTrack1, kMediaStream1, num_sim_layers);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* vc = offer->GetContentByName("video");
offer_opts.data_channel_type = cricket::DCT_RTP;
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(offer_opts,
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(offer_opts,
NULL));
MediaSessionOptions opts;
opts.AddStream(MEDIA_TYPE_DATA, kDataTrack1, kMediaStream1);
opts.AddStream(MEDIA_TYPE_DATA, kDataTrack2, kMediaStream1);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
answer(f2_.CreateAnswer(offer.get(), opts, NULL));
ASSERT_TRUE(answer.get() != NULL);
opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2);
opts.RemoveStream(MEDIA_TYPE_AUDIO, kAudioTrack2);
opts.RemoveStream(MEDIA_TYPE_DATA, kDataTrack2);
- talk_base::scoped_ptr<SessionDescription>
+ rtc::scoped_ptr<SessionDescription>
updated_answer(f2_.CreateAnswer(offer.get(), opts, answer.get()));
ASSERT_TRUE(updated_answer.get() != NULL);
opts.has_audio = true;
opts.has_video = true;
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const AudioContentDescription* acd =
GetFirstVideoContentDescription(answer.get());
EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
- talk_base::scoped_ptr<SessionDescription> updated_offer(
+ rtc::scoped_ptr<SessionDescription> updated_offer(
f2_.CreateOffer(opts, answer.get()));
// The expected audio codecs are the common audio codecs from the first
// offer/answer exchange plus the audio codecs only |f2_| offer, sorted in
// preference order.
+ // TODO(wu): |updated_offer| should not include the codec
+ // (i.e. |kAudioCodecs2[0]|) the other side doesn't support.
const AudioCodec kUpdatedAudioCodecOffer[] = {
- kAudioCodecs2[0],
kAudioCodecsAnswer[0],
kAudioCodecsAnswer[1],
+ kAudioCodecs2[0],
};
// The expected video codecs are the common video codecs from the first
// This creates rtx for H264 with the payload type |f1_| uses.
rtx_f1.params[cricket::kCodecParamAssociatedPayloadType] =
- talk_base::ToString<int>(kVideoCodecs1[1].id);
+ rtc::ToString<int>(kVideoCodecs1[1].id);
f1_codecs.push_back(rtx_f1);
f1_.set_video_codecs(f1_codecs);
// This creates rtx for H264 with the payload type |f2_| uses.
rtx_f2.params[cricket::kCodecParamAssociatedPayloadType] =
- talk_base::ToString<int>(kVideoCodecs2[0].id);
+ rtc::ToString<int>(kVideoCodecs2[0].id);
f2_codecs.push_back(rtx_f2);
f2_.set_video_codecs(f2_codecs);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const VideoContentDescription* vcd =
// are different from |f1_|.
expected_codecs[0].preference = f1_codecs[1].preference;
- talk_base::scoped_ptr<SessionDescription> updated_offer(
+ rtc::scoped_ptr<SessionDescription> updated_offer(
f2_.CreateOffer(opts, answer.get()));
ASSERT_TRUE(updated_offer);
- talk_base::scoped_ptr<SessionDescription> updated_answer(
+ rtc::scoped_ptr<SessionDescription> updated_answer(
f1_.CreateAnswer(updated_offer.get(), opts, answer.get()));
const VideoContentDescription* updated_vcd =
// This creates rtx for H264 with the payload type |f1_| uses.
rtx_f1.params[cricket::kCodecParamAssociatedPayloadType] =
- talk_base::ToString<int>(kVideoCodecs1[1].id);
+ rtc::ToString<int>(kVideoCodecs1[1].id);
f1_codecs.push_back(rtx_f1);
f1_.set_video_codecs(f1_codecs);
opts.has_audio = true;
opts.has_video = false;
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const AudioContentDescription* acd =
rtx_f2.id = 127;
rtx_f2.name = cricket::kRtxCodecName;
rtx_f2.params[cricket::kCodecParamAssociatedPayloadType] =
- talk_base::ToString<int>(used_pl_type);
+ rtc::ToString<int>(used_pl_type);
f2_codecs.push_back(rtx_f2);
f2_.set_video_codecs(f2_codecs);
- talk_base::scoped_ptr<SessionDescription> updated_offer(
+ rtc::scoped_ptr<SessionDescription> updated_offer(
f2_.CreateOffer(opts, answer.get()));
ASSERT_TRUE(updated_offer);
- talk_base::scoped_ptr<SessionDescription> updated_answer(
+ rtc::scoped_ptr<SessionDescription> updated_answer(
f1_.CreateAnswer(updated_offer.get(), opts, answer.get()));
const AudioContentDescription* updated_acd =
int new_h264_pl_type = updated_vcd->codecs()[0].id;
EXPECT_NE(used_pl_type, new_h264_pl_type);
VideoCodec rtx = updated_vcd->codecs()[1];
- int pt_referenced_by_rtx = talk_base::FromString<int>(
+ int pt_referenced_by_rtx = rtc::FromString<int>(
rtx.params[cricket::kCodecParamAssociatedPayloadType]);
EXPECT_EQ(new_h264_pl_type, pt_referenced_by_rtx);
}
// This creates rtx for H264 with the payload type |f2_| uses.
rtx_f2.SetParam(cricket::kCodecParamAssociatedPayloadType,
- talk_base::ToString<int>(kVideoCodecs2[0].id));
+ rtc::ToString<int>(kVideoCodecs2[0].id));
f2_codecs.push_back(rtx_f2);
f2_.set_video_codecs(f2_codecs);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
ASSERT_TRUE(offer.get() != NULL);
// kCodecParamAssociatedPayloadType will always be added to the offer when RTX
// is selected. Manually remove kCodecParamAssociatedPayloadType so that it
}
desc->set_codecs(codecs);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
const VideoContentDescription* vcd =
f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2));
f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2));
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, NULL));
EXPECT_EQ(MAKE_VECTOR(kAudioRtpExtensionAnswer),
GetFirstVideoContentDescription(
answer.get())->rtp_header_extensions());
- talk_base::scoped_ptr<SessionDescription> updated_offer(
+ rtc::scoped_ptr<SessionDescription> updated_offer(
f2_.CreateOffer(opts, answer.get()));
// The expected RTP header extensions in the new offer are the resulting
vcd->AddLegacyStream(2);
source.AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP, vcd);
- talk_base::scoped_ptr<SessionDescription> copy(source.Copy());
+ rtc::scoped_ptr<SessionDescription> copy(source.Copy());
ASSERT_TRUE(copy.get() != NULL);
EXPECT_TRUE(copy->HasGroup(cricket::CN_AUDIO));
const ContentInfo* ac = copy->GetContentByName("audio");
TestCryptoWithBundle(false);
}
+// Verifies that creating answer fails if the offer has UDP/TLS/RTP/SAVPF but
+// DTLS is not enabled locally.
+TEST_F(MediaSessionDescriptionFactoryTest,
+ TestOfferDtlsSavpfWithoutDtlsFailed) {
+ f1_.set_secure(SEC_ENABLED);
+ f2_.set_secure(SEC_ENABLED);
+ tdf1_.set_secure(SEC_DISABLED);
+ tdf2_.set_secure(SEC_DISABLED);
+
+ rtc::scoped_ptr<SessionDescription> offer(
+ f1_.CreateOffer(MediaSessionOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ ContentInfo* offer_content = offer->GetContentByName("audio");
+ ASSERT_TRUE(offer_content != NULL);
+ AudioContentDescription* offer_audio_desc =
+ static_cast<AudioContentDescription*>(offer_content->description);
+ offer_audio_desc->set_protocol(cricket::kMediaProtocolDtlsSavpf);
+
+ rtc::scoped_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
+ ASSERT_TRUE(answer != NULL);
+ ContentInfo* answer_content = answer->GetContentByName("audio");
+ ASSERT_TRUE(answer_content != NULL);
+
+ ASSERT_TRUE(answer_content->rejected);
+}
+
+// Offers UDP/TLS/RTP/SAVPF and verifies the answer can be created and contains
+// UDP/TLS/RTP/SAVPF.
+TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) {
+ f1_.set_secure(SEC_ENABLED);
+ f2_.set_secure(SEC_ENABLED);
+ tdf1_.set_secure(SEC_ENABLED);
+ tdf2_.set_secure(SEC_ENABLED);
+
+ rtc::scoped_ptr<SessionDescription> offer(
+ f1_.CreateOffer(MediaSessionOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ ContentInfo* offer_content = offer->GetContentByName("audio");
+ ASSERT_TRUE(offer_content != NULL);
+ AudioContentDescription* offer_audio_desc =
+ static_cast<AudioContentDescription*>(offer_content->description);
+ offer_audio_desc->set_protocol(cricket::kMediaProtocolDtlsSavpf);
+
+ rtc::scoped_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
+ ASSERT_TRUE(answer != NULL);
+
+ const ContentInfo* answer_content = answer->GetContentByName("audio");
+ ASSERT_TRUE(answer_content != NULL);
+ ASSERT_FALSE(answer_content->rejected);
+
+ const AudioContentDescription* answer_audio_desc =
+ static_cast<const AudioContentDescription*>(answer_content->description);
+ EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
+ answer_audio_desc->protocol());
+}
+
// Test that we include both SDES and DTLS in the offer, but only include SDES
// in the answer if DTLS isn't negotiated.
TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoDtls) {
MediaSessionOptions options;
options.has_audio = true;
options.has_video = true;
- talk_base::scoped_ptr<SessionDescription> offer, answer;
+ rtc::scoped_ptr<SessionDescription> offer, answer;
const cricket::MediaContentDescription* audio_media_desc;
const cricket::MediaContentDescription* video_media_desc;
const cricket::TransportDescription* audio_trans_desc;
f2_.set_secure(SEC_REQUIRED);
tdf1_.set_secure(SEC_ENABLED);
- talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(options,
+ rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(options,
NULL));
ASSERT_TRUE(offer.get() != NULL);
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), options, NULL));
EXPECT_TRUE(answer.get() == NULL);
}
options.has_video = true;
options.data_channel_type = cricket::DCT_RTP;
- talk_base::scoped_ptr<SessionDescription> offer, answer;
+ rtc::scoped_ptr<SessionDescription> offer, answer;
// Generate an offer with DTLS but without SDES.
offer.reset(f1_.CreateOffer(options, NULL));
MediaSessionOptions options;
options.has_audio = true;
options.has_video = true;
- talk_base::scoped_ptr<SessionDescription> offer(
+ rtc::scoped_ptr<SessionDescription> offer(
f1_.CreateOffer(options, NULL));
ASSERT_TRUE(offer.get() != NULL);
const ContentInfo* audio_content = offer->GetContentByName("audio");
ASSERT_TRUE(offer.get() != NULL);
audio_content = offer->GetContentByName("audio");
EXPECT_TRUE(VerifyNoCNCodecs(audio_content));
- talk_base::scoped_ptr<SessionDescription> answer(
+ rtc::scoped_ptr<SessionDescription> answer(
f1_.CreateAnswer(offer.get(), options, NULL));
ASSERT_TRUE(answer.get() != NULL);
audio_content = answer->GetContentByName("audio");