Adding support for simulcast and spatial layers into VideoQualityTest
The CL includes several changes:
- Adding flags describing the streams and spatial layers.
- Reorganizing the order of the flags, to make them easier to maintain.
- Adding a member .params_ to VideoQualityAnalyzer.
(instead of passing it to every member function manually)
- Updating VideoAnalyzer to support simulcast.
(select appropriate ssrc and fix timestamps which are sometimes increased by 1)
- VP9EncoderImpl already had code for automatic calculation of bitrate for each layer.
Changing to first read bitrates and resolution ratios from the flags, if specified.
If not specified, reverting to the old code are setting the values automatically.
- Changing the parameters in LayerFilteringTransport, replacing
xx_discard_thresholds with selected_xx, to make it easier to use for the end user.
Review URL: https://codereview.webrtc.org/1353263005
Cr-Commit-Position: refs/heads/master@{#10215}
This commit is contained in:
@ -112,42 +112,72 @@ int VP9EncoderImpl::Release() {
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
bool VP9EncoderImpl::ExplicitlyConfiguredSpatialLayers() const {
|
||||
// We check target_bitrate_bps of the 0th layer to see if the spatial layers
|
||||
// (i.e. bitrates) were explicitly configured.
|
||||
return num_spatial_layers_ > 1 &&
|
||||
codec_.spatialLayers[0].target_bitrate_bps > 0;
|
||||
}
|
||||
|
||||
bool VP9EncoderImpl::SetSvcRates() {
|
||||
float rate_ratio[VPX_MAX_LAYERS] = {0};
|
||||
float total = 0;
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||
if (svc_internal_.svc_params.scaling_factor_num[i] <= 0 ||
|
||||
svc_internal_.svc_params.scaling_factor_den[i] <= 0) {
|
||||
if (ExplicitlyConfiguredSpatialLayers()) {
|
||||
if (num_temporal_layers_ > 1) {
|
||||
LOG(LS_ERROR) << "Multiple temporal layers when manually specifying "
|
||||
"spatial layers not implemented yet!";
|
||||
return false;
|
||||
}
|
||||
rate_ratio[i] = static_cast<float>(
|
||||
svc_internal_.svc_params.scaling_factor_num[i]) /
|
||||
svc_internal_.svc_params.scaling_factor_den[i];
|
||||
total += rate_ratio[i];
|
||||
}
|
||||
int total_bitrate_bps = 0;
|
||||
for (i = 0; i < num_spatial_layers_; ++i)
|
||||
total_bitrate_bps += codec_.spatialLayers[i].target_bitrate_bps;
|
||||
// If total bitrate differs now from what has been specified at the
|
||||
// beginning, update the bitrates in the same ratio as before.
|
||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||
config_->ss_target_bitrate[i] =
|
||||
config_->layer_target_bitrate[i] = static_cast<int>(
|
||||
static_cast<int64_t>(config_->rc_target_bitrate) *
|
||||
codec_.spatialLayers[i].target_bitrate_bps / total_bitrate_bps);
|
||||
}
|
||||
} else {
|
||||
float rate_ratio[VPX_MAX_LAYERS] = {0};
|
||||
float total = 0;
|
||||
|
||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||
config_->ss_target_bitrate[i] = static_cast<unsigned int>(
|
||||
config_->rc_target_bitrate * rate_ratio[i] / total);
|
||||
if (num_temporal_layers_ == 1) {
|
||||
config_->layer_target_bitrate[i] = config_->ss_target_bitrate[i];
|
||||
} else if (num_temporal_layers_ == 2) {
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] =
|
||||
config_->ss_target_bitrate[i] * 2 / 3;
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
|
||||
config_->ss_target_bitrate[i];
|
||||
} else if (num_temporal_layers_ == 3) {
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] =
|
||||
config_->ss_target_bitrate[i] / 2;
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] +
|
||||
(config_->ss_target_bitrate[i] / 4);
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 2] =
|
||||
config_->ss_target_bitrate[i];
|
||||
} else {
|
||||
return false;
|
||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||
if (svc_internal_.svc_params.scaling_factor_num[i] <= 0 ||
|
||||
svc_internal_.svc_params.scaling_factor_den[i] <= 0) {
|
||||
LOG(LS_ERROR) << "Scaling factors not specified!";
|
||||
return false;
|
||||
}
|
||||
rate_ratio[i] = static_cast<float>(
|
||||
svc_internal_.svc_params.scaling_factor_num[i]) /
|
||||
svc_internal_.svc_params.scaling_factor_den[i];
|
||||
total += rate_ratio[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||
config_->ss_target_bitrate[i] = static_cast<unsigned int>(
|
||||
config_->rc_target_bitrate * rate_ratio[i] / total);
|
||||
if (num_temporal_layers_ == 1) {
|
||||
config_->layer_target_bitrate[i] = config_->ss_target_bitrate[i];
|
||||
} else if (num_temporal_layers_ == 2) {
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] =
|
||||
config_->ss_target_bitrate[i] * 2 / 3;
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
|
||||
config_->ss_target_bitrate[i];
|
||||
} else if (num_temporal_layers_ == 3) {
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] =
|
||||
config_->ss_target_bitrate[i] / 2;
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_] +
|
||||
(config_->ss_target_bitrate[i] / 4);
|
||||
config_->layer_target_bitrate[i * num_temporal_layers_ + 2] =
|
||||
config_->ss_target_bitrate[i];
|
||||
} else {
|
||||
LOG(LS_ERROR) << "Unsupported number of temporal layers: "
|
||||
<< num_temporal_layers_;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,14 +385,24 @@ int VP9EncoderImpl::NumberOfThreads(int width,
|
||||
int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
|
||||
config_->ss_number_layers = num_spatial_layers_;
|
||||
|
||||
int scaling_factor_num = 256;
|
||||
for (int i = num_spatial_layers_ - 1; i >= 0; --i) {
|
||||
svc_internal_.svc_params.max_quantizers[i] = config_->rc_max_quantizer;
|
||||
svc_internal_.svc_params.min_quantizers[i] = config_->rc_min_quantizer;
|
||||
// 1:2 scaling in each dimension.
|
||||
svc_internal_.svc_params.scaling_factor_num[i] = scaling_factor_num;
|
||||
svc_internal_.svc_params.scaling_factor_den[i] = 256;
|
||||
scaling_factor_num /= 2;
|
||||
if (ExplicitlyConfiguredSpatialLayers()) {
|
||||
for (int i = 0; i < num_spatial_layers_; ++i) {
|
||||
const auto &layer = codec_.spatialLayers[i];
|
||||
svc_internal_.svc_params.max_quantizers[i] = config_->rc_max_quantizer;
|
||||
svc_internal_.svc_params.min_quantizers[i] = config_->rc_min_quantizer;
|
||||
svc_internal_.svc_params.scaling_factor_num[i] = layer.scaling_factor_num;
|
||||
svc_internal_.svc_params.scaling_factor_den[i] = layer.scaling_factor_den;
|
||||
}
|
||||
} else {
|
||||
int scaling_factor_num = 256;
|
||||
for (int i = num_spatial_layers_ - 1; i >= 0; --i) {
|
||||
svc_internal_.svc_params.max_quantizers[i] = config_->rc_max_quantizer;
|
||||
svc_internal_.svc_params.min_quantizers[i] = config_->rc_min_quantizer;
|
||||
// 1:2 scaling in each dimension.
|
||||
svc_internal_.svc_params.scaling_factor_num[i] = scaling_factor_num;
|
||||
svc_internal_.svc_params.scaling_factor_den[i] = 256;
|
||||
scaling_factor_num /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetSvcRates()) {
|
||||
|
||||
@ -56,6 +56,7 @@ class VP9EncoderImpl : public VP9Encoder {
|
||||
const vpx_codec_cx_pkt& pkt,
|
||||
uint32_t timestamp);
|
||||
|
||||
bool ExplicitlyConfiguredSpatialLayers() const;
|
||||
bool SetSvcRates();
|
||||
|
||||
virtual int GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt);
|
||||
|
||||
Reference in New Issue
Block a user