1 /*
2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/frame_dependencies_calculator.h"
12
13 #include "api/video/video_frame_type.h"
14 #include "common_video/generic_frame_descriptor/generic_frame_info.h"
15 #include "test/gmock.h"
16 #include "test/gtest.h"
17
18 namespace webrtc {
19 namespace {
20
21 using ::testing::ElementsAre;
22 using ::testing::IsEmpty;
23 using ::testing::UnorderedElementsAre;
24
25 constexpr VideoFrameType kVideoFrameKey = VideoFrameType::kVideoFrameKey;
26 constexpr VideoFrameType kVideoFrameDelta = VideoFrameType::kVideoFrameDelta;
27
ReferenceAndUpdate(int id)28 constexpr CodecBufferUsage ReferenceAndUpdate(int id) {
29 return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/true);
30 }
Reference(int id)31 constexpr CodecBufferUsage Reference(int id) {
32 return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/false);
33 }
Update(int id)34 constexpr CodecBufferUsage Update(int id) {
35 return CodecBufferUsage(id, /*referenced=*/false, /*updated=*/true);
36 }
37
TEST(FrameDependenciesCalculatorTest,SingleLayer)38 TEST(FrameDependenciesCalculatorTest, SingleLayer) {
39 CodecBufferUsage pattern[] = {ReferenceAndUpdate(0)};
40 FrameDependenciesCalculator calculator;
41
42 EXPECT_THAT(
43 calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern),
44 IsEmpty());
45 EXPECT_THAT(
46 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern),
47 ElementsAre(1));
48 EXPECT_THAT(
49 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern),
50 ElementsAre(3));
51 }
52
TEST(FrameDependenciesCalculatorTest,TwoTemporalLayers)53 TEST(FrameDependenciesCalculatorTest, TwoTemporalLayers) {
54 // Shortened 4-frame pattern:
55 // T1: 2---4 6---8 ...
56 // / / / /
57 // T0: 1---3---5---7 ...
58 CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
59 CodecBufferUsage pattern1[] = {Reference(0), Update(1)};
60 CodecBufferUsage pattern2[] = {ReferenceAndUpdate(0)};
61 CodecBufferUsage pattern3[] = {Reference(0), Reference(1)};
62 FrameDependenciesCalculator calculator;
63
64 EXPECT_THAT(
65 calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
66 IsEmpty());
67 EXPECT_THAT(
68 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/2, pattern1),
69 ElementsAre(1));
70 EXPECT_THAT(
71 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern2),
72 ElementsAre(1));
73 EXPECT_THAT(
74 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern3),
75 UnorderedElementsAre(2, 3));
76 EXPECT_THAT(
77 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
78 ElementsAre(3));
79 EXPECT_THAT(
80 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
81 ElementsAre(5));
82 EXPECT_THAT(
83 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/7, pattern2),
84 ElementsAre(5));
85 EXPECT_THAT(
86 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/8, pattern3),
87 UnorderedElementsAre(6, 7));
88 }
89
TEST(FrameDependenciesCalculatorTest,ThreeTemporalLayers4FramePattern)90 TEST(FrameDependenciesCalculatorTest, ThreeTemporalLayers4FramePattern) {
91 // T2: 2---4 6---8 ...
92 // / / / /
93 // T1: | 3 | 7 ...
94 // /_/ /_/
95 // T0: 1-------5----- ...
96 CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
97 CodecBufferUsage pattern1[] = {Reference(0), Update(2)};
98 CodecBufferUsage pattern2[] = {Reference(0), Update(1)};
99 CodecBufferUsage pattern3[] = {Reference(0), Reference(1), Reference(2)};
100 FrameDependenciesCalculator calculator;
101
102 EXPECT_THAT(
103 calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
104 IsEmpty());
105 EXPECT_THAT(
106 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/2, pattern1),
107 ElementsAre(1));
108 EXPECT_THAT(
109 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern2),
110 ElementsAre(1));
111 // Note that frame#4 references buffer#0 that is updated by frame#1,
112 // yet there is no direct dependency from frame#4 to frame#1.
113 EXPECT_THAT(
114 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern3),
115 UnorderedElementsAre(2, 3));
116 EXPECT_THAT(
117 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
118 ElementsAre(1));
119 EXPECT_THAT(
120 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
121 ElementsAre(5));
122 }
123
TEST(FrameDependenciesCalculatorTest,SimulcastWith2Layers)124 TEST(FrameDependenciesCalculatorTest, SimulcastWith2Layers) {
125 // S1: 2---4---6- ...
126 //
127 // S0: 1---3---5- ...
128 CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
129 CodecBufferUsage pattern1[] = {ReferenceAndUpdate(1)};
130 FrameDependenciesCalculator calculator;
131
132 EXPECT_THAT(
133 calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/1, pattern0),
134 IsEmpty());
135 EXPECT_THAT(
136 calculator.FromBuffersUsage(kVideoFrameKey, /*frame_id=*/2, pattern1),
137 IsEmpty());
138 EXPECT_THAT(
139 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/3, pattern0),
140 ElementsAre(1));
141 EXPECT_THAT(
142 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/4, pattern1),
143 ElementsAre(2));
144 EXPECT_THAT(
145 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/5, pattern0),
146 ElementsAre(3));
147 EXPECT_THAT(
148 calculator.FromBuffersUsage(kVideoFrameDelta, /*frame_id=*/6, pattern1),
149 ElementsAre(4));
150 }
151
152 } // namespace
153 } // namespace webrtc
154