Bug 1470568: Remove the rid= and pt= stuff from our simulcast parsing. Also, handle paused rids correctly. r=mjf

Differential Revision: https://phabricator.services.mozilla.com/D47658

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Byron Campen [:bwc] 2019-10-02 20:20:07 +00:00
parent 6868f703ec
commit 9067a09c0a
10 changed files with 138 additions and 259 deletions

View File

@ -246,12 +246,11 @@ var sdputils = {
return answer_sdp;
}
ok(
offer_sdp.includes("a=simulcast: send rid"),
offer_sdp.includes("a=simulcast:send "),
"Offer contains simulcast attribute"
);
var o_simul = offer_sdp.match(/simulcast: send rid=(.*)([\n$])*/i);
var new_answer_sdp =
answer_sdp + "a=simulcast: recv rid=" + o_simul[1] + "\r\n";
var o_simul = offer_sdp.match(/simulcast:send (.*)([\n$])*/i);
var new_answer_sdp = answer_sdp + "a=simulcast:recv " + o_simul[1] + "\r\n";
ok(offer_sdp.includes("a=rid:"), "Offer contains RID attribute");
var o_rids = offer_sdp.match(/a=rid:(.*)/gi);
o_rids.forEach(o_rid => {

View File

@ -1200,9 +1200,9 @@ TEST_F(JsepTrackTest, SimulcastOfferer) {
ASSERT_EQ(10000U,
mSendOff.GetNegotiatedDetails()->GetEncoding(1).mConstraints.maxBr);
ASSERT_NE(std::string::npos,
mOffer->ToString().find("a=simulcast: send rid=foo;bar"));
mOffer->ToString().find("a=simulcast:send foo;bar"));
ASSERT_NE(std::string::npos,
mAnswer->ToString().find("a=simulcast: recv rid=foo;bar"));
mAnswer->ToString().find("a=simulcast:recv foo;bar"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:foo send"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:bar send"));
ASSERT_NE(std::string::npos, mAnswer->ToString().find("a=rid:foo recv"));
@ -1229,9 +1229,9 @@ TEST_F(JsepTrackTest, SimulcastAnswerer) {
ASSERT_EQ(10000U,
mSendAns.GetNegotiatedDetails()->GetEncoding(1).mConstraints.maxBr);
ASSERT_NE(std::string::npos,
mOffer->ToString().find("a=simulcast: recv rid=foo;bar"));
mOffer->ToString().find("a=simulcast:recv foo;bar"));
ASSERT_NE(std::string::npos,
mAnswer->ToString().find("a=simulcast: send rid=foo;bar"));
mAnswer->ToString().find("a=simulcast:send foo;bar"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:foo recv"));
ASSERT_NE(std::string::npos, mOffer->ToString().find("a=rid:bar recv"));
ASSERT_NE(std::string::npos, mAnswer->ToString().find("a=rid:foo send"));

View File

@ -3292,10 +3292,9 @@ TEST_P(NewSdpTest, CheckSimulcast) {
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(0U, simulcast.sendVersions.size());
ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("bar", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("bar", simulcast.recvVersions[0].choices[0].rid);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("bar123", simulcast.recvVersions[1].choices[0]);
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, simulcast.recvVersions.type);
ASSERT_EQ("bar123", simulcast.recvVersions[1].choices[0].rid);
}
TEST_P(NewSdpTest, CheckSctpmap) {
@ -4831,19 +4830,19 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionSerialize)
std::ostringstream os;
SdpSimulcastAttribute::Version version;
version.choices.push_back("8");
version.choices.push_back(SdpSimulcastAttribute::Encoding("8", false));
version.Serialize(os);
ASSERT_EQ("8", os.str());
os.str("");
version.choices.push_back("9");
version.choices.push_back(SdpSimulcastAttribute::Encoding("9", true));
version.Serialize(os);
ASSERT_EQ("8,9", os.str());
ASSERT_EQ("8,~9", os.str());
os.str("");
version.choices.push_back("0");
version.choices.push_back(SdpSimulcastAttribute::Encoding("0", false));
version.Serialize(os);
ASSERT_EQ("8,9,0", os.str());
ASSERT_EQ("8,~9,0", os.str());
os.str("");
}
@ -4863,14 +4862,17 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionValidParse)
{
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1"));
ASSERT_EQ(1U, version.choices.size());
ASSERT_EQ("1", version.choices[0]);
ASSERT_EQ("1", version.choices[0].rid);
ASSERT_FALSE(version.choices[0].paused);
}
{
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1,2"));
SdpSimulcastAttribute::Version version(ParseSimulcastVersion("1,~2"));
ASSERT_EQ(2U, version.choices.size());
ASSERT_EQ("1", version.choices[0]);
ASSERT_EQ("2", version.choices[1]);
ASSERT_EQ("1", version.choices[0].rid);
ASSERT_EQ("2", version.choices[1].rid);
ASSERT_FALSE(version.choices[0].paused);
ASSERT_TRUE(version.choices[1].paused);
}
}
@ -4891,32 +4893,28 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionsSerialize)
std::ostringstream os;
SdpSimulcastAttribute::Versions versions;
versions.type = SdpSimulcastAttribute::Versions::kPt;
versions.push_back(SdpSimulcastAttribute::Version());
versions.back().choices.push_back("8");
versions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("8", false));
versions.Serialize(os);
ASSERT_EQ("pt=8", os.str());
os.str("");
versions.type = SdpSimulcastAttribute::Versions::kRid;
versions.Serialize(os);
ASSERT_EQ("rid=8", os.str());
ASSERT_EQ("8", os.str());
os.str("");
versions.push_back(SdpSimulcastAttribute::Version());
versions.Serialize(os);
ASSERT_EQ("rid=8", os.str());
ASSERT_EQ("8", os.str());
os.str("");
versions.back().choices.push_back("9");
versions.back().choices.push_back(SdpSimulcastAttribute::Encoding("9", true));
versions.Serialize(os);
ASSERT_EQ("rid=8;9", os.str());
ASSERT_EQ("8;~9", os.str());
os.str("");
versions.push_back(SdpSimulcastAttribute::Version());
versions.back().choices.push_back("0");
versions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("0", false));
versions.Serialize(os);
ASSERT_EQ("rid=8;9;0", os.str());
ASSERT_EQ("8;~9;0", os.str());
os.str("");
}
@ -4933,67 +4931,35 @@ static SdpSimulcastAttribute::Versions ParseSimulcastVersions(
TEST(NewSdpTestNoFixture, CheckSimulcastVersionsValidParse)
{
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("pt=8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("rid=8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(1U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_FALSE(versions[0].choices[0].paused);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("pt=8,9"));
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("~8,9"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_EQ("9", versions[0].choices[1].rid);
ASSERT_TRUE(versions[0].choices[0].paused);
ASSERT_FALSE(versions[0].choices[1].paused);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9"));
ASSERT_EQ(1U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
}
{
SdpSimulcastAttribute::Versions versions(
ParseSimulcastVersions("pt=8,9;10"));
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9;~10"));
ASSERT_EQ(2U, versions.size());
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ("8", versions[0].choices[0].rid);
ASSERT_EQ("9", versions[0].choices[1].rid);
ASSERT_FALSE(versions[0].choices[0].paused);
ASSERT_FALSE(versions[0].choices[1].paused);
ASSERT_EQ(1U, versions[1].choices.size());
ASSERT_EQ("10", versions[1].choices[0]);
}
{
SdpSimulcastAttribute::Versions versions(ParseSimulcastVersions("8,9;10"));
ASSERT_EQ(2U, versions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
ASSERT_EQ(2U, versions[0].choices.size());
ASSERT_EQ("8", versions[0].choices[0]);
ASSERT_EQ("9", versions[0].choices[1]);
ASSERT_EQ(1U, versions[1].choices.size());
ASSERT_EQ("10", versions[1].choices[0]);
ASSERT_EQ("10", versions[1].choices[0].rid);
ASSERT_TRUE(versions[1].choices[0].paused);
}
}
@ -5001,14 +4967,8 @@ TEST(NewSdpTestNoFixture, CheckSimulcastVersionsInvalidParse)
{
ParseInvalid<SdpSimulcastAttribute::Versions>("", 0);
ParseInvalid<SdpSimulcastAttribute::Versions>(";", 0);
ParseInvalid<SdpSimulcastAttribute::Versions>("foo=", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("foo=8", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=9999", 7);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=-1", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=x", 4);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;x", 6);
ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;;", 5);
ParseInvalid<SdpSimulcastAttribute::Versions>("8;", 2);
ParseInvalid<SdpSimulcastAttribute::Versions>("8;;", 2);
}
TEST(NewSdpTestNoFixture, CheckSimulcastSerialize)
@ -5016,18 +4976,18 @@ TEST(NewSdpTestNoFixture, CheckSimulcastSerialize)
std::ostringstream os;
SdpSimulcastAttribute simulcast;
simulcast.recvVersions.type = SdpSimulcastAttribute::Versions::kRid;
simulcast.recvVersions.push_back(SdpSimulcastAttribute::Version());
simulcast.recvVersions.back().choices.push_back("8");
simulcast.recvVersions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("8", false));
simulcast.Serialize(os);
ASSERT_EQ("a=simulcast: recv rid=8" CRLF, os.str());
ASSERT_EQ("a=simulcast:recv 8" CRLF, os.str());
os.str("");
simulcast.sendVersions.type = SdpSimulcastAttribute::Versions::kRid;
simulcast.sendVersions.push_back(SdpSimulcastAttribute::Version());
simulcast.sendVersions.back().choices.push_back("9");
simulcast.sendVersions.back().choices.push_back(
SdpSimulcastAttribute::Encoding("9", true));
simulcast.Serialize(os);
ASSERT_EQ("a=simulcast: send rid=9 recv rid=8" CRLF, os.str());
ASSERT_EQ("a=simulcast:send ~9 recv 8" CRLF, os.str());
}
static SdpSimulcastAttribute ParseSimulcast(const std::string& input) {
@ -5044,90 +5004,54 @@ TEST(NewSdpTestNoFixture, CheckSimulcastValidParse)
{
SdpSimulcastAttribute simulcast(ParseSimulcast("send 8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" send pt=8"));
SdpSimulcastAttribute simulcast(ParseSimulcast(" SEND 8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" SEND pt=8"));
ASSERT_EQ(1U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ(0U, simulcast.recvVersions.size());
}
{
SdpSimulcastAttribute simulcast(ParseSimulcast(" recv pt=8"));
SdpSimulcastAttribute simulcast(ParseSimulcast("recv 8"));
ASSERT_EQ(1U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.recvVersions.type);
ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("8", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("8", simulcast.recvVersions[0].choices[0].rid);
ASSERT_FALSE(simulcast.recvVersions[0].choices[0].paused);
ASSERT_EQ(0U, simulcast.sendVersions.size());
}
{
SdpSimulcastAttribute simulcast(
ParseSimulcast("send 8,9;101;97,98 recv 101,120;97"));
ParseSimulcast("send 8,9;~101;97,~98 recv 101,120;97"));
ASSERT_EQ(3U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.sendVersions.type);
ASSERT_EQ(2U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1]);
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0].rid);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1].rid);
ASSERT_FALSE(simulcast.sendVersions[0].choices[0].paused);
ASSERT_FALSE(simulcast.sendVersions[0].choices[1].paused);
ASSERT_EQ(1U, simulcast.sendVersions[1].choices.size());
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0]);
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0].rid);
ASSERT_TRUE(simulcast.sendVersions[1].choices[0].paused);
ASSERT_EQ(2U, simulcast.sendVersions[2].choices.size());
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0]);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1]);
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0].rid);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1].rid);
ASSERT_FALSE(simulcast.sendVersions[2].choices[0].paused);
ASSERT_TRUE(simulcast.sendVersions[2].choices[1].paused);
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
simulcast.recvVersions.type);
ASSERT_EQ(2U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1]);
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0].rid);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1].rid);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0]);
}
{
SdpSimulcastAttribute simulcast(
ParseSimulcast(" send pt=8,9;101;97,98 recv pt=101,120;97"));
ASSERT_EQ(3U, simulcast.sendVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.sendVersions.type);
ASSERT_EQ(2U, simulcast.sendVersions[0].choices.size());
ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
ASSERT_EQ("9", simulcast.sendVersions[0].choices[1]);
ASSERT_EQ(1U, simulcast.sendVersions[1].choices.size());
ASSERT_EQ("101", simulcast.sendVersions[1].choices[0]);
ASSERT_EQ(2U, simulcast.sendVersions[2].choices.size());
ASSERT_EQ("97", simulcast.sendVersions[2].choices[0]);
ASSERT_EQ("98", simulcast.sendVersions[2].choices[1]);
ASSERT_EQ(2U, simulcast.recvVersions.size());
ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
simulcast.recvVersions.type);
ASSERT_EQ(2U, simulcast.recvVersions[0].choices.size());
ASSERT_EQ("101", simulcast.recvVersions[0].choices[0]);
ASSERT_EQ("120", simulcast.recvVersions[0].choices[1]);
ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0]);
ASSERT_EQ("97", simulcast.recvVersions[1].choices[0].rid);
}
}
@ -5136,8 +5060,8 @@ TEST(NewSdpTestNoFixture, CheckSimulcastInvalidParse)
ParseInvalid<SdpSimulcastAttribute>("", 0);
ParseInvalid<SdpSimulcastAttribute>(" ", 1);
ParseInvalid<SdpSimulcastAttribute>("vcer ", 4);
ParseInvalid<SdpSimulcastAttribute>(" send pt=8 send ", 15);
ParseInvalid<SdpSimulcastAttribute>(" recv pt=8 recv ", 15);
ParseInvalid<SdpSimulcastAttribute>(" send 8 send ", 12);
ParseInvalid<SdpSimulcastAttribute>(" recv 8 recv ", 12);
}
static SdpRidAttributeList::Rid ParseRid(const std::string& input) {

View File

@ -136,7 +136,7 @@ void JsepTrack::AddToAnswer(const SdpMediaSection& offer,
std::vector<JsConstraints> constraints;
if (answer->IsSending()) {
constraints = mJsEncodeConstraints;
std::vector<SdpRidAttributeList::Rid> rids;
std::vector<std::pair<SdpRidAttributeList::Rid, bool>> rids;
GetRids(offer, sdp::kRecv, &rids);
NegotiateRids(rids, &constraints);
}
@ -192,14 +192,15 @@ void JsepTrack::AddToMsection(
// Updates the |id| values in |constraintsList| with the rid values in |rids|,
// where necessary.
void JsepTrack::NegotiateRids(
const std::vector<SdpRidAttributeList::Rid>& rids,
const std::vector<std::pair<SdpRidAttributeList::Rid, bool>>& rids,
std::vector<JsConstraints>* constraintsList) const {
for (const SdpRidAttributeList::Rid& rid : rids) {
if (!FindConstraints(rid.id, *constraintsList)) {
for (const auto& ridAndPaused : rids) {
if (!FindConstraints(ridAndPaused.first.id, *constraintsList)) {
// Pair up the first JsConstraints with an empty id, if it exists.
JsConstraints* constraints = FindConstraints("", *constraintsList);
if (constraints) {
constraints->rid = rid.id;
constraints->rid = ridAndPaused.first.id;
constraints->paused = ridAndPaused.second;
}
}
}
@ -239,7 +240,8 @@ void JsepTrack::AddToMsection(const std::vector<JsConstraints>& constraintsList,
rids->mRids.push_back(rid);
SdpSimulcastAttribute::Version version;
version.choices.push_back(constraints.rid);
version.choices.push_back(
SdpSimulcastAttribute::Encoding(constraints.rid, false));
if (direction == sdp::kSend) {
simulcast->sendVersions.push_back(version);
} else {
@ -259,9 +261,9 @@ void JsepTrack::AddToMsection(const std::vector<JsConstraints>& constraintsList,
}
}
void JsepTrack::GetRids(const SdpMediaSection& msection,
sdp::Direction direction,
std::vector<SdpRidAttributeList::Rid>* rids) const {
void JsepTrack::GetRids(
const SdpMediaSection& msection, sdp::Direction direction,
std::vector<std::pair<SdpRidAttributeList::Rid, bool>>* rids) const {
rids->clear();
if (!msection.GetAttributeList().HasAttribute(
SdpAttribute::kSimulcastAttribute)) {
@ -285,15 +287,11 @@ void JsepTrack::GetRids(const SdpMediaSection& msection,
return;
}
if (versions->type != SdpSimulcastAttribute::Versions::kRid) {
// No support for PT-based simulcast, yet.
return;
}
for (const SdpSimulcastAttribute::Version& version : *versions) {
if (!version.choices.empty()) {
// We validate that rids are present (and sane) elsewhere.
rids->push_back(*msection.FindRid(version.choices[0]));
rids->push_back(std::make_pair(*msection.FindRid(version.choices[0].rid),
version.choices[0].paused));
}
}
}
@ -315,13 +313,13 @@ void JsepTrack::CreateEncodings(
negotiatedDetails->mTias = remote.GetBandwidth("TIAS");
// TODO add support for b=AS if TIAS is not set (bug 976521)
std::vector<SdpRidAttributeList::Rid> rids;
std::vector<std::pair<SdpRidAttributeList::Rid, bool>> rids;
GetRids(remote, sdp::kRecv, &rids); // Get rids we will send
NegotiateRids(rids, &mJsEncodeConstraints);
if (rids.empty()) {
// Add dummy value with an empty id to make sure we get a single unicast
// stream.
rids.push_back(SdpRidAttributeList::Rid());
rids.push_back(std::make_pair(SdpRidAttributeList::Rid(), false));
}
size_t max_streams = 1;
@ -345,17 +343,18 @@ void JsepTrack::CreateEncodings(
auto& encoding = negotiatedDetails->mEncodings[i];
for (const auto& codec : negotiatedCodecs) {
if (rids[i].HasFormat(codec->mDefaultPt)) {
if (rids[i].first.HasFormat(codec->mDefaultPt)) {
encoding->AddCodec(*codec);
}
}
encoding->mRid = rids[i].id;
encoding->mRid = rids[i].first.id;
encoding->mPaused = rids[i].second;
// If we end up supporting params for rid, we would handle that here.
// Incorporate the corresponding JS encoding constraints, if they exist
for (const JsConstraints& jsConstraints : mJsEncodeConstraints) {
if (jsConstraints.rid == rids[i].id) {
if (jsConstraints.rid == rids[i].first.id) {
encoding->mConstraints = jsConstraints.constraints;
}
}

View File

@ -216,9 +216,11 @@ class JsepTrack {
struct JsConstraints {
std::string rid;
bool paused = false;
EncodingConstraints constraints;
bool operator==(const JsConstraints& other) const {
return rid == other.rid && constraints == other.constraints;
return rid == other.rid && paused == other.paused &&
constraints == other.constraints;
}
};
@ -243,8 +245,9 @@ class JsepTrack {
std::vector<uint16_t>* pts);
void AddToMsection(const std::vector<UniquePtr<JsepCodecDescription>>& codecs,
SdpMediaSection* msection);
void GetRids(const SdpMediaSection& msection, sdp::Direction direction,
std::vector<SdpRidAttributeList::Rid>* rids) const;
void GetRids(
const SdpMediaSection& msection, sdp::Direction direction,
std::vector<std::pair<SdpRidAttributeList::Rid, bool>>* rids) const;
void CreateEncodings(
const SdpMediaSection& remote,
const std::vector<UniquePtr<JsepCodecDescription>>& negotiatedCodecs,
@ -256,8 +259,9 @@ class JsepTrack {
JsConstraints* FindConstraints(
const std::string& rid,
std::vector<JsConstraints>& constraintsList) const;
void NegotiateRids(const std::vector<SdpRidAttributeList::Rid>& rids,
std::vector<JsConstraints>* constraints) const;
void NegotiateRids(
const std::vector<std::pair<SdpRidAttributeList::Rid, bool>>& rids,
std::vector<JsConstraints>* constraints) const;
void UpdateSsrcs(SsrcGenerator& ssrcGenerator, size_t encodings);
mozilla::SdpMediaSection::MediaType mType;

View File

@ -46,6 +46,7 @@ class JsepTrackEncoding {
EncodingConstraints mConstraints;
std::string mRid;
bool mPaused = false;
private:
std::vector<UniquePtr<JsepCodecDescription>> mCodecs;

View File

@ -892,7 +892,6 @@ SdpSimulcastAttribute::Versions LoadSimulcastVersions(
rustVersionArray.get());
SdpSimulcastAttribute::Versions versions;
versions.type = SdpSimulcastAttribute::Versions::kRid;
for (size_t i = 0; i < rustVersionCount; i++) {
const RustSdpAttributeSimulcastVersion& rustVersion = rustVersionArray[i];
@ -909,7 +908,8 @@ SdpSimulcastAttribute::Versions LoadSimulcastVersions(
const RustSdpAttributeSimulcastId& rustId = rustIdArray[j];
std::string id = convertStringView(rustId.id);
// TODO: Bug 1225877. Added support for 'paused'-state
version.choices.push_back(id);
version.choices.push_back(
SdpSimulcastAttribute::Encoding(id, rustId.paused));
}
versions.push_back(version);

View File

@ -1076,47 +1076,31 @@ void SdpSetupAttribute::Serialize(std::ostream& os) const {
void SdpSimulcastAttribute::Version::Serialize(std::ostream& os) const {
SkipFirstDelimiter comma(",");
for (const std::string& choice : choices) {
os << comma << choice;
for (const Encoding& choice : choices) {
os << comma;
if (choice.paused) {
os << '~';
}
os << choice.rid;
}
}
bool SdpSimulcastAttribute::Version::Parse(std::istream& is,
std::string* error) {
do {
bool paused = SkipChar(is, '~', error);
std::string value = ParseToken(is, ",; ", error);
if (value.empty()) {
*error = "Missing rid";
return false;
}
choices.push_back(value);
choices.push_back(Encoding(value, paused));
} while (SkipChar(is, ',', error));
return true;
}
bool SdpSimulcastAttribute::Version::GetChoicesAsFormats(
std::vector<uint16_t>* formats) const {
for (const std::string& choice : choices) {
uint16_t format;
if (!SdpHelper::GetPtAsInt(choice, &format) || (format > 127)) {
return false;
}
formats->push_back(format);
}
return true;
}
void SdpSimulcastAttribute::Versions::Serialize(std::ostream& os) const {
switch (type) {
case kRid:
os << "rid=";
break;
case kPt:
os << "pt=";
break;
}
SkipFirstDelimiter semic(";");
for (const Version& version : *this) {
if (!version.IsSet()) {
@ -1129,39 +1113,11 @@ void SdpSimulcastAttribute::Versions::Serialize(std::ostream& os) const {
bool SdpSimulcastAttribute::Versions::Parse(std::istream& is,
std::string* error) {
int startPos = is.tellg();
std::string rawType = ParseKey(is, error);
if (rawType.empty()) {
// New simulcast format does not have pt= or rid=, it is always rid
rawType = "rid";
is.clear();
is.seekg(startPos);
}
if (rawType == "pt") {
type = kPt;
} else if (rawType == "rid") {
type = kRid;
} else {
*error = "Unknown simulcast identification type ";
error->append(rawType);
return false;
}
do {
Version version;
if (!version.Parse(is, error)) {
return false;
}
if (type == kPt) {
std::vector<uint16_t> formats;
if (!version.GetChoicesAsFormats(&formats)) {
*error = "Invalid payload type";
return false;
}
}
push_back(version);
} while (SkipChar(is, ';', error));
@ -1174,12 +1130,15 @@ void SdpSimulcastAttribute::Serialize(std::ostream& os) const {
os << "a=" << mType << ":";
if (sendVersions.IsSet()) {
os << " send ";
os << "send ";
sendVersions.Serialize(os);
}
if (recvVersions.IsSet()) {
os << " recv ";
if (sendVersions.IsSet()) {
os << " ";
}
os << "recv ";
recvVersions.Serialize(os);
}

View File

@ -1535,21 +1535,25 @@ class SdpSimulcastAttribute : public SdpAttribute {
void Serialize(std::ostream& os) const override;
bool Parse(std::istream& is, std::string* error);
class Encoding {
public:
Encoding(const std::string& aRid, bool aPaused)
: rid(aRid), paused(aPaused) {}
std::string rid;
bool paused = false;
};
class Version {
public:
void Serialize(std::ostream& os) const;
bool IsSet() const { return !choices.empty(); }
bool Parse(std::istream& is, std::string* error);
bool GetChoicesAsFormats(std::vector<uint16_t>* formats) const;
std::vector<std::string> choices;
std::vector<Encoding> choices;
};
class Versions : public std::vector<Version> {
public:
enum Type { kPt, kRid };
Versions() : type(kRid) {}
void Serialize(std::ostream& os) const;
bool IsSet() const {
if (empty()) {
@ -1566,7 +1570,6 @@ class SdpSimulcastAttribute : public SdpAttribute {
}
bool Parse(std::istream& is, std::string* error);
Type type;
};
Versions sendVersions;

View File

@ -234,24 +234,14 @@ bool SipccSdpMediaSection::ValidateSimulcastVersions(
}
for (const SdpSimulcastAttribute::Version& version : versions) {
for (const std::string& id : version.choices) {
if (versions.type == SdpSimulcastAttribute::Versions::kRid) {
const SdpRidAttributeList::Rid* ridAttr = FindRid(id);
if (!ridAttr || (ridAttr->direction != direction)) {
std::ostringstream os;
os << "No rid attribute for \'" << id << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
} else if (versions.type == SdpSimulcastAttribute::Versions::kPt) {
if (std::find(mFormats.begin(), mFormats.end(), id) == mFormats.end()) {
std::ostringstream os;
os << "No pt for \'" << id << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
for (const SdpSimulcastAttribute::Encoding& encoding : version.choices) {
const SdpRidAttributeList::Rid* ridAttr = FindRid(encoding.rid);
if (!ridAttr || (ridAttr->direction != direction)) {
std::ostringstream os;
os << "No rid attribute for \'" << encoding.rid << "\'";
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
os.str());
return false;
}
}
}