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:
wu@webrtc.org
2013-08-10 07:18:04 +00:00
parent bf853f2732
commit 91053e7c5a
50 changed files with 2377 additions and 819 deletions

View File

@@ -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;
}

View File

@@ -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;