Skip to content

Commit

Permalink
Merge to M84: [VP9 SVC] Round spatial layers dimensions to ensure int…
Browse files Browse the repository at this point in the history
…eger scaling factors are used

// Skipping CQ, because bots are broken. The same bot passed yesterday.
// Now two windows bots fail with "no executable found" or gn errors.
TBR=srpang@webrtc.org
(cherry picked from commit 09eb6e2)

No-Try: True
Bug: webrtc:11652
Change-Id: Id3642d607f62b72a567d521d9874b8588c2ce429
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176517
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Original-Commit-Position: refs/heads/master@{#31465}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176848
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/branch-heads/4147@{#7}
Cr-Branched-From: 2b7d969-refs/heads/master@{#31262}
  • Loading branch information
Ilya Nikolaevskiy authored and Commit Bot committed Jun 12, 2020
1 parent 1b649a8 commit 528f23d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
5 changes: 5 additions & 0 deletions modules/video_coding/codecs/vp9/svc_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
// First active layer must be configured.
num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1);

// Ensure top layer is even enough.
int required_divisiblity = 1 << num_spatial_layers;
input_width = input_width - input_width % required_divisiblity;
input_height = input_height - input_height % required_divisiblity;

for (size_t sl_idx = first_active_layer; sl_idx < num_spatial_layers;
++sl_idx) {
SpatialLayer spatial_layer = {0};
Expand Down
8 changes: 8 additions & 0 deletions modules/video_coding/video_codec_initializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,14 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
video_codec.spatialLayers[i] = spatial_layers[i];
}

// The top spatial layer dimensions may not be equal to the input
// resolution because of the rounding or explicit configuration.
// This difference must be propagated to the stream configuration.
video_codec.width = spatial_layers.back().width;
video_codec.height = spatial_layers.back().height;
video_codec.simulcastStream[0].width = spatial_layers.back().width;
video_codec.simulcastStream[0].height = spatial_layers.back().height;

// Update layering settings.
video_codec.VP9()->numberOfSpatialLayers =
static_cast<unsigned char>(spatial_layers.size());
Expand Down
7 changes: 7 additions & 0 deletions video/video_stream_encoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,13 @@ void VideoStreamEncoder::ReconfigureEncoder() {
RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
}

if (encoder_config_.codec_type == kVideoCodecVP9) {
// Spatial layers configuration might impose some parity restrictions,
// thus some cropping might be needed.
crop_width_ = last_frame_info_->width - codec.width;
crop_height_ = last_frame_info_->height - codec.height;
}

char log_stream_buf[4 * 1024];
rtc::SimpleStringBuilder log_stream(log_stream_buf);
log_stream << "ReconfigureEncoder:\n";
Expand Down
30 changes: 30 additions & 0 deletions video/video_stream_encoder_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5882,4 +5882,34 @@ TEST_F(VideoStreamEncoderTest, AutomaticAnimationDetection) {
video_stream_encoder_->Stop();
}

TEST_F(VideoStreamEncoderTest, ConfiguresVp9SvcAtOddResolutions) {
const int kWidth = 720; // 540p adapted down.
const int kHeight = 405;
const int kNumFrames = 3;
// Works on screenshare mode.
ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1,
/*num_spatial_layers=*/2, /*screenshare=*/true);

video_source_.set_adaptation_enabled(true);

video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
DataRate::BitsPerSec(kTargetBitrateBps),
DataRate::BitsPerSec(kTargetBitrateBps),
DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);

VideoFrame frame = CreateFrame(1, kWidth, kHeight);

// Pass enough frames with the full update to trigger animation detection.
for (int i = 0; i < kNumFrames; ++i) {
int64_t timestamp_ms =
fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
frame.set_ntp_time_ms(timestamp_ms);
frame.set_timestamp_us(timestamp_ms * 1000);
video_source_.IncomingCapturedFrame(frame);
WaitForEncodedFrame(timestamp_ms);
}

video_stream_encoder_->Stop();
}

} // namespace webrtc

0 comments on commit 528f23d

Please sign in to comment.