Allow HVGA Vp9 SVC to have 2 spatial layers and remove excessive rounding
Bug: webrtc:11652 Change-Id: I8bfa91c3115d6ebb17beefbb2a5e51efbbd599e0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/177000 Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31502}
This commit is contained in:

committed by
Commit Bot

parent
f72de7bb61
commit
2899b3bc3d
@ -536,6 +536,7 @@ rtc_library("webrtc_vp9_helpers") {
|
|||||||
"../../api/video_codecs:video_codecs_api",
|
"../../api/video_codecs:video_codecs_api",
|
||||||
"../../common_video",
|
"../../common_video",
|
||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
|
"../../rtc_base:logging",
|
||||||
"../../rtc_base/experiments:stable_target_rate_experiment",
|
"../../rtc_base/experiments:stable_target_rate_experiment",
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector" ]
|
||||||
|
@ -30,8 +30,8 @@ const size_t kMaxVp9RefPics = 3;
|
|||||||
const size_t kMaxVp9FramesInGof = 0xFF; // 8 bits
|
const size_t kMaxVp9FramesInGof = 0xFF; // 8 bits
|
||||||
const size_t kMaxVp9NumberOfSpatialLayers = 8;
|
const size_t kMaxVp9NumberOfSpatialLayers = 8;
|
||||||
|
|
||||||
const size_t kMinVp9SpatialLayerWidth = 320;
|
const size_t kMinVp9SpatialLayerWidth = 240;
|
||||||
const size_t kMinVp9SpatialLayerHeight = 180;
|
const size_t kMinVp9SpatialLayerHeight = 135;
|
||||||
|
|
||||||
enum TemporalStructureMode {
|
enum TemporalStructureMode {
|
||||||
kTemporalStructureMode1, // 1 temporal layer structure - i.e., IPPP...
|
kTemporalStructureMode1, // 1 temporal layer structure - i.e., IPPP...
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -74,13 +75,20 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
|||||||
const size_t num_layers_fit_vert = static_cast<size_t>(
|
const size_t num_layers_fit_vert = static_cast<size_t>(
|
||||||
std::floor(1 + std::max(0.0f, std::log2(1.0f * input_height /
|
std::floor(1 + std::max(0.0f, std::log2(1.0f * input_height /
|
||||||
kMinVp9SpatialLayerHeight))));
|
kMinVp9SpatialLayerHeight))));
|
||||||
num_spatial_layers =
|
const size_t limited_num_spatial_layers =
|
||||||
std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert});
|
std::min(num_layers_fit_horz, num_layers_fit_vert);
|
||||||
|
if (limited_num_spatial_layers < num_spatial_layers) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Reducing number of spatial layers from "
|
||||||
|
<< num_spatial_layers << " to "
|
||||||
|
<< limited_num_spatial_layers
|
||||||
|
<< " due to low input resolution.";
|
||||||
|
num_spatial_layers = limited_num_spatial_layers;
|
||||||
|
}
|
||||||
// First active layer must be configured.
|
// First active layer must be configured.
|
||||||
num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1);
|
num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1);
|
||||||
|
|
||||||
// Ensure top layer is even enough.
|
// Ensure top layer is even enough.
|
||||||
int required_divisiblity = 1 << num_spatial_layers;
|
int required_divisiblity = 1 << (num_spatial_layers - first_active_layer - 1);
|
||||||
input_width = input_width - input_width % required_divisiblity;
|
input_width = input_width - input_width % required_divisiblity;
|
||||||
input_height = input_height - input_height % required_divisiblity;
|
input_height = input_height - input_height % required_divisiblity;
|
||||||
|
|
||||||
|
@ -41,6 +41,32 @@ TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) {
|
|||||||
EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerWidth);
|
EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SvcConfig, EnforcesMinimalRequiredParity) {
|
||||||
|
const size_t max_num_spatial_layers = 3;
|
||||||
|
const size_t kOddSize = 1023;
|
||||||
|
|
||||||
|
std::vector<SpatialLayer> spatial_layers =
|
||||||
|
GetSvcConfig(kOddSize, kOddSize, 30,
|
||||||
|
/*first_active_layer=*/1, max_num_spatial_layers, 1, false);
|
||||||
|
// Since there are 2 layers total (1, 2), divisiblity by 2 is required.
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize - 1);
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize - 1);
|
||||||
|
|
||||||
|
spatial_layers =
|
||||||
|
GetSvcConfig(kOddSize, kOddSize, 30,
|
||||||
|
/*first_active_layer=*/0, max_num_spatial_layers, 1, false);
|
||||||
|
// Since there are 3 layers total (0, 1, 2), divisiblity by 4 is required.
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize - 3);
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize - 3);
|
||||||
|
|
||||||
|
spatial_layers =
|
||||||
|
GetSvcConfig(kOddSize, kOddSize, 30,
|
||||||
|
/*first_active_layer=*/2, max_num_spatial_layers, 1, false);
|
||||||
|
// Since there is only 1 layer active (2), divisiblity by 1 is required.
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize);
|
||||||
|
EXPECT_EQ(spatial_layers.back().width, kOddSize);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SvcConfig, SkipsInactiveLayers) {
|
TEST(SvcConfig, SkipsInactiveLayers) {
|
||||||
const size_t num_spatial_layers = 4;
|
const size_t num_spatial_layers = 4;
|
||||||
const size_t first_active_layer = 2;
|
const size_t first_active_layer = 2;
|
||||||
|
Reference in New Issue
Block a user