[Video, Svc] Remove inactive spatial layers in codec initializer
This is more logical way to remove inactive lower layers. Current way is to notify the encoder that the layer is inactive, then renumber layers at the packatization level. This Cl will allow to simplify libvpx vp9 encoder, svcRateAllocator and vp9 packetizer. Bug: webrtc:11319 Change-Id: Idf0bb30b729f5ecc97e31454b32934546b681aa2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/173182 Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31058}
This commit is contained in:

committed by
Commit Bot

parent
9f297b5960
commit
39fb817efd
@ -85,7 +85,7 @@ void ConfigureSvc(VideoCodec* codec_settings) {
|
|||||||
|
|
||||||
const std::vector<SpatialLayer> layers = GetSvcConfig(
|
const std::vector<SpatialLayer> layers = GetSvcConfig(
|
||||||
codec_settings->width, codec_settings->height, kMaxFramerateFps,
|
codec_settings->width, codec_settings->height, kMaxFramerateFps,
|
||||||
/*min_spatial_layers=*/1, codec_settings->VP9()->numberOfSpatialLayers,
|
/*first_active_layer=*/0, codec_settings->VP9()->numberOfSpatialLayers,
|
||||||
codec_settings->VP9()->numberOfTemporalLayers,
|
codec_settings->VP9()->numberOfTemporalLayers,
|
||||||
/* is_screen_sharing = */ false);
|
/* is_screen_sharing = */ false);
|
||||||
ASSERT_EQ(codec_settings->VP9()->numberOfSpatialLayers, layers.size())
|
ASSERT_EQ(codec_settings->VP9()->numberOfSpatialLayers, layers.size())
|
||||||
|
@ -61,10 +61,10 @@ std::vector<SpatialLayer> ConfigureSvcScreenSharing(size_t input_width,
|
|||||||
std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||||
size_t input_height,
|
size_t input_height,
|
||||||
float max_framerate_fps,
|
float max_framerate_fps,
|
||||||
size_t min_spatial_layers,
|
size_t first_active_layer,
|
||||||
size_t num_spatial_layers,
|
size_t num_spatial_layers,
|
||||||
size_t num_temporal_layers) {
|
size_t num_temporal_layers) {
|
||||||
RTC_DCHECK_LE(min_spatial_layers, num_spatial_layers);
|
RTC_DCHECK_LT(first_active_layer, num_spatial_layers);
|
||||||
std::vector<SpatialLayer> spatial_layers;
|
std::vector<SpatialLayer> spatial_layers;
|
||||||
|
|
||||||
// Limit number of layers for given resolution.
|
// Limit number of layers for given resolution.
|
||||||
@ -76,9 +76,11 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
|||||||
kMinVp9SpatialLayerHeight))));
|
kMinVp9SpatialLayerHeight))));
|
||||||
num_spatial_layers =
|
num_spatial_layers =
|
||||||
std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert});
|
std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert});
|
||||||
num_spatial_layers = std::max(num_spatial_layers, min_spatial_layers);
|
// First active layer must be configured.
|
||||||
|
num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1);
|
||||||
|
|
||||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
for (size_t sl_idx = first_active_layer; sl_idx < num_spatial_layers;
|
||||||
|
++sl_idx) {
|
||||||
SpatialLayer spatial_layer = {0};
|
SpatialLayer spatial_layer = {0};
|
||||||
spatial_layer.width = input_width >> (num_spatial_layers - sl_idx - 1);
|
spatial_layer.width = input_width >> (num_spatial_layers - sl_idx - 1);
|
||||||
spatial_layer.height = input_height >> (num_spatial_layers - sl_idx - 1);
|
spatial_layer.height = input_height >> (num_spatial_layers - sl_idx - 1);
|
||||||
@ -112,7 +114,7 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
|||||||
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
||||||
size_t input_height,
|
size_t input_height,
|
||||||
float max_framerate_fps,
|
float max_framerate_fps,
|
||||||
size_t min_spatial_layers,
|
size_t first_active_layer,
|
||||||
size_t num_spatial_layers,
|
size_t num_spatial_layers,
|
||||||
size_t num_temporal_layers,
|
size_t num_temporal_layers,
|
||||||
bool is_screen_sharing) {
|
bool is_screen_sharing) {
|
||||||
@ -126,7 +128,7 @@ std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
|||||||
max_framerate_fps, num_spatial_layers);
|
max_framerate_fps, num_spatial_layers);
|
||||||
} else {
|
} else {
|
||||||
return ConfigureSvcNormalVideo(input_width, input_height, max_framerate_fps,
|
return ConfigureSvcNormalVideo(input_width, input_height, max_framerate_fps,
|
||||||
min_spatial_layers, num_spatial_layers,
|
first_active_layer, num_spatial_layers,
|
||||||
num_temporal_layers);
|
num_temporal_layers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace webrtc {
|
|||||||
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
||||||
size_t input_height,
|
size_t input_height,
|
||||||
float max_framerate_fps,
|
float max_framerate_fps,
|
||||||
size_t min_spatial_layers,
|
size_t first_active_layer,
|
||||||
size_t num_spatial_layers,
|
size_t num_spatial_layers,
|
||||||
size_t num_temporal_layers,
|
size_t num_temporal_layers,
|
||||||
bool is_screen_sharing);
|
bool is_screen_sharing);
|
||||||
|
@ -19,35 +19,48 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
TEST(SvcConfig, NumSpatialLayers) {
|
TEST(SvcConfig, NumSpatialLayers) {
|
||||||
const size_t max_num_spatial_layers = 6;
|
const size_t max_num_spatial_layers = 6;
|
||||||
const size_t min_spatial_layers = 1;
|
const size_t first_active_layer = 0;
|
||||||
const size_t num_spatial_layers = 2;
|
const size_t num_spatial_layers = 2;
|
||||||
|
|
||||||
std::vector<SpatialLayer> spatial_layers =
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
||||||
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
||||||
min_spatial_layers, max_num_spatial_layers, 1, false);
|
first_active_layer, max_num_spatial_layers, 1, false);
|
||||||
|
|
||||||
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SvcConfig, NumSpatialLayersRespectsMinNumberOfLayers) {
|
TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) {
|
||||||
const size_t max_num_spatial_layers = 6;
|
const size_t max_num_spatial_layers = 6;
|
||||||
const size_t min_spatial_layers = 2;
|
const size_t first_active_layer = 5;
|
||||||
|
|
||||||
std::vector<SpatialLayer> spatial_layers =
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
GetSvcConfig(kMinVp9SpatialLayerWidth, kMinVp9SpatialLayerHeight, 30,
|
GetSvcConfig(kMinVp9SpatialLayerWidth, kMinVp9SpatialLayerHeight, 30,
|
||||||
min_spatial_layers, max_num_spatial_layers, 1, false);
|
first_active_layer, max_num_spatial_layers, 1, false);
|
||||||
|
EXPECT_EQ(spatial_layers.size(), 1u);
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SvcConfig, SkipsInactiveLayers) {
|
||||||
|
const size_t num_spatial_layers = 4;
|
||||||
|
const size_t first_active_layer = 2;
|
||||||
|
|
||||||
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
|
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
||||||
|
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
||||||
|
first_active_layer, num_spatial_layers, 1, false);
|
||||||
EXPECT_EQ(spatial_layers.size(), 2u);
|
EXPECT_EQ(spatial_layers.size(), 2u);
|
||||||
|
EXPECT_EQ(spatial_layers.back().width,
|
||||||
|
kMinVp9SpatialLayerWidth << (num_spatial_layers - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SvcConfig, BitrateThresholds) {
|
TEST(SvcConfig, BitrateThresholds) {
|
||||||
const size_t min_spatial_layers = 1;
|
const size_t first_active_layer = 0;
|
||||||
const size_t num_spatial_layers = 3;
|
const size_t num_spatial_layers = 3;
|
||||||
std::vector<SpatialLayer> spatial_layers =
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
||||||
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
||||||
min_spatial_layers, num_spatial_layers, 1, false);
|
first_active_layer, num_spatial_layers, 1, false);
|
||||||
|
|
||||||
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static VideoCodec Configure(size_t width,
|
|||||||
: VideoCodecMode::kRealtimeVideo;
|
: VideoCodecMode::kRealtimeVideo;
|
||||||
|
|
||||||
std::vector<SpatialLayer> spatial_layers =
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
GetSvcConfig(width, height, 30, /*min_spatial_layers=*/1,
|
GetSvcConfig(width, height, 30, /*first_active_layer=*/0,
|
||||||
num_spatial_layers, num_temporal_layers, is_screen_sharing);
|
num_spatial_layers, num_temporal_layers, is_screen_sharing);
|
||||||
RTC_CHECK_LE(spatial_layers.size(), kMaxSpatialLayers);
|
RTC_CHECK_LE(spatial_layers.size(), kMaxSpatialLayers);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ class TestVp9Impl : public VideoCodecUnitTest {
|
|||||||
|
|
||||||
std::vector<SpatialLayer> layers =
|
std::vector<SpatialLayer> layers =
|
||||||
GetSvcConfig(codec_settings_.width, codec_settings_.height,
|
GetSvcConfig(codec_settings_.width, codec_settings_.height,
|
||||||
codec_settings_.maxFramerate, /*min_spatial_layers=*/1,
|
codec_settings_.maxFramerate, /*first_active_layer=*/0,
|
||||||
num_spatial_layers, num_temporal_layers, false);
|
num_spatial_layers, num_temporal_layers, false);
|
||||||
for (size_t i = 0; i < layers.size(); ++i) {
|
for (size_t i = 0; i < layers.size(); ++i) {
|
||||||
codec_settings_.spatialLayers[i] = layers[i];
|
codec_settings_.spatialLayers[i] = layers[i];
|
||||||
|
@ -179,19 +179,18 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
|
|||||||
// Layering is set explicitly.
|
// Layering is set explicitly.
|
||||||
spatial_layers = config.spatial_layers;
|
spatial_layers = config.spatial_layers;
|
||||||
} else {
|
} else {
|
||||||
size_t min_required_layers = 0;
|
size_t first_active_layer = 0;
|
||||||
// Need at least enough layers for the first active one to be present.
|
|
||||||
for (size_t spatial_idx = 0;
|
for (size_t spatial_idx = 0;
|
||||||
spatial_idx < config.simulcast_layers.size(); ++spatial_idx) {
|
spatial_idx < config.simulcast_layers.size(); ++spatial_idx) {
|
||||||
if (config.simulcast_layers[spatial_idx].active) {
|
if (config.simulcast_layers[spatial_idx].active) {
|
||||||
min_required_layers = spatial_idx + 1;
|
first_active_layer = spatial_idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spatial_layers = GetSvcConfig(
|
spatial_layers = GetSvcConfig(
|
||||||
video_codec.width, video_codec.height, video_codec.maxFramerate,
|
video_codec.width, video_codec.height, video_codec.maxFramerate,
|
||||||
min_required_layers, video_codec.VP9()->numberOfSpatialLayers,
|
first_active_layer, video_codec.VP9()->numberOfSpatialLayers,
|
||||||
video_codec.VP9()->numberOfTemporalLayers,
|
video_codec.VP9()->numberOfTemporalLayers,
|
||||||
video_codec.mode == VideoCodecMode::kScreensharing);
|
video_codec.mode == VideoCodecMode::kScreensharing);
|
||||||
|
|
||||||
@ -210,7 +209,7 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
|
|||||||
spatial_idx < config.simulcast_layers.size() &&
|
spatial_idx < config.simulcast_layers.size() &&
|
||||||
spatial_idx < spatial_layers.size();
|
spatial_idx < spatial_layers.size();
|
||||||
++spatial_idx) {
|
++spatial_idx) {
|
||||||
spatial_layers[spatial_idx].active =
|
spatial_layers[spatial_idx - first_active_layer].active =
|
||||||
config.simulcast_layers[spatial_idx].active;
|
config.simulcast_layers[spatial_idx].active;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user