Skip to content

Commit 09eb6e2

Browse files
Ilya NikolaevskiyCommit Bot
authored andcommitted
[VP9 SVC] Round spatial layers dimensions to ensure integer scaling factors are used
Bug: webrtc:11652 Change-Id: Id3642d607f62b72a567d521d9874b8588c2ce429 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176517 Reviewed-by: Erik Språng <[email protected]> Commit-Queue: Ilya Nikolaevskiy <[email protected]> Cr-Commit-Position: refs/heads/master@{#31465}
1 parent 9766b89 commit 09eb6e2

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

modules/video_coding/codecs/vp9/svc_config.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
7979
// First active layer must be configured.
8080
num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1);
8181

82+
// Ensure top layer is even enough.
83+
int required_divisiblity = 1 << num_spatial_layers;
84+
input_width = input_width - input_width % required_divisiblity;
85+
input_height = input_height - input_height % required_divisiblity;
86+
8287
for (size_t sl_idx = first_active_layer; sl_idx < num_spatial_layers;
8388
++sl_idx) {
8489
SpatialLayer spatial_layer = {0};

modules/video_coding/video_codec_initializer.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
219219
video_codec.spatialLayers[i] = spatial_layers[i];
220220
}
221221

222+
// The top spatial layer dimensions may not be equal to the input
223+
// resolution because of the rounding or explicit configuration.
224+
// This difference must be propagated to the stream configuration.
225+
video_codec.width = spatial_layers.back().width;
226+
video_codec.height = spatial_layers.back().height;
227+
video_codec.simulcastStream[0].width = spatial_layers.back().width;
228+
video_codec.simulcastStream[0].height = spatial_layers.back().height;
229+
222230
// Update layering settings.
223231
video_codec.VP9()->numberOfSpatialLayers =
224232
static_cast<unsigned char>(spatial_layers.size());

video/video_stream_encoder.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,13 @@ void VideoStreamEncoder::ReconfigureEncoder() {
588588
RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
589589
}
590590

591+
if (encoder_config_.codec_type == kVideoCodecVP9) {
592+
// Spatial layers configuration might impose some parity restrictions,
593+
// thus some cropping might be needed.
594+
crop_width_ = last_frame_info_->width - codec.width;
595+
crop_height_ = last_frame_info_->height - codec.height;
596+
}
597+
591598
char log_stream_buf[4 * 1024];
592599
rtc::SimpleStringBuilder log_stream(log_stream_buf);
593600
log_stream << "ReconfigureEncoder:\n";

video/video_stream_encoder_unittest.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5917,4 +5917,34 @@ TEST_F(VideoStreamEncoderTest, AutomaticAnimationDetection) {
59175917
video_stream_encoder_->Stop();
59185918
}
59195919

5920+
TEST_F(VideoStreamEncoderTest, ConfiguresVp9SvcAtOddResolutions) {
5921+
const int kWidth = 720; // 540p adapted down.
5922+
const int kHeight = 405;
5923+
const int kNumFrames = 3;
5924+
// Works on screenshare mode.
5925+
ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1,
5926+
/*num_spatial_layers=*/2, /*screenshare=*/true);
5927+
5928+
video_source_.set_adaptation_enabled(true);
5929+
5930+
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5931+
DataRate::BitsPerSec(kTargetBitrateBps),
5932+
DataRate::BitsPerSec(kTargetBitrateBps),
5933+
DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5934+
5935+
VideoFrame frame = CreateFrame(1, kWidth, kHeight);
5936+
5937+
// Pass enough frames with the full update to trigger animation detection.
5938+
for (int i = 0; i < kNumFrames; ++i) {
5939+
int64_t timestamp_ms =
5940+
fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5941+
frame.set_ntp_time_ms(timestamp_ms);
5942+
frame.set_timestamp_us(timestamp_ms * 1000);
5943+
video_source_.IncomingCapturedFrame(frame);
5944+
WaitForEncodedFrame(timestamp_ms);
5945+
}
5946+
5947+
video_stream_encoder_->Stop();
5948+
}
5949+
59205950
} // namespace webrtc

0 commit comments

Comments
 (0)