Ensure that the first active layer isn't disabled by too low input resolution
If e.g. CPU adaptation reduces input video size too much, video pipeline would reduce the number of used simulcast streams/spatial layers. This may result in disabled video if some streams are disabled by Rtp encoding parameters API. Bug: webrtc:11319 Change-Id: Id7f157255599dcb6f494129b83477cda4bea982a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168480 Reviewed-by: Evan Shrubsole <eshr@google.com> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30498}
This commit is contained in:
committed by
Commit Bot
parent
ccd49d9af6
commit
03d909634b
@ -62,8 +62,8 @@ const int kMaxQp = 56;
|
||||
|
||||
void ConfigureSimulcast(VideoCodec* codec_settings) {
|
||||
const std::vector<webrtc::VideoStream> streams = cricket::GetSimulcastConfig(
|
||||
codec_settings->numberOfSimulcastStreams, codec_settings->width,
|
||||
codec_settings->height, kBitratePriority, kMaxQp,
|
||||
/*min_layer=*/1, codec_settings->numberOfSimulcastStreams,
|
||||
codec_settings->width, codec_settings->height, kBitratePriority, kMaxQp,
|
||||
/* is_screenshare = */ false, true);
|
||||
|
||||
for (size_t i = 0; i < streams.size(); ++i) {
|
||||
@ -85,7 +85,7 @@ void ConfigureSvc(VideoCodec* codec_settings) {
|
||||
|
||||
const std::vector<SpatialLayer> layers = GetSvcConfig(
|
||||
codec_settings->width, codec_settings->height, kMaxFramerateFps,
|
||||
codec_settings->VP9()->numberOfSpatialLayers,
|
||||
/*min_spatial_layers=*/1, codec_settings->VP9()->numberOfSpatialLayers,
|
||||
codec_settings->VP9()->numberOfTemporalLayers,
|
||||
/* is_screen_sharing = */ false);
|
||||
ASSERT_EQ(codec_settings->VP9()->numberOfSpatialLayers, layers.size())
|
||||
|
||||
@ -61,8 +61,10 @@ std::vector<SpatialLayer> ConfigureSvcScreenSharing(size_t input_width,
|
||||
std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||
size_t input_height,
|
||||
float max_framerate_fps,
|
||||
size_t min_spatial_layers,
|
||||
size_t num_spatial_layers,
|
||||
size_t num_temporal_layers) {
|
||||
RTC_DCHECK_LE(min_spatial_layers, num_spatial_layers);
|
||||
std::vector<SpatialLayer> spatial_layers;
|
||||
|
||||
// Limit number of layers for given resolution.
|
||||
@ -74,6 +76,7 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||
kMinVp9SpatialLayerHeight))));
|
||||
num_spatial_layers =
|
||||
std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert});
|
||||
num_spatial_layers = std::max(num_spatial_layers, min_spatial_layers);
|
||||
|
||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
||||
SpatialLayer spatial_layer = {0};
|
||||
@ -109,6 +112,7 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
||||
size_t input_height,
|
||||
float max_framerate_fps,
|
||||
size_t min_spatial_layers,
|
||||
size_t num_spatial_layers,
|
||||
size_t num_temporal_layers,
|
||||
bool is_screen_sharing) {
|
||||
@ -122,7 +126,8 @@ std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
||||
max_framerate_fps, num_spatial_layers);
|
||||
} else {
|
||||
return ConfigureSvcNormalVideo(input_width, input_height, max_framerate_fps,
|
||||
num_spatial_layers, num_temporal_layers);
|
||||
min_spatial_layers, num_spatial_layers,
|
||||
num_temporal_layers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ namespace webrtc {
|
||||
std::vector<SpatialLayer> GetSvcConfig(size_t input_width,
|
||||
size_t input_height,
|
||||
float max_framerate_fps,
|
||||
size_t min_spatial_layers,
|
||||
size_t num_spatial_layers,
|
||||
size_t num_temporal_layers,
|
||||
bool is_screen_sharing);
|
||||
|
||||
@ -19,22 +19,35 @@
|
||||
namespace webrtc {
|
||||
TEST(SvcConfig, NumSpatialLayers) {
|
||||
const size_t max_num_spatial_layers = 6;
|
||||
const size_t min_spatial_layers = 1;
|
||||
const size_t num_spatial_layers = 2;
|
||||
|
||||
std::vector<SpatialLayer> spatial_layers =
|
||||
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
||||
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
||||
max_num_spatial_layers, 1, false);
|
||||
min_spatial_layers, max_num_spatial_layers, 1, false);
|
||||
|
||||
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
||||
}
|
||||
|
||||
TEST(SvcConfig, NumSpatialLayersRespectsMinNumberOfLayers) {
|
||||
const size_t max_num_spatial_layers = 6;
|
||||
const size_t min_spatial_layers = 2;
|
||||
|
||||
std::vector<SpatialLayer> spatial_layers =
|
||||
GetSvcConfig(kMinVp9SpatialLayerWidth, kMinVp9SpatialLayerHeight, 30,
|
||||
min_spatial_layers, max_num_spatial_layers, 1, false);
|
||||
|
||||
EXPECT_EQ(spatial_layers.size(), 2u);
|
||||
}
|
||||
|
||||
TEST(SvcConfig, BitrateThresholds) {
|
||||
const size_t min_spatial_layers = 1;
|
||||
const size_t num_spatial_layers = 3;
|
||||
std::vector<SpatialLayer> spatial_layers =
|
||||
GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1),
|
||||
kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30,
|
||||
num_spatial_layers, 1, false);
|
||||
min_spatial_layers, num_spatial_layers, 1, false);
|
||||
|
||||
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
|
||||
|
||||
@ -47,7 +60,7 @@ TEST(SvcConfig, BitrateThresholds) {
|
||||
|
||||
TEST(SvcConfig, ScreenSharing) {
|
||||
std::vector<SpatialLayer> spatial_layers =
|
||||
GetSvcConfig(1920, 1080, 30, 3, 3, true);
|
||||
GetSvcConfig(1920, 1080, 30, 1, 3, 3, true);
|
||||
|
||||
EXPECT_EQ(spatial_layers.size(), 3UL);
|
||||
|
||||
|
||||
@ -34,8 +34,8 @@ static VideoCodec Configure(size_t width,
|
||||
: VideoCodecMode::kRealtimeVideo;
|
||||
|
||||
std::vector<SpatialLayer> spatial_layers =
|
||||
GetSvcConfig(width, height, 30, num_spatial_layers, num_temporal_layers,
|
||||
is_screen_sharing);
|
||||
GetSvcConfig(width, height, 30, /*min_spatial_layers=*/1,
|
||||
num_spatial_layers, num_temporal_layers, is_screen_sharing);
|
||||
RTC_CHECK_LE(spatial_layers.size(), kMaxSpatialLayers);
|
||||
|
||||
codec.VP9()->numberOfSpatialLayers =
|
||||
|
||||
@ -114,8 +114,8 @@ class TestVp9Impl : public VideoCodecUnitTest {
|
||||
|
||||
std::vector<SpatialLayer> layers =
|
||||
GetSvcConfig(codec_settings_.width, codec_settings_.height,
|
||||
codec_settings_.maxFramerate, num_spatial_layers,
|
||||
num_temporal_layers, false);
|
||||
codec_settings_.maxFramerate, /*min_spatial_layers=*/1,
|
||||
num_spatial_layers, num_temporal_layers, false);
|
||||
for (size_t i = 0; i < layers.size(); ++i) {
|
||||
codec_settings_.spatialLayers[i] = layers[i];
|
||||
}
|
||||
|
||||
@ -179,9 +179,19 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
|
||||
// Layering is set explicitly.
|
||||
spatial_layers = config.spatial_layers;
|
||||
} else {
|
||||
size_t min_required_layers = 0;
|
||||
// Need at least enough layers for the first active one to be present.
|
||||
for (size_t spatial_idx = 0;
|
||||
spatial_idx < config.simulcast_layers.size(); ++spatial_idx) {
|
||||
if (config.simulcast_layers[spatial_idx].active) {
|
||||
min_required_layers = spatial_idx + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spatial_layers = GetSvcConfig(
|
||||
video_codec.width, video_codec.height, video_codec.maxFramerate,
|
||||
video_codec.VP9()->numberOfSpatialLayers,
|
||||
min_required_layers, video_codec.VP9()->numberOfSpatialLayers,
|
||||
video_codec.VP9()->numberOfTemporalLayers,
|
||||
video_codec.mode == VideoCodecMode::kScreensharing);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user