Bug 1003994 - H.246 and multiple video codec tests. r=jesup

This commit is contained in:
Enda Mannion 2014-05-26 10:07:19 +01:00
parent 91aef177a5
commit 2a2092dc76
3 changed files with 329 additions and 11 deletions

View File

@ -420,6 +420,9 @@ nsresult PeerConnectionCtx::Initialize() {
if (Preferences::GetBool("media.peerconnection.video.h264_enabled")) {
codecMask |= VCM_CODEC_RESOURCE_H264;
}
#else
// Outside MOZILLA_INTERNAL_API ensures H.264 available in unit tests
codecMask |= VCM_CODEC_RESOURCE_H264;
#endif
codecMask |= VCM_CODEC_RESOURCE_VP8;

View File

@ -613,6 +613,7 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
//codec_mask = vcmGetVideoCodecList(DSP_ENCODEONLY);
codec_mask = vcmGetVideoCodecList(VCM_DSP_IGNORE);
}
#ifdef WEBRTC_GONK
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
aSupportedCodecs[count] = RTP_H264_P1;
@ -625,6 +626,21 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
aSupportedCodecs[count] = RTP_VP8;
count++;
}
#else
// Apply video codecs with VP8 first on non gonk
if ( codec_mask & VCM_CODEC_RESOURCE_VP8) {
aSupportedCodecs[count] = RTP_VP8;
count++;
}
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
aSupportedCodecs[count] = RTP_H264_P1;
count++;
}
aSupportedCodecs[count] = RTP_H264_P0;
count++;
}
#endif
if ( codec_mask & VCM_CODEC_RESOURCE_H263) {
aSupportedCodecs[count] = RTP_H263;
count++;

View File

@ -1514,26 +1514,22 @@ private:
switch(flags & VIDEO_FLAGS) {
case 0:
ASSERT_EQ(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
AssertWildCardExpressionNotExists(sdp, "m=video*a=rtpmap");
break;
case SHOULD_CHECK_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
AssertWildCardExpressionExists(sdp, "m=video*a=rtpmap");
break;
case SHOULD_SEND_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendonly"),
std::string::npos);
AssertWildCardExpressionExists(sdp, "m=video*a=sendonly");
break;
case SHOULD_RECV_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=recvonly"),
std::string::npos);
AssertWildCardExpressionExists(sdp, "m=video*a=recvonly");
break;
case SHOULD_SENDRECV_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendrecv"),
std::string::npos);
AssertWildCardExpressionExists(sdp, "m=video*a=sendrecv");
break;
case SHOULD_INACTIVE_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=inactive"),
std::string::npos);
AssertWildCardExpressionExists(sdp, "m=video*a=inactive");
break;
case SHOULD_REJECT_VIDEO:
ASSERT_NE(sdp.find("m=video 0 "), std::string::npos);
@ -1553,6 +1549,22 @@ private:
ASSERT_EQ(sdp.find("m=application"), std::string::npos);
}
}
void AssertWildCardExpressionExists(std::string sdp, std::string expr)
{
int wildcard_pos=expr.find("*");
size_t firstPart=sdp.find(expr.substr(0, wildcard_pos));
size_t secondPart=sdp.find(expr.substr(wildcard_pos+1));
ASSERT_TRUE(firstPart != std::string::npos && secondPart != std::string::npos);
}
void AssertWildCardExpressionNotExists(std::string sdp, std::string expr)
{
int wildcard_pos=expr.find("*");
size_t firstPart=sdp.find(expr.substr(0, wildcard_pos));
size_t secondPart=sdp.find(expr.substr(wildcard_pos+1));
ASSERT_FALSE(firstPart == std::string::npos && secondPart == std::string::npos);
}
};
class SignalingEnvironment : public ::testing::Environment {
@ -2765,7 +2777,8 @@ TEST_F(SignalingTest, OfferAnswerCheckDescriptions)
std::cout << "Callee's Remote Description: " << std::endl
<< indent(a2_->getRemoteDescription()) << std::endl << std::endl;
ASSERT_EQ(a1_->getLocalDescription(),a2_->getRemoteDescription());
// bug 1014486
//ASSERT_EQ(a1_->getLocalDescription(),a2_->getRemoteDescription());
ASSERT_EQ(a2_->getLocalDescription(),a1_->getRemoteDescription());
}
@ -3984,6 +3997,292 @@ TEST_F(SignalingTest, MaxFsFrCallerCodec)
ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 60);
}
// Validate offer with multiple video codecs
TEST_F(SignalingTest, ValidateMultipleVideoCodecsInOffer)
{
EnsureInit();
sipcc::MediaConstraints constraints;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
std::string offer = a1_->offer();
ASSERT_NE(offer.find("RTP/SAVPF 120 126 97"), std::string::npos);
ASSERT_NE(offer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
ASSERT_NE(offer.find("a=rtpmap:126 H264/90000"), std::string::npos);
ASSERT_NE(offer.find("a=rtpmap:97 H264/90000"), std::string::npos);
ASSERT_NE(offer.find("a=fmtp:126 profile-level-id="), std::string::npos);
ASSERT_NE(offer.find("a=fmtp:97 profile-level-id="), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:120 nack"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:120 nack pli"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:120 ccm fir"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:126 nack"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:126 nack pli"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:126 ccm fir"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:97 nack"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:97 nack pli"), std::string::npos);
ASSERT_NE(offer.find("a=rtcp-fb:97 ccm fir"), std::string::npos);
}
// Remove VP8 from offer and check that answer negotiates H264 P1 correctly
TEST_F(SignalingTest, RemoveVP8FromOfferWithP1First)
{
EnsureInit();
sipcc::MediaConstraints constraints;
size_t match;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
// Remove VP8 from offer
std::string offer = a1_->offer();
offer.replace(match = offer.find("RTP/SAVPF 120"),
strlen("RTP/SAVPF 126"), "RTP/SAVPF");
ParsedSDP sdpWrapper(offer);
sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
sdpWrapper.DeleteLine("a=rtpmap:120");
std::cout << "Modified SDP " << std::endl
<< indent(sdpWrapper.getSdp()) << std::endl;
// P1 should be offered first
ASSERT_NE(offer.find("RTP/SAVPF 126"), std::string::npos);
a1_->SetLocal(TestObserver::OFFER, sdpWrapper.getSdp());
a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
a2_->CreateAnswer(constraints, sdpWrapper.getSdp(),
OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
std::string answer(a2_->answer());
// Validate answer SDP
ASSERT_NE(answer.find("RTP/SAVPF 126"), std::string::npos);
ASSERT_NE(answer.find("a=rtpmap:126 H264/90000"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 nack"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 nack pli"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 ccm fir"), std::string::npos);
// Ensure VP8 and P0 removed
ASSERT_EQ(answer.find("a=rtpmap:97 H264/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:120"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:97"), std::string::npos);
}
// Insert H.264 before VP8 in Offer, check answer selects H.264
TEST_F(SignalingTest, OfferWithH264BeforeVP8)
{
EnsureInit();
sipcc::MediaConstraints constraints;
size_t match;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
// Swap VP8 and P1 in offer
std::string offer = a1_->offer();
offer.replace(match = offer.find("RTP/SAVPF 120 126 97"),
strlen("RTP/SAVPF 126 120 97"), "RTP/SAVPF 126 120 97");
offer.replace(match = offer.find("a=rtpmap:126 H264/90000"),
strlen("a=rtpmap:120 VP8/90000"), "a=rtpmap:120 VP8/90000");
offer.replace(match = offer.find("a=rtpmap:120 VP8/90000"),
strlen("a=rtpmap:126 H264/90000"), "a=rtpmap:126 H264/90000");
offer.replace(match = offer.find("a=rtcp-fb:126 nack"),
strlen("a=rtcp-fb:120 nack"), "a=rtcp-fb:120 nack");
offer.replace(match = offer.find("a=rtcp-fb:126 nack pli"),
strlen("a=rtcp-fb:120 nack pli"), "a=rtcp-fb:120 nack pli");
offer.replace(match = offer.find("a=rtcp-fb:126 ccm fir"),
strlen("a=rtcp-fb:120 ccm fir"), "a=rtcp-fb:120 ccm fir");
offer.replace(match = offer.find("a=rtcp-fb:120 nack"),
strlen("a=rtcp-fb:126 nack"), "a=rtcp-fb:126 nack");
offer.replace(match = offer.find("a=rtcp-fb:120 nack pli"),
strlen("a=rtcp-fb:126 nack pli"), "a=rtcp-fb:126 nack pli");
offer.replace(match = offer.find("a=rtcp-fb:120 ccm fir"),
strlen("a=rtcp-fb:126 ccm fir"), "a=rtcp-fb:126 ccm fir");
std::cout << "Modified SDP " << std::endl
<< indent(offer) << std::endl;
// P1 should be offered first
ASSERT_NE(offer.find("RTP/SAVPF 126 120 97"), std::string::npos);
a1_->SetLocal(TestObserver::OFFER, offer);
a2_->SetRemote(TestObserver::OFFER, offer, false);
a2_->CreateAnswer(constraints, offer,
OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
std::string answer(a2_->answer());
// Validate answer SDP
ASSERT_NE(answer.find("RTP/SAVPF 126"), std::string::npos);
ASSERT_NE(answer.find("a=rtpmap:126 H264/90000"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 nack"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 nack pli"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:126 ccm fir"), std::string::npos);
// VP8 and P0 removed
ASSERT_EQ(answer.find("a=rtpmap:97 H264/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:120"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:97"), std::string::npos);
}
// Remove H.264 P1 and VP8 from offer, check answer negotiates H.264 P0
TEST_F(SignalingTest, OfferWithOnlyH264P0)
{
EnsureInit();
sipcc::MediaConstraints constraints;
size_t match;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
// Remove VP8 from offer
std::string offer = a1_->offer();
offer.replace(match = offer.find("RTP/SAVPF 120 126"),
strlen("RTP/SAVPF 120 126"), "RTP/SAVPF");
ParsedSDP sdpWrapper(offer);
sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
sdpWrapper.DeleteLine("a=rtpmap:120");
sdpWrapper.DeleteAllLines("a=rtcp-fb:126");
sdpWrapper.DeleteLine("a=rtpmap:126");
sdpWrapper.DeleteLine("a=fmtp:126");
std::cout << "Modified SDP " << std::endl
<< indent(sdpWrapper.getSdp()) << std::endl;
// Offer shouldn't have P1 or VP8 now
offer = sdpWrapper.getSdp();
ASSERT_EQ(offer.find("a=rtpmap:126 H264/90000"), std::string::npos);
ASSERT_EQ(offer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
// P0 should be offered first
ASSERT_NE(offer.find("RTP/SAVPF 97"), std::string::npos);
a1_->SetLocal(TestObserver::OFFER, offer);
a2_->SetRemote(TestObserver::OFFER, offer, false);
a2_->CreateAnswer(constraints, offer,
OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
std::string answer(a2_->answer());
// validate answer SDP
ASSERT_NE(answer.find("RTP/SAVPF 97"), std::string::npos);
ASSERT_NE(answer.find("a=rtpmap:97 H264/90000"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:97 nack"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:97 nack pli"), std::string::npos);
ASSERT_NE(answer.find("a=rtcp-fb:97 ccm fir"), std::string::npos);
// Ensure VP8 and P1 removed
ASSERT_EQ(answer.find("a=rtpmap:126 H264/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:120"), std::string::npos);
ASSERT_EQ(answer.find("a=rtcp-fb:126"), std::string::npos);
}
// Test negotiating an answer which has only H.264 P1
// Which means replace VP8 with H.264 P1 in answer
TEST_F(SignalingTest, AnswerWithoutVP8)
{
EnsureInit();
sipcc::MediaConstraints constraints;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
a1_->SetLocal(TestObserver::OFFER, a1_->offer());
a2_->SetRemote(TestObserver::OFFER, a1_->offer(), false);
a2_->CreateAnswer(constraints, a1_->offer(),
OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
std::string answer(a2_->answer());
// Ensure answer has VP8
ASSERT_NE(answer.find("\r\na=rtpmap:120 VP8/90000"), std::string::npos);
// Replace VP8 with H.264 P1
ParsedSDP sdpWrapper(a2_->answer());
sdpWrapper.AddLine("a=fmtp:126 profile-level-id=42E00C;packetization-mode=1\r\n");
answer = sdpWrapper.getSdp();
answer.replace(answer.find("RTP/SAVPF 120"), strlen("RTP/SAVPF 120"), "RTP/SAVPF 126");
answer.replace(answer.find("\r\na=rtpmap:120 VP8/90000"),
strlen("\r\na=rtpmap:126 H264/90000"), "\r\na=rtpmap:126 H264/90000");
answer.replace(answer.find("\r\na=rtcp-fb:120 nack"),
strlen("\r\na=rtcp-fb:126 nack"), "\r\na=rtcp-fb:126 nack");
answer.replace(answer.find("\r\na=rtcp-fb:120 nack pli"),
strlen("\r\na=rtcp-fb:126 nack pli"), "\r\na=rtcp-fb:126 nack pli");
answer.replace(answer.find("\r\na=rtcp-fb:120 ccm fir"),
strlen("\r\na=rtcp-fb:126 ccm fir"), "\r\na=rtcp-fb:126 ccm fir");
std::cout << "Modified SDP " << std::endl << indent(answer) << std::endl;
a2_->SetLocal(TestObserver::ANSWER, answer, false);
ASSERT_EQ(a2_->pObserver->lastStatusCode,
sipcc::PeerConnectionImpl::kNoError);
a1_->SetRemote(TestObserver::ANSWER, answer, false);
ASSERT_EQ(a1_->pObserver->lastStatusCode,
sipcc::PeerConnectionImpl::kNoError);
ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
a1_->CloseSendStreams();
a2_->CloseReceiveStreams();
}
// Test using a non preferred dynamic video payload type on answer negotiation
TEST_F(SignalingTest, UseNonPrefferedPayloadTypeOnAnswer)
{
EnsureInit();
sipcc::MediaConstraints constraints;
a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
a1_->SetLocal(TestObserver::OFFER, a1_->offer());
a2_->SetRemote(TestObserver::OFFER, a1_->offer(), false);
a2_->CreateAnswer(constraints, a1_->offer(),
OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
std::string answer(a2_->answer());
// Ensure answer has VP8
ASSERT_NE(answer.find("\r\na=rtpmap:120 VP8/90000"), std::string::npos);
// Replace VP8 Payload Type with a non preferred value
answer.replace(answer.find("RTP/SAVPF 120"),
strlen("RTP/SAVPF 121"), "RTP/SAVPF 121");
answer.replace(answer.find("\r\na=rtpmap:120 VP8/90000"),
strlen("\r\na=rtpmap:121 VP8/90000"), "\r\na=rtpmap:121 VP8/90000");
answer.replace(answer.find("\r\na=rtcp-fb:120 nack"),
strlen("\r\na=rtcp-fb:121 nack"), "\r\na=rtcp-fb:121 nack");
answer.replace(answer.find("\r\na=rtcp-fb:120 nack pli"),
strlen("\r\na=rtcp-fb:121 nack pli"), "\r\na=rtcp-fb:121 nack pli");
answer.replace(answer.find("\r\na=rtcp-fb:120 ccm fir"),
strlen("\r\na=rtcp-fb:121 ccm fir"), "\r\na=rtcp-fb:121 ccm fir");
std::cout << "Modified SDP " << std::endl
<< indent(answer) << std::endl;
a2_->SetLocal(TestObserver::ANSWER, answer, false);
ASSERT_EQ(a2_->pObserver->lastStatusCode,
sipcc::PeerConnectionImpl::kNoError);
a1_->SetRemote(TestObserver::ANSWER, answer, false);
ASSERT_EQ(a1_->pObserver->lastStatusCode,
sipcc::PeerConnectionImpl::kNoError);
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();
}
} // End namespace test.
bool is_color_terminal(const char *terminal) {