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/chain_diff_calculator.h"
12 
13 #include "test/gmock.h"
14 #include "test/gtest.h"
15 
16 namespace webrtc {
17 namespace {
18 
19 using ::testing::ElementsAre;
20 using ::testing::SizeIs;
21 
TEST(ChainDiffCalculatorTest,SingleChain)22 TEST(ChainDiffCalculatorTest, SingleChain) {
23   // Simulate  a stream with 2 temporal layer where chain
24   // protects temporal layer 0.
25   ChainDiffCalculator calculator;
26   // Key frame.
27   calculator.Reset({true});
28   EXPECT_THAT(calculator.From(1, {true}), ElementsAre(0));
29   // T1 delta frame.
30   EXPECT_THAT(calculator.From(2, {false}), ElementsAre(1));
31   // T0 delta frame.
32   EXPECT_THAT(calculator.From(3, {true}), ElementsAre(2));
33 }
34 
TEST(ChainDiffCalculatorTest,TwoChainsFullSvc)35 TEST(ChainDiffCalculatorTest, TwoChainsFullSvc) {
36   // Simulate a full svc stream with 2 spatial and 2 temporal layers.
37   // chains are protecting temporal layers 0.
38   ChainDiffCalculator calculator;
39   // S0 Key frame.
40   calculator.Reset({true, true});
41   EXPECT_THAT(calculator.From(1, {true, true}), ElementsAre(0, 0));
42   // S1 Key frame.
43   EXPECT_THAT(calculator.From(2, {false, true}), ElementsAre(1, 1));
44   // S0T1 delta frame.
45   EXPECT_THAT(calculator.From(3, {false, false}), ElementsAre(2, 1));
46   // S1T1 delta frame.
47   EXPECT_THAT(calculator.From(4, {false, false}), ElementsAre(3, 2));
48   // S0T0 delta frame.
49   EXPECT_THAT(calculator.From(5, {true, true}), ElementsAre(4, 3));
50   // S1T0 delta frame.
51   EXPECT_THAT(calculator.From(6, {false, true}), ElementsAre(1, 1));
52 }
53 
TEST(ChainDiffCalculatorTest,TwoChainsKSvc)54 TEST(ChainDiffCalculatorTest, TwoChainsKSvc) {
55   // Simulate a k-svc stream with 2 spatial and 2 temporal layers.
56   // chains are protecting temporal layers 0.
57   ChainDiffCalculator calculator;
58   // S0 Key frame.
59   calculator.Reset({true, true});
60   EXPECT_THAT(calculator.From(1, {true, true}), ElementsAre(0, 0));
61   // S1 Key frame.
62   EXPECT_THAT(calculator.From(2, {false, true}), ElementsAre(1, 1));
63   // S0T1 delta frame.
64   EXPECT_THAT(calculator.From(3, {false, false}), ElementsAre(2, 1));
65   // S1T1 delta frame.
66   EXPECT_THAT(calculator.From(4, {false, false}), ElementsAre(3, 2));
67   // S0T0 delta frame.
68   EXPECT_THAT(calculator.From(5, {true, false}), ElementsAre(4, 3));
69   // S1T0 delta frame.
70   EXPECT_THAT(calculator.From(6, {false, true}), ElementsAre(1, 4));
71 }
72 
TEST(ChainDiffCalculatorTest,TwoChainsSimulcast)73 TEST(ChainDiffCalculatorTest, TwoChainsSimulcast) {
74   // Simulate a k-svc stream with 2 spatial and 2 temporal layers.
75   // chains are protecting temporal layers 0.
76   ChainDiffCalculator calculator;
77   // S0 Key frame.
78   calculator.Reset({true, false});
79   EXPECT_THAT(calculator.From(1, {true, false}), ElementsAre(0, 0));
80   // S1 Key frame.
81   calculator.Reset({false, true});
82   EXPECT_THAT(calculator.From(2, {false, true}), ElementsAre(1, 0));
83   // S0T1 delta frame.
84   EXPECT_THAT(calculator.From(3, {false, false}), ElementsAre(2, 1));
85   // S1T1 delta frame.
86   EXPECT_THAT(calculator.From(4, {false, false}), ElementsAre(3, 2));
87   // S0T0 delta frame.
88   EXPECT_THAT(calculator.From(5, {true, false}), ElementsAre(4, 3));
89   // S1T0 delta frame.
90   EXPECT_THAT(calculator.From(6, {false, true}), ElementsAre(1, 4));
91 }
92 
TEST(ChainDiffCalculatorTest,ResilentToAbsentChainConfig)93 TEST(ChainDiffCalculatorTest, ResilentToAbsentChainConfig) {
94   ChainDiffCalculator calculator;
95   // Key frame.
96   calculator.Reset({true, false});
97   EXPECT_THAT(calculator.From(1, {true, false}), ElementsAre(0, 0));
98   // Forgot to set chains. should still return 2 chain_diffs.
99   EXPECT_THAT(calculator.From(2, {}), ElementsAre(1, 0));
100   // chain diffs for next frame(s) are undefined, but still there should be
101   // correct number of them.
102   EXPECT_THAT(calculator.From(3, {true, false}), SizeIs(2));
103   EXPECT_THAT(calculator.From(4, {false, true}), SizeIs(2));
104   // Since previous two frames updated all the chains, can expect what
105   // chain_diffs would be.
106   EXPECT_THAT(calculator.From(5, {false, false}), ElementsAre(2, 1));
107 }
108 
TEST(ChainDiffCalculatorTest,ResilentToTooMainChains)109 TEST(ChainDiffCalculatorTest, ResilentToTooMainChains) {
110   ChainDiffCalculator calculator;
111   // Key frame.
112   calculator.Reset({true, false});
113   EXPECT_THAT(calculator.From(1, {true, false}), ElementsAre(0, 0));
114   // Set wrong number of chains. Expect number of chain_diffs is not changed.
115   EXPECT_THAT(calculator.From(2, {true, true, true}), ElementsAre(1, 0));
116   // chain diffs for next frame(s) are undefined, but still there should be
117   // correct number of them.
118   EXPECT_THAT(calculator.From(3, {true, false}), SizeIs(2));
119   EXPECT_THAT(calculator.From(4, {false, true}), SizeIs(2));
120   // Since previous two frames updated all the chains, can expect what
121   // chain_diffs would be.
122   EXPECT_THAT(calculator.From(5, {false, false}), ElementsAre(2, 1));
123 }
124 
125 }  // namespace
126 }  // namespace webrtc
127