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