Accept all the media profiles required by JSEP.

JSEP section 5.1.3 states that:
  Any profile matching the following patterns MUST be accepted:
  "RTP/[S]AVP[F]" and "(UDP/TCP)/TLS/RTP/SAVP[F]"

NOTRY=True
BUG=webrtc:5638

Review URL: https://codereview.webrtc.org/1880913002

Cr-Commit-Position: refs/heads/master@{#12338}
This commit is contained in:
zhihuang 2016-04-12 18:32:30 -07:00 committed by Commit bot
parent 79299afa30
commit b7f425ab68
2 changed files with 80 additions and 3 deletions

View File

@ -57,6 +57,13 @@ const char kMediaProtocolAvpf[] = "RTP/AVPF";
// RFC5124
const char kMediaProtocolDtlsSavpf[] = "UDP/TLS/RTP/SAVPF";
// The accepted pattern for media protocol (JSEP Section 5.1.3)
const std::vector<std::string> kMediaProtocols = {"RTP/SAVPF", "RTP/SAVP",
"RTP/AVPF", "RTP/AVP"};
const std::vector<std::string> kMediaProtocolsDtls = {
"UDP/TLS/RTP/SAVPF", "UDP/TLS/RTP/SAVP", "TCP/TLS/RTP/SAVPF",
"TCP/TLS/RTP/SAVP"};
// We always generate offers with "UDP/TLS/RTP/SAVPF" when using DTLS-SRTP,
// but we tolerate "RTP/SAVPF" in offers we receive, for compatibility.
const char kMediaProtocolSavpf[] = "RTP/SAVPF";
@ -1105,6 +1112,12 @@ static bool CreateMediaContentAnswer(
return true;
}
static bool IsProtocolFound(const std::vector<std::string> protocols,
const std::string& protocol) {
return std::find(protocols.begin(), protocols.end(), protocol) !=
protocols.end();
}
static bool IsMediaProtocolSupported(MediaType type,
const std::string& protocol,
bool secure_transport) {
@ -1117,9 +1130,8 @@ static bool IsMediaProtocolSupported(MediaType type,
// Since not all applications serialize and deserialize the media protocol,
// we will have to accept |protocol| to be empty.
return protocol == kMediaProtocolAvpf || protocol.empty() ||
protocol == kMediaProtocolSavpf ||
(protocol == kMediaProtocolDtlsSavpf && secure_transport);
return protocol.empty() || IsProtocolFound(kMediaProtocols, protocol) ||
(IsProtocolFound(kMediaProtocolsDtls, protocol) && secure_transport);
}
static void SetMediaProtocol(bool secure_transport,

View File

@ -180,6 +180,12 @@ static const char kDataTrack1[] = "data_1";
static const char kDataTrack2[] = "data_2";
static const char kDataTrack3[] = "data_3";
static const char* kMediaProtocols[] = {"RTP/AVP", "RTP/SAVP", "RTP/AVPF",
"RTP/SAVPF"};
static const char* kMediaProtocolsDtls[] = {
"TCP/TLS/RTP/SAVPF", "TCP/TLS/RTP/SAVP", "UDP/TLS/RTP/SAVPF",
"UDP/TLS/RTP/SAVP"};
static bool IsMediaContentOfType(const ContentInfo* content,
MediaType media_type) {
const MediaContentDescription* mdesc =
@ -2391,3 +2397,62 @@ TEST_F(MediaSessionDescriptionFactoryTest,
EXPECT_EQ("video_modified", video_content->name);
EXPECT_EQ("data_modified", data_content->name);
}
class MediaProtocolTest : public ::testing::TestWithParam<const char*> {
public:
MediaProtocolTest() : f1_(&tdf1_), f2_(&tdf2_) {
f1_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs1));
f1_.set_video_codecs(MAKE_VECTOR(kVideoCodecs1));
f1_.set_data_codecs(MAKE_VECTOR(kDataCodecs1));
f2_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs2));
f2_.set_video_codecs(MAKE_VECTOR(kVideoCodecs2));
f2_.set_data_codecs(MAKE_VECTOR(kDataCodecs2));
f1_.set_secure(SEC_ENABLED);
f2_.set_secure(SEC_ENABLED);
tdf1_.set_certificate(rtc::RTCCertificate::Create(
rtc::scoped_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id1"))));
tdf2_.set_certificate(rtc::RTCCertificate::Create(
rtc::scoped_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id2"))));
tdf1_.set_secure(SEC_ENABLED);
tdf2_.set_secure(SEC_ENABLED);
}
protected:
MediaSessionDescriptionFactory f1_;
MediaSessionDescriptionFactory f2_;
TransportDescriptionFactory tdf1_;
TransportDescriptionFactory tdf2_;
};
TEST_P(MediaProtocolTest, TestAudioVideoAcceptance) {
MediaSessionOptions opts;
opts.recv_video = true;
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()) {
static_cast<MediaContentDescription*>(content.description)
->set_protocol(GetParam());
}
std::unique_ptr<SessionDescription> answer(
f2_.CreateAnswer(offer.get(), opts, nullptr));
const ContentInfo* ac = answer->GetContentByName("audio");
const ContentInfo* vc = answer->GetContentByName("video");
ASSERT_TRUE(ac != nullptr);
ASSERT_TRUE(vc != nullptr);
EXPECT_FALSE(ac->rejected); // the offer is accepted
EXPECT_FALSE(vc->rejected);
const AudioContentDescription* acd =
static_cast<const AudioContentDescription*>(ac->description);
const VideoContentDescription* vcd =
static_cast<const VideoContentDescription*>(vc->description);
EXPECT_EQ(GetParam(), acd->protocol());
EXPECT_EQ(GetParam(), vcd->protocol());
}
INSTANTIATE_TEST_CASE_P(MediaProtocolPatternTest,
MediaProtocolTest,
::testing::ValuesIn(kMediaProtocols));
INSTANTIATE_TEST_CASE_P(MediaProtocolDtlsPatternTest,
MediaProtocolTest,
::testing::ValuesIn(kMediaProtocolsDtls));