Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prioritize having live videos in StreamPriorityBandwidthDistributor #1801

Merged
merged 14 commits into from
Feb 22, 2022
54 changes: 43 additions & 11 deletions erizo/src/erizo/bandwidth/StreamPriorityBWDistributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,21 @@ void StreamPriorityBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
// bitrate_for_priority is automatically initialized to 0 with the first [] call to the map
remaining_bitrate += bitrate_for_priority[priority];
bitrate_for_priority[priority] = 0;
uint64_t remaining_avg_bitrate = remaining_bitrate;
if (stream_infos[priority].size() > 0) {
remaining_avg_bitrate = remaining_bitrate / stream_infos[priority].size();
}
uint64_t remaining_avg_bitrate = calulateRemainingAverageBitrate(
0,
stream_infos[priority].size() + 1 , // calculate the average for all the streams including pos 0
remaining_bitrate);
uint64_t bitrate_for_lower_temporal_in_spatial = 0;
for (MediaStreamPriorityInfo& stream_info : stream_infos[priority]) {
for (std::size_t stream_position = 0; stream_position < stream_infos[priority].size(); ++stream_position) {
MediaStreamPriorityInfo& stream_info = stream_infos[priority][stream_position];
if (remaining_bitrate == 0) {
break;
}
uint64_t result_bitrate_for_stream = 0;
ELOG_DEBUG("Calculating for a new stream, priority %s, currently assigned %u, position %u",
priority.c_str(),
stream_info.assigned_bitrate,
stream_position);
uint64_t needed_bitrate_for_stream = 0;
if (is_max) {
stream_info.stream->setTargetIsMaxVideoBW(true);
Expand All @@ -89,6 +98,7 @@ void StreamPriorityBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
if (remaining_avg_bitrate >= bitrate_for_lower_temporal_in_spatial) {
distribute_bitrate_to_spatial_levels = true;
}
result_bitrate_for_stream = std::min(needed_bitrate_for_stream, remaining_avg_bitrate);
} else if (!stream_info.stream->isSimulcast()) {
ELOG_DEBUG("Stream %s is not simulcast", stream_info.stream->getId());
int number_of_layers = strategy_.getHighestLayerForPriority(priority) + 1;
Expand All @@ -97,6 +107,7 @@ void StreamPriorityBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
}
ELOG_DEBUG("Non-simulcast stream, number of layers %d, needed_bitrate %lu",
number_of_layers, needed_bitrate_for_stream);
result_bitrate_for_stream = std::min(needed_bitrate_for_stream, remaining_avg_bitrate);
} else {
uint64_t bitrate_for_higher_temporal_in_spatial =
stream_info.stream->getBitrateForHigherTemporalInSpatialLayer(layer);
Expand All @@ -112,18 +123,32 @@ void StreamPriorityBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
bitrate_for_higher_temporal_in_spatial == 0 ? max_bitrate_that_meets_constraints :
std::min(bitrate_for_higher_temporal_in_spatial, max_bitrate_that_meets_constraints);
needed_bitrate_for_stream = needed_bitrate_for_stream * (1 + QualityManager::kIncreaseLayerBitrateThreshold);
result_bitrate_for_stream = std::min(needed_bitrate_for_stream, remaining_avg_bitrate);
if (bitrate_for_lower_temporal_in_spatial > remaining_avg_bitrate && stream_info.assigned_bitrate == 0) {
// there is enough bitrate for a lower temporal layer, assign it we will adjust the avg later
ELOG_DEBUG("Assigning bitrate for lower temporal, remaining_avg %u, needed %u, lowest_temporal %u",
remaining_avg_bitrate,
needed_bitrate_for_stream,
bitrate_for_lower_temporal_in_spatial);
result_bitrate_for_stream =
std::min(static_cast<uint32_t>(bitrate_for_lower_temporal_in_spatial), remaining_bitrate);
}
}
uint64_t bitrate = std::min(needed_bitrate_for_stream, remaining_avg_bitrate);
uint64_t remb = std::min(static_cast<uint64_t>(stream_info.stream->getMaxVideoBW()), bitrate);

uint64_t remb = std::min(static_cast<uint64_t>(stream_info.stream->getMaxVideoBW()), result_bitrate_for_stream);
stream_info.assigned_bitrate = remb;
bitrate_for_priority[priority] += remb;
remaining_bitrate -= remb;
ELOG_DEBUG("needed_bitrate %lu, max_bitrate %u, bitrate %u, streams_in_priority %d, min_bitrate %u",
ELOG_DEBUG("needed_bitrate %lu, max_bitrate %u, rslt_br_for_str %u, streams_in_priority %d, min_bitrate %u",
needed_bitrate_for_stream,
stream_info.stream->getMaxVideoBW(),
bitrate, stream_infos[priority].size(), bitrate_for_lower_temporal_in_spatial);
result_bitrate_for_stream, stream_infos[priority].size(), bitrate_for_lower_temporal_in_spatial);
ELOG_DEBUG("Assigning bitrate %lu to stream %s, remaining %lu, distribute_bitrate_to_spatial_levels %d",
remb, stream_info.stream->getId().c_str(), remaining_bitrate, distribute_bitrate_to_spatial_levels);
remaining_avg_bitrate = calulateRemainingAverageBitrate(stream_position,
stream_infos[priority].size(),
remaining_bitrate);
ELOG_DEBUG("Recalculated remaining average %u", remaining_avg_bitrate);
}
}

Expand All @@ -140,6 +165,13 @@ void StreamPriorityBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
}
}



uint32_t StreamPriorityBWDistributor::calulateRemainingAverageBitrate(size_t position,
size_t total_size,
uint32_t remaining_bitrate) {
size_t remaining_streams = total_size - (position + 1);
if (remaining_streams == 0) {
return remaining_bitrate;
}
return remaining_bitrate/remaining_streams;
}
} // namespace erizo
1 change: 1 addition & 0 deletions erizo/src/erizo/bandwidth/StreamPriorityBWDistributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ DECLARE_LOGGER();
std::string getStrategyId();

bool tooLowBandwidthEstimation() override { return not_using_spatial_layers_; }
uint32_t calulateRemainingAverageBitrate(size_t position, size_t total_size, uint32_t remaining_bitrate);

private:
StreamPriorityStrategy strategy_;
Expand Down
38 changes: 36 additions & 2 deletions erizo/src/test/bandwidth/StreamPriorityBWDistributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ INSTANTIATE_TEST_CASE_P(
StreamPriorityStep("20", "1"),
StreamPriorityStep("20", "2")
},
100, EnabledList{1, 1, 1, 1}, ExpectedList{50, 50, 0, 0},
100, EnabledList{1, 1, 1, 1}, ExpectedList{100, 0, 0, 0},
true),
make_tuple(StreamConfigList{
{1000, 0, 450, "20", std::vector<std::vector<uint64_t>>({ { 50, 150, 300 }, { 250, 300, 450} }), false, true},
Expand Down Expand Up @@ -534,5 +534,39 @@ INSTANTIATE_TEST_CASE_P(
1000,
static_cast<uint32_t>(200 * (1 + QualityManager::kIncreaseLayerBitrateThreshold)),
static_cast<uint32_t>(200 * (1 + QualityManager::kIncreaseLayerBitrateThreshold))},
false)
false),
make_tuple(StreamConfigList{
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true}
},
StrategyVector{
StreamPriorityStep("20", "0"),
StreamPriorityStep("10", "0"),
StreamPriorityStep("10", "1"),
},
200, EnabledList{1, 1, 1, 1}, ExpectedList{
100,
100,
0,
0},
true),
make_tuple(StreamConfigList{
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true},
{1000, 0, 450, "10", std::vector<std::vector<uint64_t>>({ { 100, 150, 200 }, { 250, 300, 450} }), false, true}
},
StrategyVector{
StreamPriorityStep("20", "0"),
StreamPriorityStep("10", "0"),
StreamPriorityStep("10", "1"),
},
320, EnabledList{1, 1, 1, 1}, ExpectedList{
100,
100,
100,
20},
true)
));