From b6103ff5f992a907ab000bea2528ca9075ed2e41 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 28 Sep 2020 12:32:41 +0200 Subject: [PATCH] Test scalability structures do not suggest disabled layers Bug: None Change-Id: I85cc9dabc90882f5d1afa41ddab9489660c8b032 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185501 Commit-Queue: Danil Chapovalov Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/master@{#32207} --- .../av1/scalability_structure_unittest.cc | 115 ++++++++++++++---- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/modules/video_coding/codecs/av1/scalability_structure_unittest.cc b/modules/video_coding/codecs/av1/scalability_structure_unittest.cc index 4d0e283fdd..835dc7ba40 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_unittest.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_unittest.cc @@ -52,29 +52,23 @@ struct SvcTestParam { class ScalabilityStructureTest : public TestWithParam { public: - std::vector GenerateAllFrames() { + std::vector GenerateAllFrames( + ScalableVideoController& structure_controller) { std::vector frames; - - FrameDependenciesCalculator frame_deps_calculator; - ChainDiffCalculator chain_diff_calculator; - std::unique_ptr structure_controller = - CreateScalabilityStructure(GetParam().name); - FrameDependencyStructure structure = - structure_controller->DependencyStructure(); for (int i = 0; i < GetParam().num_temporal_units; ++i) { for (auto& layer_frame : - structure_controller->NextFrameConfig(/*reset=*/false)) { - int64_t frame_id = static_cast(frames.size()); + structure_controller.NextFrameConfig(/*reset=*/false)) { + int64_t frame_id = ++frame_id_; bool is_keyframe = layer_frame.IsKeyframe(); absl::optional frame_info = - structure_controller->OnEncodeDone(std::move(layer_frame)); + structure_controller.OnEncodeDone(std::move(layer_frame)); EXPECT_TRUE(frame_info.has_value()); if (is_keyframe) { - chain_diff_calculator.Reset(frame_info->part_of_chain); + chain_diff_calculator_.Reset(frame_info->part_of_chain); } frame_info->chain_diffs = - chain_diff_calculator.From(frame_id, frame_info->part_of_chain); - for (int64_t base_frame_id : frame_deps_calculator.FromBuffersUsage( + chain_diff_calculator_.From(frame_id, frame_info->part_of_chain); + for (int64_t base_frame_id : frame_deps_calculator_.FromBuffersUsage( is_keyframe ? VideoFrameType::kVideoFrameKey : VideoFrameType::kVideoFrameDelta, frame_id, frame_info->encoder_buffers)) { @@ -88,6 +82,11 @@ class ScalabilityStructureTest : public TestWithParam { } return frames; } + + private: + FrameDependenciesCalculator frame_deps_calculator_; + ChainDiffCalculator chain_diff_calculator_; + int64_t frame_id_ = 0; }; TEST_P(ScalabilityStructureTest, @@ -153,9 +152,11 @@ TEST_P(ScalabilityStructureTest, TemplatesMatchNumberOfDecodeTargetsAndChains) { } TEST_P(ScalabilityStructureTest, FrameInfoMatchesFrameDependencyStructure) { - FrameDependencyStructure structure = - CreateScalabilityStructure(GetParam().name)->DependencyStructure(); - std::vector frame_infos = GenerateAllFrames(); + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + FrameDependencyStructure structure = svc_controller->DependencyStructure(); + std::vector frame_infos = + GenerateAllFrames(*svc_controller); for (size_t frame_id = 0; frame_id < frame_infos.size(); ++frame_id) { const auto& frame = frame_infos[frame_id]; EXPECT_GE(frame.spatial_id, 0) << " for frame " << frame_id; @@ -169,9 +170,11 @@ TEST_P(ScalabilityStructureTest, FrameInfoMatchesFrameDependencyStructure) { } TEST_P(ScalabilityStructureTest, ThereIsAPerfectTemplateForEachFrame) { - FrameDependencyStructure structure = - CreateScalabilityStructure(GetParam().name)->DependencyStructure(); - std::vector frame_infos = GenerateAllFrames(); + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + FrameDependencyStructure structure = svc_controller->DependencyStructure(); + std::vector frame_infos = + GenerateAllFrames(*svc_controller); for (size_t frame_id = 0; frame_id < frame_infos.size(); ++frame_id) { EXPECT_THAT(structure.templates, Contains(frame_infos[frame_id])) << " for frame " << frame_id; @@ -179,7 +182,10 @@ TEST_P(ScalabilityStructureTest, ThereIsAPerfectTemplateForEachFrame) { } TEST_P(ScalabilityStructureTest, FrameDependsOnSameOrLowerLayer) { - std::vector frame_infos = GenerateAllFrames(); + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + std::vector frame_infos = + GenerateAllFrames(*svc_controller); int64_t num_frames = frame_infos.size(); for (int64_t frame_id = 0; frame_id < num_frames; ++frame_id) { @@ -196,10 +202,12 @@ TEST_P(ScalabilityStructureTest, FrameDependsOnSameOrLowerLayer) { } TEST_P(ScalabilityStructureTest, NoFrameDependsOnDiscardableOrNotPresent) { - std::vector frame_infos = GenerateAllFrames(); + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + std::vector frame_infos = + GenerateAllFrames(*svc_controller); int64_t num_frames = frame_infos.size(); - FrameDependencyStructure structure = - CreateScalabilityStructure(GetParam().name)->DependencyStructure(); + FrameDependencyStructure structure = svc_controller->DependencyStructure(); for (int dt = 0; dt < structure.num_decode_targets; ++dt) { for (int64_t frame_id = 0; frame_id < num_frames; ++frame_id) { @@ -225,9 +233,11 @@ TEST_P(ScalabilityStructureTest, NoFrameDependsOnDiscardableOrNotPresent) { } TEST_P(ScalabilityStructureTest, NoFrameDependsThroughSwitchIndication) { - FrameDependencyStructure structure = - CreateScalabilityStructure(GetParam().name)->DependencyStructure(); - std::vector frame_infos = GenerateAllFrames(); + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + FrameDependencyStructure structure = svc_controller->DependencyStructure(); + std::vector frame_infos = + GenerateAllFrames(*svc_controller); int64_t num_frames = frame_infos.size(); std::vector> full_deps(num_frames); @@ -274,6 +284,47 @@ TEST_P(ScalabilityStructureTest, NoFrameDependsThroughSwitchIndication) { } } +// TODO(danilchap): Merge with ScalabilityStructureTest when SetRates +// implemented for all tested structures. +class ScalabilityStructureSetRatesTest : public ScalabilityStructureTest {}; + +TEST_P(ScalabilityStructureSetRatesTest, ProduceNoFrameForDisabledLayers) { + std::unique_ptr svc_controller = + CreateScalabilityStructure(GetParam().name); + ScalableVideoController::StreamLayersConfig structure = + svc_controller->StreamConfig(); + + VideoBitrateAllocation all_bitrates; + for (int sid = 0; sid < structure.num_spatial_layers; ++sid) { + for (int tid = 0; tid < structure.num_temporal_layers; ++tid) { + all_bitrates.SetBitrate(sid, tid, 100'000); + } + } + + svc_controller->OnRatesUpdated(all_bitrates); + std::vector frames = GenerateAllFrames(*svc_controller); + + for (int sid = 0; sid < structure.num_spatial_layers; ++sid) { + for (int tid = 0; tid < structure.num_temporal_layers; ++tid) { + // When all layers were enabled, expect there was a frame for each layer. + EXPECT_THAT(frames, + Contains(AllOf(Field(&GenericFrameInfo::spatial_id, sid), + Field(&GenericFrameInfo::temporal_id, tid)))) + << "For layer (" << sid << "," << tid << ")"; + // Restore bitrates for all layers before disabling single layer. + VideoBitrateAllocation bitrates = all_bitrates; + bitrates.SetBitrate(sid, tid, 0); + svc_controller->OnRatesUpdated(bitrates); + // With layer (sid, tid) disabled, expect no frames are produced for it. + EXPECT_THAT( + GenerateAllFrames(*svc_controller), + Not(Contains(AllOf(Field(&GenericFrameInfo::spatial_id, sid), + Field(&GenericFrameInfo::temporal_id, tid))))) + << "For layer (" << sid << "," << tid << ")"; + } + } +} + INSTANTIATE_TEST_SUITE_P( Svc, ScalabilityStructureTest, @@ -291,5 +342,15 @@ INSTANTIATE_TEST_SUITE_P( return info.param.name; }); +// TODO(danilchap): Merge with ScalabilityStructureTest when the functionality +// is implemented for all tested structures. +INSTANTIATE_TEST_SUITE_P(Svc, + ScalabilityStructureSetRatesTest, + Values(SvcTestParam{"L1T2", + /*num_temporal_units=*/4}), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); + } // namespace } // namespace webrtc