Ensure mediasession generated offers with RTX contain an RTX ssrc for each video ssrc.
BUG= R=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/49989004 Cr-Commit-Position: refs/heads/master@{#9210}
This commit is contained in:
@@ -436,8 +436,8 @@ static bool AddStreamParams(
|
|||||||
StreamParamsVec* current_streams,
|
StreamParamsVec* current_streams,
|
||||||
MediaContentDescriptionImpl<C>* content_description,
|
MediaContentDescriptionImpl<C>* content_description,
|
||||||
const bool add_legacy_stream) {
|
const bool add_legacy_stream) {
|
||||||
const bool include_rtx_stream =
|
const bool include_rtx_streams =
|
||||||
ContainsRtxCodec(content_description->codecs());
|
ContainsRtxCodec(content_description->codecs());
|
||||||
|
|
||||||
if (streams.empty() && add_legacy_stream) {
|
if (streams.empty() && add_legacy_stream) {
|
||||||
// TODO(perkj): Remove this legacy stream when all apps use StreamParams.
|
// TODO(perkj): Remove this legacy stream when all apps use StreamParams.
|
||||||
@@ -445,10 +445,10 @@ static bool AddStreamParams(
|
|||||||
if (IsSctp(content_description)) {
|
if (IsSctp(content_description)) {
|
||||||
GenerateSctpSids(*current_streams, &ssrcs);
|
GenerateSctpSids(*current_streams, &ssrcs);
|
||||||
} else {
|
} else {
|
||||||
int num_ssrcs = include_rtx_stream ? 2 : 1;
|
int num_ssrcs = include_rtx_streams ? 2 : 1;
|
||||||
GenerateSsrcs(*current_streams, num_ssrcs, &ssrcs);
|
GenerateSsrcs(*current_streams, num_ssrcs, &ssrcs);
|
||||||
}
|
}
|
||||||
if (include_rtx_stream) {
|
if (include_rtx_streams) {
|
||||||
content_description->AddLegacyStream(ssrcs[0], ssrcs[1]);
|
content_description->AddLegacyStream(ssrcs[0], ssrcs[1]);
|
||||||
content_description->set_multistream(true);
|
content_description->set_multistream(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -492,11 +492,15 @@ static bool AddStreamParams(
|
|||||||
SsrcGroup group(kSimSsrcGroupSemantics, stream_param.ssrcs);
|
SsrcGroup group(kSimSsrcGroupSemantics, stream_param.ssrcs);
|
||||||
stream_param.ssrc_groups.push_back(group);
|
stream_param.ssrc_groups.push_back(group);
|
||||||
}
|
}
|
||||||
// Generate an extra ssrc for include_rtx_stream case.
|
// Generate extra ssrcs for include_rtx_streams case.
|
||||||
if (include_rtx_stream) {
|
if (include_rtx_streams) {
|
||||||
std::vector<uint32> rtx_ssrc;
|
// Generate an RTX ssrc for every ssrc in the group.
|
||||||
GenerateSsrcs(*current_streams, 1, &rtx_ssrc);
|
std::vector<uint32> rtx_ssrcs;
|
||||||
stream_param.AddFidSsrc(ssrcs[0], rtx_ssrc[0]);
|
GenerateSsrcs(*current_streams, static_cast<int>(ssrcs.size()),
|
||||||
|
&rtx_ssrcs);
|
||||||
|
for (size_t i = 0; i < ssrcs.size(); ++i) {
|
||||||
|
stream_param.AddFidSsrc(ssrcs[i], rtx_ssrcs[i]);
|
||||||
|
}
|
||||||
content_description->set_multistream(true);
|
content_description->set_multistream(true);
|
||||||
}
|
}
|
||||||
stream_param.cname = cname;
|
stream_param.cname = cname;
|
||||||
|
@@ -1767,6 +1767,47 @@ TEST_F(MediaSessionDescriptionFactoryTest,
|
|||||||
EXPECT_EQ(expected_codecs, vcd->codecs());
|
EXPECT_EQ(expected_codecs, vcd->codecs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that when RTX is used in conjunction with simulcast, an RTX ssrc is
|
||||||
|
// generated for each simulcast ssrc and correctly grouped.
|
||||||
|
TEST_F(MediaSessionDescriptionFactoryTest, SimSsrcsGenerateMultipleRtxSsrcs) {
|
||||||
|
MediaSessionOptions opts;
|
||||||
|
opts.recv_video = true;
|
||||||
|
opts.recv_audio = false;
|
||||||
|
|
||||||
|
// Add simulcast streams.
|
||||||
|
opts.AddSendVideoStream("stream1", "stream1label", 3);
|
||||||
|
|
||||||
|
// Use a single real codec, and then add RTX for it.
|
||||||
|
std::vector<VideoCodec> f1_codecs;
|
||||||
|
f1_codecs.push_back(VideoCodec(97, "H264", 320, 200, 30, 1));
|
||||||
|
AddRtxCodec(VideoCodec::CreateRtxCodec(125, 97), &f1_codecs);
|
||||||
|
f1_.set_video_codecs(f1_codecs);
|
||||||
|
|
||||||
|
// Ensure that the offer has an RTX ssrc for each regular ssrc, and that there
|
||||||
|
// is a FID ssrc + grouping for each.
|
||||||
|
rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
|
||||||
|
ASSERT_TRUE(offer.get() != NULL);
|
||||||
|
VideoContentDescription* desc = static_cast<VideoContentDescription*>(
|
||||||
|
offer->GetContentDescriptionByName(cricket::CN_VIDEO));
|
||||||
|
ASSERT_TRUE(desc != NULL);
|
||||||
|
EXPECT_TRUE(desc->multistream());
|
||||||
|
const StreamParamsVec& streams = desc->streams();
|
||||||
|
// Single stream.
|
||||||
|
ASSERT_EQ(1u, streams.size());
|
||||||
|
// Stream should have 6 ssrcs: 3 for video, 3 for RTX.
|
||||||
|
EXPECT_EQ(6u, streams[0].ssrcs.size());
|
||||||
|
// And should have a SIM group for the simulcast.
|
||||||
|
EXPECT_TRUE(streams[0].has_ssrc_group("SIM"));
|
||||||
|
// And a FID group for RTX.
|
||||||
|
EXPECT_TRUE(streams[0].has_ssrc_group("FID"));
|
||||||
|
std::vector<uint32> primary_ssrcs;
|
||||||
|
streams[0].GetPrimarySsrcs(&primary_ssrcs);
|
||||||
|
EXPECT_EQ(3u, primary_ssrcs.size());
|
||||||
|
std::vector<uint32> fid_ssrcs;
|
||||||
|
streams[0].GetFidSsrcs(primary_ssrcs, &fid_ssrcs);
|
||||||
|
EXPECT_EQ(3u, fid_ssrcs.size());
|
||||||
|
}
|
||||||
|
|
||||||
// Create an updated offer after creating an answer to the original offer and
|
// Create an updated offer after creating an answer to the original offer and
|
||||||
// verify that the RTP header extensions that were part of the original answer
|
// verify that the RTP header extensions that were part of the original answer
|
||||||
// are not changed in the updated offer.
|
// are not changed in the updated offer.
|
||||||
|
Reference in New Issue
Block a user