| /* | 
 |  *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include "modules/video_coding/frame_dependencies_calculator.h" | 
 |  | 
 | #include "common_video/generic_frame_descriptor/generic_frame_info.h" | 
 | #include "test/gmock.h" | 
 | #include "test/gtest.h" | 
 |  | 
 | namespace webrtc { | 
 | namespace { | 
 |  | 
 | using ::testing::ElementsAre; | 
 | using ::testing::IsEmpty; | 
 | using ::testing::UnorderedElementsAre; | 
 |  | 
 | constexpr CodecBufferUsage ReferenceAndUpdate(int id) { | 
 |   return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/true); | 
 | } | 
 | constexpr CodecBufferUsage Reference(int id) { | 
 |   return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/false); | 
 | } | 
 | constexpr CodecBufferUsage Update(int id) { | 
 |   return CodecBufferUsage(id, /*referenced=*/false, /*updated=*/true); | 
 | } | 
 |  | 
 | TEST(FrameDependenciesCalculatorTest, SingleLayer) { | 
 |   CodecBufferUsage pattern[] = {ReferenceAndUpdate(0)}; | 
 |   FrameDependenciesCalculator calculator; | 
 |  | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern), IsEmpty()); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern), | 
 |               ElementsAre(3)); | 
 | } | 
 |  | 
 | TEST(FrameDependenciesCalculatorTest, TwoTemporalLayers) { | 
 |   // Shortened 4-frame pattern: | 
 |   // T1:  2---4   6---8 ... | 
 |   //      /   /   /   / | 
 |   // T0: 1---3---5---7 ... | 
 |   CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)}; | 
 |   CodecBufferUsage pattern1[] = {Reference(0), Update(1)}; | 
 |   CodecBufferUsage pattern2[] = {ReferenceAndUpdate(0)}; | 
 |   CodecBufferUsage pattern3[] = {Reference(0), Reference(1)}; | 
 |   FrameDependenciesCalculator calculator; | 
 |  | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty()); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern2), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern3), | 
 |               UnorderedElementsAre(2, 3)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0), | 
 |               ElementsAre(3)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1), | 
 |               ElementsAre(5)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/7, pattern2), | 
 |               ElementsAre(5)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/8, pattern3), | 
 |               UnorderedElementsAre(6, 7)); | 
 | } | 
 |  | 
 | TEST(FrameDependenciesCalculatorTest, ThreeTemporalLayers4FramePattern) { | 
 |   // T2:   2---4   6---8 ... | 
 |   //      /   /   /   / | 
 |   // T1:  |  3    |  7   ... | 
 |   //      /_/     /_/ | 
 |   // T0: 1-------5-----  ... | 
 |   CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)}; | 
 |   CodecBufferUsage pattern1[] = {Reference(0), Update(2)}; | 
 |   CodecBufferUsage pattern2[] = {Reference(0), Update(1)}; | 
 |   CodecBufferUsage pattern3[] = {Reference(0), Reference(1), Reference(2)}; | 
 |   FrameDependenciesCalculator calculator; | 
 |  | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty()); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern2), | 
 |               ElementsAre(1)); | 
 |   // Note that frame#4 references buffer#0 that is updated by frame#1, | 
 |   // yet there is no direct dependency from frame#4 to frame#1. | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern3), | 
 |               UnorderedElementsAre(2, 3)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1), | 
 |               ElementsAre(5)); | 
 | } | 
 |  | 
 | TEST(FrameDependenciesCalculatorTest, SimulcastWith2Layers) { | 
 |   // S1: 2---4---6-  ... | 
 |   // | 
 |   // S0: 1---3---5-  ... | 
 |   CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)}; | 
 |   CodecBufferUsage pattern1[] = {ReferenceAndUpdate(1)}; | 
 |   FrameDependenciesCalculator calculator; | 
 |  | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty()); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1), IsEmpty()); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern0), | 
 |               ElementsAre(1)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern1), | 
 |               ElementsAre(2)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0), | 
 |               ElementsAre(3)); | 
 |   EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1), | 
 |               ElementsAre(4)); | 
 | } | 
 |  | 
 | }  // namespace | 
 | }  // namespace webrtc |