From c5f152daa0853970ad38347062afc81e3229ff13 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Wed, 26 Sep 2018 13:28:50 +0200 Subject: [PATCH] Mark all low layer frames as references if inter-layer pred is enabled. Mark all low spatial layer frames as references (not just frames of active low spatial layers) if inter-layer prediction is enabled since these frames are indirect references of high spatial layer, which can later be enabled without key frame. Bug: webrtc:9782 Change-Id: Iffa5039fab2673a5582e7cdc9be4a36d9e8deb63 Reviewed-on: https://webrtc-review.googlesource.com/102063 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/master@{#24849} --- .../codecs/vp9/test/vp9_impl_unittest.cc | 25 +++++++++++++++++++ modules/video_coding/codecs/vp9/vp9_impl.cc | 9 ++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index 6d2274f854..1b8c2ce876 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -499,6 +499,31 @@ TEST_F(TestVp9Impl, } } +TEST_F(TestVp9Impl, + LowLayerMarkedAsRefIfHighLayerNotEncodedAndInterLayerPredIsEnabled) { + ConfigureSvc(3); + codec_settings_.VP9()->frameDroppingOn = false; + codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; + + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, + 0 /* max payload size (unused) */)); + + VideoBitrateAllocation bitrate_allocation; + bitrate_allocation.SetBitrate( + 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->Encode(*NextInputFrame(), nullptr, nullptr)); + EncodedImage encoded_frame; + CodecSpecificInfo codec_info; + ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_info)); + EXPECT_TRUE(codec_info.codecSpecific.VP9.ss_data_available); + EXPECT_FALSE(codec_info.codecSpecific.VP9.non_ref_for_inter_layer_pred); +} + TEST_F(TestVp9Impl, ScalabilityStructureIsAvailableInFlexibleMode) { codec_settings_.VP9()->flexibleMode = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index e83a785cbe..998c65f9ba 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -856,10 +856,13 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, vp9_info->inter_layer_predicted = first_frame_in_picture ? false : is_inter_layer_pred_allowed; - const bool is_last_layer = - (layer_id.spatial_layer_id + 1 == num_active_spatial_layers_); + // Mark all low spatial layer frames as references (not just frames of + // active low spatial layers) if inter-layer prediction is enabled since + // these frames are indirect references of high spatial layer, which can + // later be enabled without key frame. vp9_info->non_ref_for_inter_layer_pred = - is_last_layer ? true : !is_inter_layer_pred_allowed; + !is_inter_layer_pred_allowed || + layer_id.spatial_layer_id + 1 == num_spatial_layers_; // Always populate this, so that the packetizer can properly set the marker // bit.