|  | /* | 
|  | *  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 |