Update libjingle to 50654631.
R=mallinath@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2000006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4519 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -440,6 +440,25 @@ void ParsePayloadTypeParameters(const buzz::XmlElement* element,
|
||||
}
|
||||
}
|
||||
|
||||
void ParseFeedbackParams(const buzz::XmlElement* element,
|
||||
FeedbackParams* params) {
|
||||
for (const buzz::XmlElement* param = element->FirstNamed(QN_JINGLE_RTCP_FB);
|
||||
param != NULL; param = param->NextNamed(QN_JINGLE_RTCP_FB)) {
|
||||
std::string type = GetXmlAttr(param, QN_TYPE, buzz::STR_EMPTY);
|
||||
std::string subtype = GetXmlAttr(param, QN_SUBTYPE, buzz::STR_EMPTY);
|
||||
if (!type.empty()) {
|
||||
params->Add(FeedbackParam(type, subtype));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddFeedbackParams(const FeedbackParams& additional_params,
|
||||
FeedbackParams* params) {
|
||||
for (size_t i = 0; i < additional_params.params().size(); ++i) {
|
||||
params->Add(additional_params.params()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int FindWithDefault(const std::map<std::string, std::string>& map,
|
||||
const std::string& key, const int def) {
|
||||
std::map<std::string, std::string>::const_iterator iter = map.find(key);
|
||||
@@ -488,6 +507,7 @@ bool ParseJingleAudioCodec(const buzz::XmlElement* elem, AudioCodec* codec) {
|
||||
int bitrate = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_BITRATE, 0);
|
||||
|
||||
*codec = AudioCodec(id, name, clockrate, bitrate, channels, 0);
|
||||
ParseFeedbackParams(elem, &codec->feedback_params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -506,6 +526,7 @@ bool ParseJingleVideoCodec(const buzz::XmlElement* elem, VideoCodec* codec) {
|
||||
|
||||
*codec = VideoCodec(id, name, width, height, framerate, 0);
|
||||
codec->params = paramap;
|
||||
ParseFeedbackParams(elem, &codec->feedback_params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -517,6 +538,7 @@ bool ParseJingleDataCodec(const buzz::XmlElement* elem, DataCodec* codec) {
|
||||
std::string name = GetXmlAttr(elem, QN_NAME, buzz::STR_EMPTY);
|
||||
|
||||
*codec = DataCodec(id, name, 0);
|
||||
ParseFeedbackParams(elem, &codec->feedback_params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -543,12 +565,16 @@ bool ParseJingleAudioContent(const buzz::XmlElement* content_elem,
|
||||
talk_base::scoped_ptr<AudioContentDescription> audio(
|
||||
new AudioContentDescription());
|
||||
|
||||
FeedbackParams content_feedback_params;
|
||||
ParseFeedbackParams(content_elem, &content_feedback_params);
|
||||
|
||||
for (const buzz::XmlElement* payload_elem =
|
||||
content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE);
|
||||
payload_elem != NULL;
|
||||
payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) {
|
||||
AudioCodec codec;
|
||||
if (ParseJingleAudioCodec(payload_elem, &codec)) {
|
||||
AddFeedbackParams(content_feedback_params, &codec.feedback_params);
|
||||
audio->AddCodec(codec);
|
||||
}
|
||||
}
|
||||
@@ -579,12 +605,16 @@ bool ParseJingleVideoContent(const buzz::XmlElement* content_elem,
|
||||
talk_base::scoped_ptr<VideoContentDescription> video(
|
||||
new VideoContentDescription());
|
||||
|
||||
FeedbackParams content_feedback_params;
|
||||
ParseFeedbackParams(content_elem, &content_feedback_params);
|
||||
|
||||
for (const buzz::XmlElement* payload_elem =
|
||||
content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE);
|
||||
payload_elem != NULL;
|
||||
payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) {
|
||||
VideoCodec codec;
|
||||
if (ParseJingleVideoCodec(payload_elem, &codec)) {
|
||||
AddFeedbackParams(content_feedback_params, &codec.feedback_params);
|
||||
video->AddCodec(codec);
|
||||
}
|
||||
}
|
||||
@@ -645,12 +675,16 @@ bool ParseJingleRtpDataContent(const buzz::XmlElement* content_elem,
|
||||
ParseError* error) {
|
||||
DataContentDescription* data = new DataContentDescription();
|
||||
|
||||
FeedbackParams content_feedback_params;
|
||||
ParseFeedbackParams(content_elem, &content_feedback_params);
|
||||
|
||||
for (const buzz::XmlElement* payload_elem =
|
||||
content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE);
|
||||
payload_elem != NULL;
|
||||
payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) {
|
||||
DataCodec codec;
|
||||
if (ParseJingleDataCodec(payload_elem, &codec)) {
|
||||
AddFeedbackParams(content_feedback_params, &codec.feedback_params);
|
||||
data->AddCodec(codec);
|
||||
}
|
||||
}
|
||||
@@ -853,6 +887,18 @@ buzz::XmlElement* CreatePayloadTypeParameterElem(
|
||||
return elem;
|
||||
}
|
||||
|
||||
void AddRtcpFeedbackElem(buzz::XmlElement* elem,
|
||||
const FeedbackParams& feedback_params) {
|
||||
std::vector<FeedbackParam>::const_iterator it;
|
||||
for (it = feedback_params.params().begin();
|
||||
it != feedback_params.params().end(); ++it) {
|
||||
buzz::XmlElement* fb_elem = new buzz::XmlElement(QN_JINGLE_RTCP_FB);
|
||||
fb_elem->AddAttr(QN_TYPE, it->id());
|
||||
fb_elem->AddAttr(QN_SUBTYPE, it->param());
|
||||
elem->AddElement(fb_elem);
|
||||
}
|
||||
}
|
||||
|
||||
buzz::XmlElement* CreateJingleAudioCodecElem(const AudioCodec& codec) {
|
||||
buzz::XmlElement* elem = new buzz::XmlElement(QN_JINGLE_RTP_PAYLOADTYPE);
|
||||
|
||||
@@ -869,6 +915,8 @@ buzz::XmlElement* CreateJingleAudioCodecElem(const AudioCodec& codec) {
|
||||
AddXmlAttr(elem, QN_CHANNELS, codec.channels);
|
||||
}
|
||||
|
||||
AddRtcpFeedbackElem(elem, codec.feedback_params);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
@@ -883,6 +931,9 @@ buzz::XmlElement* CreateJingleVideoCodecElem(const VideoCodec& codec) {
|
||||
PAYLOADTYPE_PARAMETER_HEIGHT, codec.height));
|
||||
elem->AddElement(CreatePayloadTypeParameterElem(
|
||||
PAYLOADTYPE_PARAMETER_FRAMERATE, codec.framerate));
|
||||
|
||||
AddRtcpFeedbackElem(elem, codec.feedback_params);
|
||||
|
||||
CodecParameterMap::const_iterator param_iter;
|
||||
for (param_iter = codec.params.begin(); param_iter != codec.params.end();
|
||||
++param_iter) {
|
||||
@@ -899,6 +950,8 @@ buzz::XmlElement* CreateJingleDataCodecElem(const DataCodec& codec) {
|
||||
AddXmlAttr(elem, QN_ID, codec.id);
|
||||
elem->AddAttr(QN_NAME, codec.name);
|
||||
|
||||
AddRtcpFeedbackElem(elem, codec.feedback_params);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,16 @@
|
||||
#include "talk/xmllite/xmlprinter.h"
|
||||
#include "talk/xmpp/constants.h"
|
||||
|
||||
using cricket::AudioCodec;
|
||||
using cricket::AudioContentDescription;
|
||||
using cricket::Codec;
|
||||
using cricket::DataCodec;
|
||||
using cricket::DataContentDescription;
|
||||
using cricket::FeedbackParam;
|
||||
using cricket::FeedbackParams;
|
||||
using cricket::VideoCodec;
|
||||
using cricket::VideoContentDescription;
|
||||
|
||||
// The codecs that our FakeMediaEngine will support. Order is important, since
|
||||
// the tests check that our messages have codecs in the correct order.
|
||||
static const cricket::AudioCodec kAudioCodecs[] = {
|
||||
@@ -377,6 +387,42 @@ const std::string kJingleInitiateDifferentPreference(
|
||||
" </jingle> " \
|
||||
"</iq> ");
|
||||
|
||||
const std::string kJingleInitiateWithRtcpFb(
|
||||
"<iq xmlns='jabber:client' from='me@domain.com/resource' " \
|
||||
" to='user@domain.com/resource' type='set' id='123'> " \
|
||||
" <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \
|
||||
" sid='abcdef' initiator='me@domain.com/resource'> " \
|
||||
" <content name='test audio'> " \
|
||||
" <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
|
||||
" <payload-type id='103' name='ISAC' clockrate='16000'> " \
|
||||
" <rtcp-fb type='nack'/> " \
|
||||
" </payload-type> " \
|
||||
" </description> " \
|
||||
" <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
|
||||
" </content> " \
|
||||
" <content name='test video'> " \
|
||||
" <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \
|
||||
" <rtcp-fb type='nack'/> " \
|
||||
" <payload-type id='99' name='H264-SVC'> " \
|
||||
" <rtcp-fb type='ccm' subtype='fir'/> " \
|
||||
" <parameter name='height' value='200'/> " \
|
||||
" <parameter name='width' value='320'/> " \
|
||||
" <parameter name='framerate' value='30'/> " \
|
||||
" </payload-type> " \
|
||||
" </description> " \
|
||||
" <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
|
||||
" </content> " \
|
||||
" <content name='test data'> " \
|
||||
" <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='data'> " \
|
||||
" <rtcp-fb type='nack'/> " \
|
||||
" <payload-type id='127' name='google-data'> " \
|
||||
" </payload-type> " \
|
||||
" </description> " \
|
||||
" <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
|
||||
" </content> " \
|
||||
" </jingle> " \
|
||||
"</iq> ");
|
||||
|
||||
const std::string kGingleVideoInitiate(
|
||||
"<iq xmlns='jabber:client' from='me@domain.com/resource' " \
|
||||
" to='user@domain.com/resource' type='set' id='123'> " \
|
||||
@@ -1151,7 +1197,7 @@ static cricket::CallOptions VideoCallOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
buzz::XmlElement* CopyElement(const buzz::XmlElement* elem) {
|
||||
static buzz::XmlElement* CopyElement(const buzz::XmlElement* elem) {
|
||||
return new buzz::XmlElement(*elem);
|
||||
}
|
||||
|
||||
@@ -1164,8 +1210,8 @@ static std::string AddEncryption(std::string stanza, std::string encryption) {
|
||||
return stanza;
|
||||
}
|
||||
|
||||
int IntFromJingleCodecParameter(const buzz::XmlElement* parameter,
|
||||
const std::string& expected_name) {
|
||||
static int IntFromJingleCodecParameter(const buzz::XmlElement* parameter,
|
||||
const std::string& expected_name) {
|
||||
if (parameter) {
|
||||
const std::string& actual_name =
|
||||
parameter->Attr(cricket::QN_PAYLOADTYPE_PARAMETER_NAME);
|
||||
@@ -1181,6 +1227,18 @@ int IntFromJingleCodecParameter(const buzz::XmlElement* parameter,
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class CodecClass, class DescriptionClass>
|
||||
static void VerifyCodecFbParams(const FeedbackParams& expected,
|
||||
const DescriptionClass* desc) {
|
||||
if (!expected.params().empty()) {
|
||||
ASSERT_TRUE(desc != NULL);
|
||||
const std::vector<CodecClass> codecs = desc->codecs();
|
||||
for (size_t i = 0; i < codecs.size(); ++i) {
|
||||
EXPECT_EQ(expected, codecs[i].feedback_params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parses and extracts payload and codec info from test XML. Since
|
||||
// that XML will be in various contents (Gingle and Jingle), we need an
|
||||
// abstract parser with one concrete implementation per XML content.
|
||||
@@ -1250,6 +1308,20 @@ class JingleSessionTestParser : public MediaSessionTestParser {
|
||||
return payload_type->NextNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE);
|
||||
}
|
||||
|
||||
void ParsePayloadTypeFeedbackParameters(const buzz::XmlElement* element,
|
||||
FeedbackParams* params) {
|
||||
const buzz::XmlElement* param =
|
||||
element->FirstNamed(cricket::QN_JINGLE_RTCP_FB);
|
||||
for (; param != NULL;
|
||||
param = param->NextNamed(cricket::QN_JINGLE_RTCP_FB)) {
|
||||
std::string type = param->Attr(cricket::QN_TYPE);
|
||||
std::string subtype = param->Attr(cricket::QN_SUBTYPE);
|
||||
if (!type.empty()) {
|
||||
params->Add(FeedbackParam(type, subtype));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cricket::AudioCodec AudioCodecFromPayloadType(
|
||||
const buzz::XmlElement* payload_type) {
|
||||
int id = 0;
|
||||
@@ -1272,7 +1344,9 @@ class JingleSessionTestParser : public MediaSessionTestParser {
|
||||
channels = atoi(payload_type->Attr(
|
||||
cricket::QN_CHANNELS).c_str());
|
||||
|
||||
return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0);
|
||||
AudioCodec codec = AudioCodec(id, name, clockrate, bitrate, channels, 0);
|
||||
ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params);
|
||||
return codec;
|
||||
}
|
||||
|
||||
cricket::VideoCodec VideoCodecFromPayloadType(
|
||||
@@ -1301,8 +1375,9 @@ class JingleSessionTestParser : public MediaSessionTestParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cricket::VideoCodec(id, name, width, height, framerate, 0);
|
||||
VideoCodec codec = VideoCodec(id, name, width, height, framerate, 0);
|
||||
ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params);
|
||||
return codec;
|
||||
}
|
||||
|
||||
cricket::DataCodec DataCodecFromPayloadType(
|
||||
@@ -1315,7 +1390,9 @@ class JingleSessionTestParser : public MediaSessionTestParser {
|
||||
if (payload_type->HasAttr(cricket::QN_NAME))
|
||||
name = payload_type->Attr(cricket::QN_NAME);
|
||||
|
||||
return cricket::DataCodec(id, name, 0);
|
||||
DataCodec codec = DataCodec(id, name, 0);
|
||||
ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params);
|
||||
return codec;
|
||||
}
|
||||
|
||||
bool ActionIsTerminate(const buzz::XmlElement* action) {
|
||||
@@ -1482,14 +1559,24 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
fme_ = new cricket::FakeMediaEngine();
|
||||
fdme_ = new cricket::FakeDataEngine();
|
||||
|
||||
FeedbackParams params_nack_fir;
|
||||
params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamCcm,
|
||||
cricket::kRtcpFbCcmParamFir));
|
||||
params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamNack));
|
||||
FeedbackParams params_nack;
|
||||
params_nack.Add(FeedbackParam(cricket::kRtcpFbParamNack));
|
||||
|
||||
std::vector<cricket::AudioCodec>
|
||||
audio_codecs(kAudioCodecs, kAudioCodecs + ARRAY_SIZE(kAudioCodecs));
|
||||
SetCodecFeedbackParams(&audio_codecs, params_nack);
|
||||
fme_->SetAudioCodecs(audio_codecs);
|
||||
std::vector<cricket::VideoCodec>
|
||||
video_codecs(kVideoCodecs, kVideoCodecs + ARRAY_SIZE(kVideoCodecs));
|
||||
SetCodecFeedbackParams(&video_codecs, params_nack_fir);
|
||||
fme_->SetVideoCodecs(video_codecs);
|
||||
std::vector<cricket::DataCodec>
|
||||
data_codecs(kDataCodecs, kDataCodecs + ARRAY_SIZE(kDataCodecs));
|
||||
SetCodecFeedbackParams(&data_codecs, params_nack);
|
||||
fdme_->SetDataCodecs(data_codecs);
|
||||
|
||||
client_ = new cricket::MediaSessionClient(
|
||||
@@ -1551,14 +1638,23 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
return parser_->AudioCodecFromPayloadType(payload_type);
|
||||
}
|
||||
|
||||
const cricket::AudioContentDescription* GetFirstAudioContentDescription(
|
||||
cricket::VideoCodec VideoCodecFromPayloadType(
|
||||
const buzz::XmlElement* payload_type) {
|
||||
return parser_->VideoCodecFromPayloadType(payload_type);
|
||||
}
|
||||
|
||||
cricket::DataCodec DataCodecFromPayloadType(
|
||||
const buzz::XmlElement* payload_type) {
|
||||
return parser_->DataCodecFromPayloadType(payload_type);
|
||||
}
|
||||
|
||||
const AudioContentDescription* GetFirstAudioContentDescription(
|
||||
const cricket::SessionDescription* sdesc) {
|
||||
const cricket::ContentInfo* content =
|
||||
cricket::GetFirstAudioContent(sdesc);
|
||||
if (content == NULL)
|
||||
return NULL;
|
||||
return static_cast<const cricket::AudioContentDescription*>(
|
||||
content->description);
|
||||
return static_cast<const AudioContentDescription*>(content->description);
|
||||
}
|
||||
|
||||
const cricket::VideoContentDescription* GetFirstVideoContentDescription(
|
||||
@@ -1573,7 +1669,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
|
||||
void CheckCryptoFromGoodIncomingInitiate(const cricket::Session* session) {
|
||||
ASSERT_TRUE(session != NULL);
|
||||
const cricket::AudioContentDescription* content =
|
||||
const AudioContentDescription* content =
|
||||
GetFirstAudioContentDescription(session->remote_description());
|
||||
ASSERT_TRUE(content != NULL);
|
||||
ASSERT_EQ(2U, content->cryptos().size());
|
||||
@@ -1588,7 +1684,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckCryptoForGoodOutgoingAccept(const cricket::Session* session) {
|
||||
const cricket::AudioContentDescription* content =
|
||||
const AudioContentDescription* content =
|
||||
GetFirstAudioContentDescription(session->local_description());
|
||||
ASSERT_EQ(1U, content->cryptos().size());
|
||||
ASSERT_EQ(145, content->cryptos()[0].tag);
|
||||
@@ -1597,7 +1693,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckBadCryptoFromIncomingInitiate(const cricket::Session* session) {
|
||||
const cricket::AudioContentDescription* content =
|
||||
const AudioContentDescription* content =
|
||||
GetFirstAudioContentDescription(session->remote_description());
|
||||
ASSERT_EQ(1U, content->cryptos().size());
|
||||
ASSERT_EQ(145, content->cryptos()[0].tag);
|
||||
@@ -1607,11 +1703,22 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckNoCryptoForOutgoingAccept(const cricket::Session* session) {
|
||||
const cricket::AudioContentDescription* content =
|
||||
const AudioContentDescription* content =
|
||||
GetFirstAudioContentDescription(session->local_description());
|
||||
ASSERT_TRUE(content->cryptos().empty());
|
||||
}
|
||||
|
||||
void CheckRtcpFb(const cricket::SessionDescription* sdesc) {
|
||||
VerifyCodecFbParams<AudioCodec>(expected_audio_fb_params_,
|
||||
GetFirstAudioContentDescription(sdesc));
|
||||
|
||||
VerifyCodecFbParams<VideoCodec>(expected_video_fb_params_,
|
||||
GetFirstVideoContentDescription(sdesc));
|
||||
|
||||
VerifyCodecFbParams<DataCodec>(expected_data_fb_params_,
|
||||
GetFirstDataContentDescription(sdesc));
|
||||
}
|
||||
|
||||
void CheckVideoBandwidth(int expected_bandwidth,
|
||||
const cricket::SessionDescription* sdesc) {
|
||||
const cricket::VideoContentDescription* video =
|
||||
@@ -1638,9 +1745,10 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
|
||||
buzz::XmlElement* e = PayloadTypeFromContent(content);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
cricket::DataCodec codec = parser_->DataCodecFromPayloadType(e);
|
||||
cricket::DataCodec codec = DataCodecFromPayloadType(e);
|
||||
EXPECT_EQ(127, codec.id);
|
||||
EXPECT_EQ("google-data", codec.name);
|
||||
EXPECT_EQ(expected_data_fb_params_, codec.feedback_params);
|
||||
|
||||
CheckDataRtcpMux(true, call_->sessions()[0]->local_description());
|
||||
CheckDataRtcpMux(true, call_->sessions()[0]->remote_description());
|
||||
@@ -1675,7 +1783,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckAudioSsrcForIncomingAccept(const cricket::Session* session) {
|
||||
const cricket::AudioContentDescription* audio =
|
||||
const AudioContentDescription* audio =
|
||||
GetFirstAudioContentDescription(session->remote_description());
|
||||
ASSERT_TRUE(audio != NULL);
|
||||
ASSERT_EQ(kAudioSsrc, audio->first_ssrc());
|
||||
@@ -1716,6 +1824,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
call_->sessions()[0]->remote_description());
|
||||
CheckVideoRtcpMux(expected_video_rtcp_mux_,
|
||||
call_->sessions()[0]->remote_description());
|
||||
CheckRtcpFb(call_->sessions()[0]->remote_description());
|
||||
if (expect_incoming_crypto_) {
|
||||
CheckCryptoFromGoodIncomingInitiate(call_->sessions()[0]);
|
||||
}
|
||||
@@ -1739,7 +1848,7 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
CheckCryptoForGoodOutgoingAccept(call_->sessions()[0]);
|
||||
}
|
||||
|
||||
if (options.data_channel_type == cricket::DCT_RTP) {
|
||||
if (options.data_channel_type == cricket::DCT_RTP) {
|
||||
CheckDataRtcpMux(true, call_->sessions()[0]->local_description());
|
||||
CheckDataRtcpMux(true, call_->sessions()[0]->remote_description());
|
||||
// TODO(pthatcher): Check rtcpmux and crypto?
|
||||
@@ -1841,7 +1950,23 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
ClearStanzas();
|
||||
}
|
||||
|
||||
void VerifyAudioCodec(const AudioCodec& codec, int id,
|
||||
const std::string& name, int clockrate,
|
||||
int bitrate, int channels) {
|
||||
ASSERT_EQ(id, codec.id);
|
||||
ASSERT_EQ(name, codec.name);
|
||||
ASSERT_EQ(clockrate, codec.clockrate);
|
||||
ASSERT_EQ(bitrate, codec.bitrate);
|
||||
ASSERT_EQ(channels, codec.channels);
|
||||
ASSERT_EQ(expected_audio_fb_params_, codec.feedback_params);
|
||||
}
|
||||
|
||||
void TestGoodOutgoingInitiate(const cricket::CallOptions& options) {
|
||||
if (initial_protocol_ == cricket::PROTOCOL_JINGLE) {
|
||||
// rtcp fb is only implemented for jingle.
|
||||
ExpectRtcpFb();
|
||||
}
|
||||
|
||||
client_->CreateCall();
|
||||
ASSERT_TRUE(call_ != NULL);
|
||||
call_->InitiateSession(buzz::Jid("me@mydomain.com"),
|
||||
@@ -1861,159 +1986,92 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
buzz::XmlElement* e = PayloadTypeFromContent(content);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(103, codec.id);
|
||||
ASSERT_EQ("ISAC", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(0, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 103, "ISAC", 16000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(104, codec.id);
|
||||
ASSERT_EQ("ISAC", codec.name);
|
||||
ASSERT_EQ(32000, codec.clockrate);
|
||||
ASSERT_EQ(0, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 104, "ISAC", 32000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(119, codec.id);
|
||||
ASSERT_EQ("ISACLC", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(40000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 119, "ISACLC", 16000, 40000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(99, codec.id);
|
||||
ASSERT_EQ("speex", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(22000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 99, "speex", 16000, 22000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(97, codec.id);
|
||||
ASSERT_EQ("IPCMWB", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(80000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 97, "IPCMWB", 16000, 80000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(9, codec.id);
|
||||
ASSERT_EQ("G722", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(64000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 9, "G722", 16000, 64000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(102, codec.id);
|
||||
ASSERT_EQ("iLBC", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(13300, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 102, "iLBC", 8000, 13300, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(98, codec.id);
|
||||
ASSERT_EQ("speex", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(11000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 98, "speex", 8000, 11000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(3, codec.id);
|
||||
ASSERT_EQ("GSM", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(13000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 3, "GSM", 8000, 13000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(100, codec.id);
|
||||
ASSERT_EQ("EG711U", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(64000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 100, "EG711U", 8000, 64000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(101, codec.id);
|
||||
ASSERT_EQ("EG711A", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(64000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 101, "EG711A", 8000, 64000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(0, codec.id);
|
||||
ASSERT_EQ("PCMU", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(64000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 0, "PCMU", 8000, 64000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(8, codec.id);
|
||||
ASSERT_EQ("PCMA", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(64000, codec.bitrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 8, "PCMA", 8000, 64000, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(126, codec.id);
|
||||
ASSERT_EQ("CN", codec.name);
|
||||
ASSERT_EQ(32000, codec.clockrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 126, "CN", 32000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(105, codec.id);
|
||||
ASSERT_EQ("CN", codec.name);
|
||||
ASSERT_EQ(16000, codec.clockrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 105, "CN", 16000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(13, codec.id);
|
||||
ASSERT_EQ("CN", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 13, "CN", 8000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(117, codec.id);
|
||||
ASSERT_EQ("red", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 117, "red", 8000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
codec = AudioCodecFromPayloadType(e);
|
||||
ASSERT_EQ(106, codec.id);
|
||||
ASSERT_EQ("telephone-event", codec.name);
|
||||
ASSERT_EQ(8000, codec.clockrate);
|
||||
ASSERT_EQ(1, codec.channels);
|
||||
VerifyAudioCodec(codec, 106, "telephone-event", 8000, 0, 1);
|
||||
|
||||
e = NextFromPayloadType(e);
|
||||
ASSERT_TRUE(e == NULL);
|
||||
@@ -2073,6 +2131,14 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
ASSERT_EQ(talk_base::ToString(options.video_bandwidth / 1000),
|
||||
bandwidth->BodyText());
|
||||
}
|
||||
|
||||
buzz::XmlElement* e = PayloadTypeFromContent(content);
|
||||
ASSERT_TRUE(e != NULL);
|
||||
VideoCodec codec = VideoCodecFromPayloadType(e);
|
||||
VideoCodec expected_codec = kVideoCodecs[0];
|
||||
expected_codec.preference = codec.preference;
|
||||
expected_codec.feedback_params = expected_video_fb_params_;
|
||||
EXPECT_EQ(expected_codec, codec);
|
||||
}
|
||||
|
||||
if (options.data_channel_type == cricket::DCT_RTP) {
|
||||
@@ -2705,6 +2771,28 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
expected_video_rtcp_mux_ = rtcp_mux;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void SetCodecFeedbackParams(std::vector<C>* codecs,
|
||||
const FeedbackParams& fb_params) {
|
||||
for (size_t i = 0; i < codecs->size(); ++i) {
|
||||
codecs->at(i).feedback_params = fb_params;
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectRtcpFb() {
|
||||
FeedbackParams params_nack_fir;
|
||||
params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamCcm,
|
||||
cricket::kRtcpFbCcmParamFir));
|
||||
params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamNack));
|
||||
|
||||
FeedbackParams params_nack;
|
||||
params_nack.Add(FeedbackParam(cricket::kRtcpFbParamNack));
|
||||
|
||||
expected_audio_fb_params_ = params_nack;
|
||||
expected_video_fb_params_ = params_nack_fir;
|
||||
expected_data_fb_params_ = params_nack;
|
||||
}
|
||||
|
||||
private:
|
||||
void OnSendStanza(cricket::SessionManager* manager,
|
||||
const buzz::XmlElement* stanza) {
|
||||
@@ -2749,6 +2837,9 @@ class MediaSessionClientTest : public sigslot::has_slots<> {
|
||||
bool expect_outgoing_crypto_;
|
||||
int expected_video_bandwidth_;
|
||||
bool expected_video_rtcp_mux_;
|
||||
FeedbackParams expected_audio_fb_params_;
|
||||
FeedbackParams expected_video_fb_params_;
|
||||
FeedbackParams expected_data_fb_params_;
|
||||
cricket::MediaStreams last_streams_added_;
|
||||
cricket::MediaStreams last_streams_removed_;
|
||||
};
|
||||
@@ -2763,6 +2854,17 @@ MediaSessionClientTest* JingleTest() {
|
||||
cricket::PROTOCOL_JINGLE);
|
||||
}
|
||||
|
||||
TEST(MediaSessionTest, JingleGoodInitiateWithRtcpFb) {
|
||||
talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
|
||||
talk_base::scoped_ptr<buzz::XmlElement> elem;
|
||||
|
||||
cricket::CallOptions options = VideoCallOptions();
|
||||
options.data_channel_type = cricket::DCT_SCTP;
|
||||
test->ExpectRtcpFb();
|
||||
test->TestGoodIncomingInitiate(
|
||||
kJingleInitiateWithRtcpFb, options, elem.use());
|
||||
}
|
||||
|
||||
TEST(MediaSessionTest, JingleGoodVideoInitiate) {
|
||||
talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
|
||||
talk_base::scoped_ptr<buzz::XmlElement> elem;
|
||||
|
||||
Reference in New Issue
Block a user