Skip to content

Commit

Permalink
Calculate target bitrate from max constrained layer (#1490)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Oct 25, 2019
1 parent 7693e93 commit 527823d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
8 changes: 5 additions & 3 deletions erizo/src/erizo/rtp/LayerDetectorHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ LayerDetectorHandler::LayerDetectorHandler(std::shared_ptr<erizo::Clock> the_clo
video_ssrc_list_ = std::vector<uint32_t>(kMaxSpatialLayers, 0);
video_frame_height_list_ = std::vector<uint32_t>(kMaxSpatialLayers, 0);
video_frame_width_list_ = std::vector<uint32_t>(kMaxSpatialLayers, 0);
video_frame_rate_list_ = std::vector<MovingIntervalRateStat>(kMaxTemporalLayers,
MovingIntervalRateStat{std::chrono::milliseconds(500), 10, .5, clock_});
video_frame_rate_list_ = std::vector<MovingIntervalRateStat>();
for (uint32_t i = 0; i < kMaxTemporalLayers; i++) {
video_frame_rate_list_.emplace_back(MovingIntervalRateStat{std::chrono::milliseconds(500), 10, .5, clock_});
}
}

void LayerDetectorHandler::enable() {
Expand Down Expand Up @@ -55,7 +57,7 @@ void LayerDetectorHandler::notifyLayerInfoChangedEvent() {
for (uint32_t temporal_layer = 0; temporal_layer < video_frame_rate_list_.size(); temporal_layer++) {
video_frame_rate_list.push_back(video_frame_rate_list_[temporal_layer].value());
ELOG_DEBUG("Temporal Layer (%u): %lu",
temporal_layer, video_frame_rate_list_[temporal_layer].value());
temporal_layer, video_frame_rate_list[temporal_layer]);
}

if (stream_) {
Expand Down
32 changes: 29 additions & 3 deletions erizo/src/erizo/rtp/QualityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,44 @@ bool QualityManager::doesLayerMeetConstraints(int spatial_layer, int temporal_la

bool meets_resolution = max_resolution_not_set || meets_width || meets_height;
bool meets_frame_rate = max_frame_rate_not_set || max_video_frame_rate >= layer_frame_rate;

return meets_resolution && meets_frame_rate;
}

void QualityManager::calculateMaxBitrateThatMeetsConstraints() {
int max_available_spatial_layer_that_meets_constraints = 0;
int max_available_temporal_layer_that_meets_constraints = 0;

int max_spatial_layer_with_resolution_info = 0;
if (video_frame_width_list_.size() > 0 && video_frame_height_list_.size() > 0) {
max_spatial_layer_with_resolution_info = std::min(static_cast<int>(video_frame_width_list_.size()) - 1,
static_cast<int>(video_frame_height_list_.size()) - 1);
}
int max_temporal_layer_with_frame_rate_info = std::max(static_cast<int>(video_frame_rate_list_.size()) - 1, 0);

int max_spatial_layer_available = std::min(max_spatial_layer_with_resolution_info, max_active_spatial_layer_);
int max_temporal_layer_available = std::min(max_temporal_layer_with_frame_rate_info, max_active_temporal_layer_);

for (int spatial_layer = 0; spatial_layer <= max_spatial_layer_available; spatial_layer++) {
for (int temporal_layer = 0; temporal_layer <= max_temporal_layer_available; temporal_layer++) {
if (doesLayerMeetConstraints(spatial_layer, temporal_layer)) {
max_available_spatial_layer_that_meets_constraints = spatial_layer;
max_available_temporal_layer_that_meets_constraints = temporal_layer;
}
}
}

stream_->setBitrateFromMaxQualityLayer(getInstantLayerBitrate(max_available_spatial_layer_that_meets_constraints,
max_available_temporal_layer_that_meets_constraints));
}

void QualityManager::selectLayer(bool try_higher_layers) {
if (!initialized_ || !stats_->getNode().hasChild("qualityLayers")) {
return;
}
stream_->setSimulcast(true);
last_quality_check_ = clock_->now();
calculateMaxBitrateThatMeetsConstraints();

int min_requested_spatial_layer =
enable_slideshow_below_spatial_layer_ ? std::max(slideshow_below_spatial_layer_, 0) : 0;
int min_valid_spatial_layer = std::min(min_requested_spatial_layer, max_active_spatial_layer_);
Expand Down Expand Up @@ -272,8 +300,6 @@ void QualityManager::calculateMaxActiveLayer() {

max_active_spatial_layer_ = max_active_spatial_layer;
max_active_temporal_layer_ = max_active_temporal_layer;

stream_->setBitrateFromMaxQualityLayer(getInstantLayerBitrate(max_active_spatial_layer, max_active_temporal_layer));
}

uint64_t QualityManager::getInstantLayerBitrate(int spatial_layer, int temporal_layer) {
Expand Down
1 change: 1 addition & 0 deletions erizo/src/erizo/rtp/QualityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class QualityManager: public Service, public std::enable_shared_from_this<Qualit

private:
void calculateMaxActiveLayer();
void calculateMaxBitrateThatMeetsConstraints();
void selectLayer(bool try_higher_layers);
uint64_t getInstantLayerBitrate(int spatial_layer, int temporal_layer);
bool isInBaseLayer();
Expand Down
15 changes: 13 additions & 2 deletions extras/basic_example/public/quality_layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,21 +230,32 @@ const updateCharts = (stream) => {
maxActiveSpatialLayer >= spatialLayer);
}
}
if (qualityLayersData.selectedSpatialLayer) {
if (qualityLayersData.selectedSpatialLayer !== undefined) {
selectedLayers += `Spatial: ${qualityLayersData.selectedSpatialLayer
} / Temporal: ${qualityLayersData.selectedTemporalLayer}`;
}
}

if (!data[i].total) {
return;
}
const totalBitrate = data[i].total.bitrateCalculated || 0;
const bitrateEstimated = data[i].total.senderBitrateEstimation || 0;
const remb = data[i].total.bandwidth || 0;
const targetVideoBitrate = data[i].total.targetVideoBitrate || 0;
const numberOfStreams = data[i].total.numberOfStreams || 0;
const paddingBitrate = data[i].total.paddingBitrate || 0;
const rtxBitrate = data[i].total.rtxBitrate || 0;

updateSeriesForKey(stream, subId, 'Current Received', undefined, undefined,
date, totalBitrate, selectedLayers);
updateSeriesForKey(stream, subId, 'Estimated Bandwidth', undefined, undefined,
date, bitrateEstimated);
updateSeriesForKey(stream, subId, 'REMB Bandwidth', undefined, undefined,
date, remb);
updateSeriesForKey(stream, subId, 'Target Video Bitrate', undefined, undefined,
date, targetVideoBitrate);
updateSeriesForKey(stream, subId, 'Number Of Streams', undefined, undefined,
date, numberOfStreams);
updateSeriesForKey(stream, subId, 'Padding Bitrate', undefined, undefined,
date, paddingBitrate);
updateSeriesForKey(stream, subId, 'Rtx Bitrate', undefined, undefined,
Expand Down

0 comments on commit 527823d

Please sign in to comment.