Merge SimulcastStream and SpatialLayer structures.

Both simulcast stream and spatial layer can be described with the same
set of parameters. There is no need in two separate definitions.

1. Original definition of SpatialLayer is removed.
2. SimulcastStream is renamed to SpatialLayer.
3. SimulcastStream is equated to SpatialLayer using typedef.

Bug: webrtc:8518
Change-Id: I90761952b032a1b71fc4bba11f74a6daaf58880a
Reviewed-on: https://webrtc-review.googlesource.com/57102
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22272}
This commit is contained in:
Sergey Silkin 2018-03-02 12:28:00 +01:00 committed by Commit Bot
parent 9039969de2
commit 13e743419d
4 changed files with 76 additions and 20 deletions

View File

@ -496,9 +496,7 @@ union VideoCodecUnion {
VideoCodecH264 H264;
};
// Simulcast is when the same stream is encoded multiple times with different
// settings such as resolution.
struct SimulcastStream {
struct SpatialLayer {
unsigned short width;
unsigned short height;
unsigned char numberOfTemporalLayers;
@ -509,12 +507,9 @@ struct SimulcastStream {
bool active; // encoded and sent.
};
struct SpatialLayer {
int scaling_factor_num;
int scaling_factor_den;
int target_bitrate_bps;
// TODO(ivica): Add max_quantizer and min_quantizer?
};
// Simulcast is when the same stream is encoded multiple times with different
// settings such as resolution.
typedef SpatialLayer SimulcastStream;
enum VideoCodecMode { kRealtimeVideo, kScreensharing };

View File

@ -202,4 +202,41 @@ TEST_F(TestVp9Impl, EncoderRetainsRtpStateAfterRelease) {
1);
}
TEST_F(TestVp9Impl, EncoderExplicitLayering) {
// Override default settings.
codec_settings_.VP9()->numberOfTemporalLayers = 1;
codec_settings_.VP9()->numberOfSpatialLayers = 2;
codec_settings_.width = 960;
codec_settings_.height = 540;
codec_settings_.spatialLayers[0].targetBitrate = 500;
codec_settings_.spatialLayers[1].targetBitrate = 1000;
codec_settings_.spatialLayers[0].width = codec_settings_.width / 2;
codec_settings_.spatialLayers[0].height = codec_settings_.height / 2;
codec_settings_.spatialLayers[1].width = codec_settings_.width;
codec_settings_.spatialLayers[1].height = codec_settings_.height;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
// Ensure it fails if scaling factors in horz/vert dimentions are different.
codec_settings_.spatialLayers[0].width = codec_settings_.width;
codec_settings_.spatialLayers[0].height = codec_settings_.height / 2;
codec_settings_.spatialLayers[1].width = codec_settings_.width;
codec_settings_.spatialLayers[1].height = codec_settings_.height;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
// Ensure it fails if scaling factor is not power of two.
codec_settings_.spatialLayers[0].width = codec_settings_.width / 3;
codec_settings_.spatialLayers[0].height = codec_settings_.height / 3;
codec_settings_.spatialLayers[1].width = codec_settings_.width;
codec_settings_.spatialLayers[1].height = codec_settings_.height;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
}
} // namespace webrtc

View File

@ -124,8 +124,7 @@ int VP9EncoderImpl::Release() {
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;
return num_spatial_layers_ > 1 && codec_.spatialLayers[0].targetBitrate > 0;
}
bool VP9EncoderImpl::SetSvcRates() {
@ -139,13 +138,13 @@ bool VP9EncoderImpl::SetSvcRates() {
}
int total_bitrate_bps = 0;
for (i = 0; i < num_spatial_layers_; ++i)
total_bitrate_bps += codec_.spatialLayers[i].target_bitrate_bps;
total_bitrate_bps += codec_.spatialLayers[i].targetBitrate * 1000;
// 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 /
codec_.spatialLayers[i].targetBitrate * 1000 /
total_bitrate_bps);
}
} else {
@ -412,8 +411,27 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
if (ExplicitlyConfiguredSpatialLayers()) {
for (int i = 0; i < num_spatial_layers_; ++i) {
const auto& layer = codec_.spatialLayers[i];
svc_params_.scaling_factor_num[i] = layer.scaling_factor_num;
svc_params_.scaling_factor_den[i] = layer.scaling_factor_den;
const int scale_factor = codec_.width / layer.width;
RTC_DCHECK_GT(scale_factor, 0);
// Ensure scaler factor is integer.
if (scale_factor * layer.width != codec_.width) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
// Ensure scale factor is the same in both dimensions.
if (scale_factor * layer.height != codec_.height) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
// Ensure scale factor is power of two.
const bool is_pow_of_two = (scale_factor & (scale_factor - 1)) == 0;
if (!is_pow_of_two) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
svc_params_.scaling_factor_num[i] = 1;
svc_params_.scaling_factor_den[i] = scale_factor;
}
} else {
int scaling_factor_num = 256;

View File

@ -1326,12 +1326,18 @@ void VideoQualityTest::FillScalabilitySettings(
if (descriptor.empty())
continue;
std::vector<int> v = VideoQualityTest::ParseCSV(descriptor);
RTC_CHECK_GT(v[2], 0);
RTC_CHECK_EQ(v.size(), 7);
SpatialLayer layer = {0};
layer.width = v[0];
layer.height = v[1];
layer.numberOfTemporalLayers = v[2];
layer.maxBitrate = v[3];
layer.minBitrate = v[4];
layer.targetBitrate = v[5];
layer.qpMax = v[6];
layer.active = true;
SpatialLayer layer;
layer.scaling_factor_num = v[0] == -1 ? 1 : v[0];
layer.scaling_factor_den = v[1] == -1 ? 1 : v[1];
layer.target_bitrate_bps = v[2];
params->ss[video_idx].spatial_layers.push_back(layer);
}
}