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