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:
parent
9039969de2
commit
13e743419d
@ -496,9 +496,7 @@ union VideoCodecUnion {
|
|||||||
VideoCodecH264 H264;
|
VideoCodecH264 H264;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simulcast is when the same stream is encoded multiple times with different
|
struct SpatialLayer {
|
||||||
// settings such as resolution.
|
|
||||||
struct SimulcastStream {
|
|
||||||
unsigned short width;
|
unsigned short width;
|
||||||
unsigned short height;
|
unsigned short height;
|
||||||
unsigned char numberOfTemporalLayers;
|
unsigned char numberOfTemporalLayers;
|
||||||
@ -509,12 +507,9 @@ struct SimulcastStream {
|
|||||||
bool active; // encoded and sent.
|
bool active; // encoded and sent.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpatialLayer {
|
// Simulcast is when the same stream is encoded multiple times with different
|
||||||
int scaling_factor_num;
|
// settings such as resolution.
|
||||||
int scaling_factor_den;
|
typedef SpatialLayer SimulcastStream;
|
||||||
int target_bitrate_bps;
|
|
||||||
// TODO(ivica): Add max_quantizer and min_quantizer?
|
|
||||||
};
|
|
||||||
|
|
||||||
enum VideoCodecMode { kRealtimeVideo, kScreensharing };
|
enum VideoCodecMode { kRealtimeVideo, kScreensharing };
|
||||||
|
|
||||||
|
|||||||
@ -202,4 +202,41 @@ TEST_F(TestVp9Impl, EncoderRetainsRtpStateAfterRelease) {
|
|||||||
1);
|
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
|
} // namespace webrtc
|
||||||
|
|||||||
@ -124,8 +124,7 @@ int VP9EncoderImpl::Release() {
|
|||||||
bool VP9EncoderImpl::ExplicitlyConfiguredSpatialLayers() const {
|
bool VP9EncoderImpl::ExplicitlyConfiguredSpatialLayers() const {
|
||||||
// We check target_bitrate_bps of the 0th layer to see if the spatial layers
|
// We check target_bitrate_bps of the 0th layer to see if the spatial layers
|
||||||
// (i.e. bitrates) were explicitly configured.
|
// (i.e. bitrates) were explicitly configured.
|
||||||
return num_spatial_layers_ > 1 &&
|
return num_spatial_layers_ > 1 && codec_.spatialLayers[0].targetBitrate > 0;
|
||||||
codec_.spatialLayers[0].target_bitrate_bps > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VP9EncoderImpl::SetSvcRates() {
|
bool VP9EncoderImpl::SetSvcRates() {
|
||||||
@ -139,13 +138,13 @@ bool VP9EncoderImpl::SetSvcRates() {
|
|||||||
}
|
}
|
||||||
int total_bitrate_bps = 0;
|
int total_bitrate_bps = 0;
|
||||||
for (i = 0; i < num_spatial_layers_; ++i)
|
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
|
// If total bitrate differs now from what has been specified at the
|
||||||
// beginning, update the bitrates in the same ratio as before.
|
// beginning, update the bitrates in the same ratio as before.
|
||||||
for (i = 0; i < num_spatial_layers_; ++i) {
|
for (i = 0; i < num_spatial_layers_; ++i) {
|
||||||
config_->ss_target_bitrate[i] = config_->layer_target_bitrate[i] =
|
config_->ss_target_bitrate[i] = config_->layer_target_bitrate[i] =
|
||||||
static_cast<int>(static_cast<int64_t>(config_->rc_target_bitrate) *
|
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);
|
total_bitrate_bps);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -412,8 +411,27 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
|
|||||||
if (ExplicitlyConfiguredSpatialLayers()) {
|
if (ExplicitlyConfiguredSpatialLayers()) {
|
||||||
for (int i = 0; i < num_spatial_layers_; ++i) {
|
for (int i = 0; i < num_spatial_layers_; ++i) {
|
||||||
const auto& layer = codec_.spatialLayers[i];
|
const auto& layer = codec_.spatialLayers[i];
|
||||||
svc_params_.scaling_factor_num[i] = layer.scaling_factor_num;
|
const int scale_factor = codec_.width / layer.width;
|
||||||
svc_params_.scaling_factor_den[i] = layer.scaling_factor_den;
|
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 {
|
} else {
|
||||||
int scaling_factor_num = 256;
|
int scaling_factor_num = 256;
|
||||||
|
|||||||
@ -1326,12 +1326,18 @@ void VideoQualityTest::FillScalabilitySettings(
|
|||||||
if (descriptor.empty())
|
if (descriptor.empty())
|
||||||
continue;
|
continue;
|
||||||
std::vector<int> v = VideoQualityTest::ParseCSV(descriptor);
|
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);
|
params->ss[video_idx].spatial_layers.push_back(layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user