Bug 1047487 - Add support for G.722. r=jesup

This commit is contained in:
EKR 2014-08-02 21:10:09 -07:00
parent 7f958e1e10
commit 57a019564f
6 changed files with 137 additions and 7 deletions

View File

@ -51,7 +51,7 @@ gyp_vars = {
# codec enable/disables:
'include_g711': 1,
'include_opus': 1,
'include_g722': 0,
'include_g722': 1,
'include_ilbc': 0,
'include_isac': 0,
'include_pcm16b': 1,

View File

@ -401,7 +401,7 @@ nsresult PeerConnectionCtx::Initialize() {
codecMask |= VCM_CODEC_RESOURCE_G711;
codecMask |= VCM_CODEC_RESOURCE_OPUS;
//codecMask |= VCM_CODEC_RESOURCE_LINEAR;
//codecMask |= VCM_CODEC_RESOURCE_G722;
codecMask |= VCM_CODEC_RESOURCE_G722;
//codecMask |= VCM_CODEC_RESOURCE_iLBC;
//codecMask |= VCM_CODEC_RESOURCE_iSAC;
mCCM->setAudioCodecs(codecMask);

View File

@ -735,6 +735,11 @@ config_set_current_codec_table (int codec_mask, rtp_ptype *codecs)
idx++;
}
if (codec_mask & VCM_CODEC_RESOURCE_G722) {
codecs[idx] = RTP_G722;
idx++;
}
if (codec_mask & VCM_CODEC_RESOURCE_G711) {
codecs[idx] = RTP_PCMU;
idx++;
@ -752,11 +757,6 @@ config_set_current_codec_table (int codec_mask, rtp_ptype *codecs)
idx++;
}
if (codec_mask & VCM_CODEC_RESOURCE_G722) {
codecs[idx] = RTP_G722;
idx++;
}
if (codec_mask & VCM_CODEC_RESOURCE_iLBC) {
codecs[idx] = RTP_ILBC;
idx++;

View File

@ -3485,6 +3485,27 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
payload_info->audio.bitrate = 32000;
break;
case RTP_G722:
/* RFC 3551
G722 is specified in ITU-T Recommendation G.722, "7 kHz audio-coding
within 64 kbit/s". The G.722 encoder produces a stream of octets,
each of which SHALL be octet-aligned in an RTP packet. The first bit
transmitted in the G.722 octet, which is the most significant bit of
the higher sub-band sample, SHALL correspond to the most significant
bit of the octet in the RTP packet.
Even though the actual sampling rate for G.722 audio is 16,000 Hz,
the RTP clock rate for the G722 payload format is 8,000 Hz because
that value was erroneously assigned in RFC 1890 and must remain
unchanged for backward compatibility. The octet rate or sample-pair
rate is 8,000 Hz.
*/
payload_info->audio.frequency = 16000;
payload_info->audio.packet_size = 320;
payload_info->audio.bitrate = 64000;
break;
case RTP_ILBC:
payload_info->ilbc.mode =
(uint16_t)sdp_attr_get_fmtp_mode_for_payload_type(
@ -3511,6 +3532,7 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
dcb_p->call_id, fname), codec);
payload_info->audio.packet_size = -1;
payload_info->audio.bitrate = -1;
MOZ_ASSERT(0);
} /* end switch */

View File

@ -1445,6 +1445,7 @@ private:
case SHOULD_CHECK_AUDIO:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
if (offer) {
ASSERT_NE(sdp.find("a=rtpmap:9 G722/8000"), std::string::npos);
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
}
break;
@ -1452,6 +1453,7 @@ private:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find(" 0-15\r\na=sendonly"), std::string::npos);
if (offer) {
ASSERT_NE(sdp.find("a=rtpmap:9 G722/8000"), std::string::npos);
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
}
break;
@ -1459,6 +1461,7 @@ private:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find(" 0-15\r\na=recvonly"), std::string::npos);
if (offer) {
ASSERT_NE(sdp.find("a=rtpmap:9 G722/8000"), std::string::npos);
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
}
break;
@ -1466,6 +1469,7 @@ private:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find(" 0-15\r\na=sendrecv"), std::string::npos);
if (offer) {
ASSERT_NE(sdp.find("a=rtpmap:9 G722/8000"), std::string::npos);
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
}
break;
@ -2053,6 +2057,17 @@ TEST_F(SignalingTest, OfferAnswerNothingDisabled)
SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
}
TEST_F(SignalingTest, OfferAnswerNothingDisabledFullCycle)
{
sipcc::OfferOptions options;
OfferAnswer(options, OFFER_AV | ANSWER_AV, true,
SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
// verify the default codec priorities
ASSERT_NE(a1_->getLocalDescription().find("RTP/SAVPF 109 9 0 8 101\r"), std::string::npos);
// verify that opus got selected
ASSERT_NE(a2_->getLocalDescription().find("RTP/SAVPF 109 101\r"), std::string::npos);
}
// XXX reject streams has changed. Re-enable when we can stop() received stream
TEST_F(SignalingTest, DISABLED_OfferAnswerDontReceiveAudioOnOffer)
{
@ -3201,6 +3216,97 @@ TEST_F(SignalingTest, AudioOnlyCalleeNoRtcpMux)
a2_->CheckMediaPipeline(0, 1, 0);
}
TEST_F(SignalingTest, AudioOnlyG722Only)
{
EnsureInit();
sipcc::OfferOptions options;
a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
ParsedSDP sdpWrapper(a1_->offer());
sdpWrapper.ReplaceLine("m=audio",
"m=audio 65375 RTP/SAVPF 9\r\n");
std::cout << "Modified SDP " << std::endl
<< indent(sdpWrapper.getSdp()) << std::endl;
a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
a2_->CreateAnswer(sdpWrapper.getSdp(),
OFFER_AUDIO | ANSWER_AUDIO);
a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
ASSERT_NE(a2_->getLocalDescription().find("RTP/SAVPF 9\r"), std::string::npos);
ASSERT_NE(a2_->getLocalDescription().find("a=rtpmap:9 G722/8000"), std::string::npos);
ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
// Wait for some data to get written
ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
a1_->CloseSendStreams();
a2_->CloseReceiveStreams();
ASSERT_GE(a1_->GetPacketsSent(0), 40);
ASSERT_GE(a2_->GetPacketsReceived(0), 40);
}
TEST_F(SignalingTest, AudioOnlyG722MostPreferred)
{
EnsureInit();
sipcc::OfferOptions options;
a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
ParsedSDP sdpWrapper(a1_->offer());
sdpWrapper.ReplaceLine("m=audio",
"m=audio 65375 RTP/SAVPF 9 0 8 109 101\r\n");
std::cout << "Modified SDP " << std::endl
<< indent(sdpWrapper.getSdp()) << std::endl;
a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
a2_->CreateAnswer(sdpWrapper.getSdp(),
OFFER_AUDIO | ANSWER_AUDIO);
a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
ASSERT_NE(a2_->getLocalDescription().find("RTP/SAVPF 9 101\r"), std::string::npos);
ASSERT_NE(a2_->getLocalDescription().find("a=rtpmap:9 G722/8000"), std::string::npos);
a1_->CloseSendStreams();
a2_->CloseReceiveStreams();
}
TEST_F(SignalingTest, AudioOnlyG722Rejected)
{
EnsureInit();
sipcc::OfferOptions options;
a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
// creating different SDPs as a workaround for rejecting codecs
// this way the answerer should pick a codec with lower priority
a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
ParsedSDP sdpWrapper(a1_->offer());
sdpWrapper.ReplaceLine("m=audio",
"m=audio 65375 RTP/SAVPF 0 8 101\r\n");
std::cout << "Modified SDP offer " << std::endl
<< indent(sdpWrapper.getSdp()) << std::endl;
a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
a2_->CreateAnswer(sdpWrapper.getSdp(),
OFFER_AUDIO | ANSWER_AUDIO);
a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
ASSERT_NE(a2_->getLocalDescription().find("RTP/SAVPF 0 101\r"), std::string::npos);
ASSERT_NE(a2_->getLocalDescription().find("a=rtpmap:0 PCMU/8000"), std::string::npos);
ASSERT_EQ(a2_->getLocalDescription().find("a=rtpmap:109 opus/48000/2"), std::string::npos);
ASSERT_EQ(a2_->getLocalDescription().find("a=rtpmap:9 G722/8000"), std::string::npos);
a1_->CloseSendStreams();
a2_->CloseReceiveStreams();
}
TEST_F(SignalingTest, FullCallAudioNoMuxVideoMux)
{
EnsureInit();

View File

@ -46,6 +46,8 @@
'acm_common_defs.h',
'acm_dtmf_playout.cc',
'acm_dtmf_playout.h',
'acm_g722.cc',
'acm_g722.h',
'acm_g729.cc',
'acm_g729.h',
'acm_g7291.cc',