Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc

Issue 3003823003: Fix FrameConfigs used for VP8 with four temporal layers. (Closed)
Patch Set: Fixed int to uint cast in test Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" 11 #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
12 #include "vpx/vp8cx.h" 12 #include "vpx/vp8cx.h"
13 #include "vpx/vpx_encoder.h" 13 #include "vpx/vpx_encoder.h"
14 #include "webrtc/modules/video_coding/codecs/vp8/vp8_impl.h" 14 #include "webrtc/modules/video_coding/codecs/vp8/vp8_impl.h"
15 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 15 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
16 #include "webrtc/test/field_trial.h"
16 #include "webrtc/test/gtest.h" 17 #include "webrtc/test/gtest.h"
17 18
18 namespace webrtc { 19 namespace webrtc {
20 namespace test {
19 21
20 enum { 22 enum {
21 kTemporalUpdateLast = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 23 kTemporalUpdateLast = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
22 VP8_EFLAG_NO_REF_GF | 24 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF,
23 VP8_EFLAG_NO_REF_ARF,
24 kTemporalUpdateGoldenWithoutDependency = 25 kTemporalUpdateGoldenWithoutDependency =
25 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | 26 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
26 VP8_EFLAG_NO_UPD_LAST, 27 VP8_EFLAG_NO_UPD_LAST,
27 kTemporalUpdateGolden = 28 kTemporalUpdateGolden =
28 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST, 29 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
29 kTemporalUpdateAltrefWithoutDependency = 30 kTemporalUpdateAltrefWithoutDependency =
30 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | 31 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
31 VP8_EFLAG_NO_UPD_LAST, 32 VP8_EFLAG_NO_UPD_LAST,
32 kTemporalUpdateAltref = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST, 33 kTemporalUpdateAltref = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST,
33 kTemporalUpdateNone = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | 34 kTemporalUpdateNone = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
34 VP8_EFLAG_NO_UPD_LAST | 35 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY,
35 VP8_EFLAG_NO_UPD_ENTROPY, 36 kTemporalUpdateNoneNoRefAltRef =
36 kTemporalUpdateNoneNoRefAltRef = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | 37 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
37 VP8_EFLAG_NO_UPD_ARF | 38 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY,
38 VP8_EFLAG_NO_UPD_LAST | 39 kTemporalUpdateNoneNoRefGolden =
39 VP8_EFLAG_NO_UPD_ENTROPY, 40 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
40 kTemporalUpdateNoneNoRefGolden = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | 41 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY,
41 VP8_EFLAG_NO_UPD_ARF | 42 kTemporalUpdateNoneNoRefGoldenAltRef =
42 VP8_EFLAG_NO_UPD_LAST | 43 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_REF_ARF |
43 VP8_EFLAG_NO_UPD_ENTROPY, 44 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY,
44 kTemporalUpdateGoldenWithoutDependencyRefAltRef = 45 kTemporalUpdateGoldenWithoutDependencyRefAltRef =
45 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST, 46 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
46 kTemporalUpdateGoldenRefAltRef = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST, 47 kTemporalUpdateGoldenRefAltRef = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
47 kTemporalUpdateLastRefAltRef = 48 kTemporalUpdateLastRefAltRef =
48 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF, 49 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF,
49 kTemporalUpdateLastAndGoldenRefAltRef = 50 kTemporalUpdateLastAndGoldenRefAltRef =
50 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF, 51 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF,
51 }; 52 };
52 53
53 TEST(TemporalLayersTest, 2Layers) { 54 TEST(TemporalLayersTest, 2Layers) {
54 DefaultTemporalLayers tl(2, 0); 55 DefaultTemporalLayers tl(2, 0);
55 vpx_codec_enc_cfg_t cfg; 56 vpx_codec_enc_cfg_t cfg;
56 CodecSpecificInfoVP8 vp8_info; 57 CodecSpecificInfoVP8 vp8_info;
57 tl.OnRatesUpdated(500, 500, 30); 58 tl.OnRatesUpdated(500, 500, 30);
58 tl.UpdateConfiguration(&cfg); 59 tl.UpdateConfiguration(&cfg);
59 60
60 int expected_flags[16] = { 61 int expected_flags[16] = {
61 kTemporalUpdateLastAndGoldenRefAltRef, 62 kTemporalUpdateLastRefAltRef,
62 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 63 kTemporalUpdateGoldenWithoutDependencyRefAltRef,
63 kTemporalUpdateLastRefAltRef, 64 kTemporalUpdateLastRefAltRef,
64 kTemporalUpdateGoldenRefAltRef, 65 kTemporalUpdateGoldenRefAltRef,
65 kTemporalUpdateLastRefAltRef, 66 kTemporalUpdateLastRefAltRef,
66 kTemporalUpdateGoldenRefAltRef, 67 kTemporalUpdateGoldenRefAltRef,
67 kTemporalUpdateLastRefAltRef, 68 kTemporalUpdateLastRefAltRef,
68 kTemporalUpdateNone, 69 kTemporalUpdateNone,
69 kTemporalUpdateLastAndGoldenRefAltRef, 70 kTemporalUpdateLastRefAltRef,
70 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 71 kTemporalUpdateGoldenWithoutDependencyRefAltRef,
71 kTemporalUpdateLastRefAltRef, 72 kTemporalUpdateLastRefAltRef,
72 kTemporalUpdateGoldenRefAltRef, 73 kTemporalUpdateGoldenRefAltRef,
73 kTemporalUpdateLastRefAltRef, 74 kTemporalUpdateLastRefAltRef,
74 kTemporalUpdateGoldenRefAltRef, 75 kTemporalUpdateGoldenRefAltRef,
75 kTemporalUpdateLastRefAltRef, 76 kTemporalUpdateLastRefAltRef,
76 kTemporalUpdateNone, 77 kTemporalUpdateNone,
77 }; 78 };
78 int expected_temporal_idx[16] = {0, 1, 0, 1, 0, 1, 0, 1, 79 int expected_temporal_idx[16] = {0, 1, 0, 1, 0, 1, 0, 1,
79 0, 1, 0, 1, 0, 1, 0, 1}; 80 0, 1, 0, 1, 0, 1, 0, 1};
80 81
81 bool expected_layer_sync[16] = {false, true, false, false, false, false, 82 bool expected_layer_sync[16] = {false, true, false, false, false, false,
82 false, false, false, true, false, false, 83 false, false, false, true, false, false,
83 false, false, false, false}; 84 false, false, false, false};
84 85
85 uint32_t timestamp = 0; 86 uint32_t timestamp = 0;
86 for (int i = 0; i < 16; ++i) { 87 for (int i = 0; i < 16; ++i) {
87 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp); 88 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
88 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)); 89 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)) << i;
89 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0); 90 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0);
90 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 91 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
91 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx); 92 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
92 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id); 93 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
93 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 94 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
94 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync); 95 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
95 timestamp += 3000; 96 timestamp += 3000;
96 } 97 }
97 } 98 }
98 99
99 TEST(TemporalLayersTest, 3Layers) { 100 TEST(TemporalLayersTest, 3Layers) {
100 DefaultTemporalLayers tl(3, 0); 101 DefaultTemporalLayers tl(3, 0);
101 vpx_codec_enc_cfg_t cfg; 102 vpx_codec_enc_cfg_t cfg;
102 CodecSpecificInfoVP8 vp8_info; 103 CodecSpecificInfoVP8 vp8_info;
103 tl.OnRatesUpdated(500, 500, 30); 104 tl.OnRatesUpdated(500, 500, 30);
104 tl.UpdateConfiguration(&cfg); 105 tl.UpdateConfiguration(&cfg);
105 106
106 int expected_flags[16] = { 107 int expected_flags[16] = {
107 kTemporalUpdateLastAndGoldenRefAltRef, 108 kTemporalUpdateLastRefAltRef,
108 kTemporalUpdateNoneNoRefGolden, 109 kTemporalUpdateNoneNoRefGolden,
109 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 110 kTemporalUpdateGoldenWithoutDependencyRefAltRef,
110 kTemporalUpdateNone, 111 kTemporalUpdateNone,
111 kTemporalUpdateLastRefAltRef, 112 kTemporalUpdateLastRefAltRef,
112 kTemporalUpdateNone, 113 kTemporalUpdateNone,
113 kTemporalUpdateGoldenRefAltRef, 114 kTemporalUpdateGoldenRefAltRef,
114 kTemporalUpdateNone, 115 kTemporalUpdateNone,
115 kTemporalUpdateLastAndGoldenRefAltRef, 116 kTemporalUpdateLastRefAltRef,
116 kTemporalUpdateNoneNoRefGolden, 117 kTemporalUpdateNoneNoRefGolden,
117 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 118 kTemporalUpdateGoldenWithoutDependencyRefAltRef,
118 kTemporalUpdateNone, 119 kTemporalUpdateNone,
119 kTemporalUpdateLastRefAltRef, 120 kTemporalUpdateLastRefAltRef,
120 kTemporalUpdateNone, 121 kTemporalUpdateNone,
121 kTemporalUpdateGoldenRefAltRef, 122 kTemporalUpdateGoldenRefAltRef,
122 kTemporalUpdateNone, 123 kTemporalUpdateNone,
123 }; 124 };
124 int expected_temporal_idx[16] = {0, 2, 1, 2, 0, 2, 1, 2, 125 int expected_temporal_idx[16] = {0, 2, 1, 2, 0, 2, 1, 2,
125 0, 2, 1, 2, 0, 2, 1, 2}; 126 0, 2, 1, 2, 0, 2, 1, 2};
126 127
127 bool expected_layer_sync[16] = {false, true, true, false, false, false, 128 bool expected_layer_sync[16] = {false, true, true, false, false, false,
128 false, false, false, true, true, false, 129 false, false, false, true, true, false,
129 false, false, false, false}; 130 false, false, false, false};
130 131
131 unsigned int timestamp = 0; 132 unsigned int timestamp = 0;
132 for (int i = 0; i < 16; ++i) { 133 for (int i = 0; i < 16; ++i) {
133 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp); 134 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
134 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)); 135 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)) << i;
135 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0); 136 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0);
136 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 137 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
137 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx); 138 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
139 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
140 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
141 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
142 timestamp += 3000;
143 }
144 }
145
146 TEST(TemporalLayersTest, Alternative3Layers) {
147 ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
148 DefaultTemporalLayers tl(3, 0);
149 vpx_codec_enc_cfg_t cfg;
150 CodecSpecificInfoVP8 vp8_info;
151 tl.OnRatesUpdated(500, 500, 30);
152 tl.UpdateConfiguration(&cfg);
153
154 int expected_flags[8] = {kTemporalUpdateLast,
155 kTemporalUpdateAltrefWithoutDependency,
156 kTemporalUpdateGoldenWithoutDependency,
157 kTemporalUpdateNone,
158 kTemporalUpdateLast,
159 kTemporalUpdateAltrefWithoutDependency,
160 kTemporalUpdateGoldenWithoutDependency,
161 kTemporalUpdateNone};
162 int expected_temporal_idx[8] = {0, 2, 1, 2, 0, 2, 1, 2};
163
164 bool expected_layer_sync[8] = {false, true, true, false,
165 false, true, true, false};
166
167 unsigned int timestamp = 0;
168 for (int i = 0; i < 8; ++i) {
169 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
170 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)) << i;
171 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0);
172 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
173 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
138 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id); 174 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
139 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 175 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
140 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync); 176 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
141 timestamp += 3000; 177 timestamp += 3000;
142 } 178 }
143 } 179 }
144 180
145 TEST(TemporalLayersTest, 4Layers) { 181 TEST(TemporalLayersTest, 4Layers) {
146 DefaultTemporalLayers tl(4, 0); 182 DefaultTemporalLayers tl(4, 0);
147 vpx_codec_enc_cfg_t cfg; 183 vpx_codec_enc_cfg_t cfg;
148 CodecSpecificInfoVP8 vp8_info; 184 CodecSpecificInfoVP8 vp8_info;
149 tl.OnRatesUpdated(500, 500, 30); 185 tl.OnRatesUpdated(500, 500, 30);
150 tl.UpdateConfiguration(&cfg); 186 tl.UpdateConfiguration(&cfg);
151 int expected_flags[16] = { 187 int expected_flags[16] = {
152 kTemporalUpdateLast, 188 kTemporalUpdateLast,
153 kTemporalUpdateNone, 189 kTemporalUpdateNoneNoRefGoldenAltRef,
154 kTemporalUpdateAltrefWithoutDependency, 190 kTemporalUpdateAltrefWithoutDependency,
155 kTemporalUpdateNone, 191 kTemporalUpdateNoneNoRefGolden,
156 kTemporalUpdateGoldenWithoutDependency, 192 kTemporalUpdateGoldenWithoutDependency,
157 kTemporalUpdateNone, 193 kTemporalUpdateNone,
158 kTemporalUpdateAltref, 194 kTemporalUpdateAltref,
159 kTemporalUpdateNone, 195 kTemporalUpdateNone,
160 kTemporalUpdateLast, 196 kTemporalUpdateLast,
161 kTemporalUpdateNone, 197 kTemporalUpdateNone,
162 kTemporalUpdateAltref, 198 kTemporalUpdateAltref,
163 kTemporalUpdateNone, 199 kTemporalUpdateNone,
164 kTemporalUpdateGolden, 200 kTemporalUpdateGolden,
165 kTemporalUpdateNone, 201 kTemporalUpdateNone,
166 kTemporalUpdateAltref, 202 kTemporalUpdateAltref,
167 kTemporalUpdateNone, 203 kTemporalUpdateNone,
168 }; 204 };
169 int expected_temporal_idx[16] = {0, 3, 2, 3, 1, 3, 2, 3, 205 int expected_temporal_idx[16] = {0, 3, 2, 3, 1, 3, 2, 3,
170 0, 3, 2, 3, 1, 3, 2, 3}; 206 0, 3, 2, 3, 1, 3, 2, 3};
171 207
172 bool expected_layer_sync[16] = {false, true, true, true, true, true, 208 bool expected_layer_sync[16] = {false, true, true, false, true, false,
173 false, true, false, true, false, true, 209 false, false, false, false, false, false,
174 false, true, false, true}; 210 false, false, false, false};
175 211
176 uint32_t timestamp = 0; 212 uint32_t timestamp = 0;
177 for (int i = 0; i < 16; ++i) { 213 for (int i = 0; i < 16; ++i) {
178 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp); 214 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
179 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)); 215 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)) << i;
180 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0); 216 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0);
181 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 217 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
182 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx); 218 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
183 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id); 219 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
184 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 220 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
185 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync); 221 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
186 timestamp += 3000; 222 timestamp += 3000;
187 } 223 }
188 } 224 }
189 225
190 TEST(TemporalLayersTest, KeyFrame) { 226 TEST(TemporalLayersTest, KeyFrame) {
191 DefaultTemporalLayers tl(3, 0); 227 DefaultTemporalLayers tl(3, 0);
192 vpx_codec_enc_cfg_t cfg; 228 vpx_codec_enc_cfg_t cfg;
193 CodecSpecificInfoVP8 vp8_info; 229 CodecSpecificInfoVP8 vp8_info;
194 tl.OnRatesUpdated(500, 500, 30); 230 tl.OnRatesUpdated(500, 500, 30);
195 tl.UpdateConfiguration(&cfg); 231 tl.UpdateConfiguration(&cfg);
196 232
197 int expected_flags[8] = { 233 int expected_flags[8] = {
198 kTemporalUpdateLastAndGoldenRefAltRef, 234 kTemporalUpdateLastRefAltRef,
199 kTemporalUpdateNoneNoRefGolden, 235 kTemporalUpdateNoneNoRefGolden,
200 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 236 kTemporalUpdateGoldenWithoutDependencyRefAltRef,
201 kTemporalUpdateNone, 237 kTemporalUpdateNone,
202 kTemporalUpdateLastRefAltRef, 238 kTemporalUpdateLastRefAltRef,
203 kTemporalUpdateNone, 239 kTemporalUpdateNone,
204 kTemporalUpdateGoldenRefAltRef, 240 kTemporalUpdateGoldenRefAltRef,
205 kTemporalUpdateNone, 241 kTemporalUpdateNone,
206 }; 242 };
207 int expected_temporal_idx[8] = {0, 2, 1, 2, 0, 2, 1, 2}; 243 int expected_temporal_idx[8] = {0, 2, 1, 2, 0, 2, 1, 2};
208 bool expected_layer_sync[8] = {false, true, true, false, 244 bool expected_layer_sync[8] = {false, true, true, false,
209 false, false, false, false}; 245 false, false, false, false};
210 246
211 uint32_t timestamp = 0; 247 uint32_t timestamp = 0;
212 for (int i = 0; i < 7; ++i) { 248 for (int i = 0; i < 7; ++i) {
213 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp); 249 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
214 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)); 250 EXPECT_EQ(expected_flags[i], VP8EncoderImpl::EncodeFlags(tl_config)) << i;
215 tl.PopulateCodecSpecific(true, tl_config, &vp8_info, 0); 251 tl.PopulateCodecSpecific(true, tl_config, &vp8_info, 0);
216 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx); 252 EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
217 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id); 253 EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
218 EXPECT_EQ(0, vp8_info.temporalIdx) 254 EXPECT_EQ(0, vp8_info.temporalIdx)
219 << "Key frame should always be packetized as layer 0"; 255 << "Key frame should always be packetized as layer 0";
220 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync); 256 EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
221 EXPECT_TRUE(vp8_info.layerSync) << "Key frame should be marked layer sync."; 257 EXPECT_TRUE(vp8_info.layerSync) << "Key frame should be marked layer sync.";
222 timestamp += 3000; 258 timestamp += 3000;
223 } 259 }
224 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp); 260 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
225 EXPECT_EQ(expected_flags[7], VP8EncoderImpl::EncodeFlags(tl_config)); 261 EXPECT_EQ(expected_flags[7], VP8EncoderImpl::EncodeFlags(tl_config));
226 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0); 262 tl.PopulateCodecSpecific(false, tl_config, &vp8_info, 0);
227 EXPECT_NE(0, vp8_info.temporalIdx) 263 EXPECT_NE(0, vp8_info.temporalIdx)
228 << "To test something useful, this frame should not use layer 0."; 264 << "To test something useful, this frame should not use layer 0.";
229 EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx) 265 EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx)
230 << "Non-keyframe, should use frame temporal index."; 266 << "Non-keyframe, should use frame temporal index.";
231 EXPECT_EQ(expected_temporal_idx[7], tl_config.packetizer_temporal_idx); 267 EXPECT_EQ(expected_temporal_idx[7], tl_config.packetizer_temporal_idx);
232 EXPECT_EQ(expected_temporal_idx[7], tl_config.encoder_layer_id); 268 EXPECT_EQ(expected_temporal_idx[7], tl_config.encoder_layer_id);
233 EXPECT_FALSE(tl_config.layer_sync); 269 EXPECT_FALSE(tl_config.layer_sync);
234 EXPECT_TRUE(vp8_info.layerSync) << "Frame after keyframe should always be " 270 EXPECT_TRUE(vp8_info.layerSync) << "Frame after keyframe should always be "
235 "marked layer sync since it only depends " 271 "marked layer sync since it only depends "
236 "on the base layer."; 272 "on the base layer.";
237 } 273 }
274
275 class TemporalLayersReferenceTest : public ::testing::TestWithParam<int> {
276 public:
277 TemporalLayersReferenceTest()
278 : timestamp_(1),
279 last_sync_timestamp_(timestamp_),
280 tl0_reference_(nullptr) {}
281 virtual ~TemporalLayersReferenceTest() {}
282
283 protected:
284 static const int kMaxPatternLength = 32;
285
286 struct BufferState {
287 BufferState() : BufferState(-1, 0, false) {}
288 BufferState(int temporal_idx, uint32_t timestamp, bool sync)
289 : temporal_idx(temporal_idx), timestamp(timestamp), sync(sync) {}
290 int temporal_idx;
291 uint32_t timestamp;
292 bool sync;
293 };
294
295 bool UpdateSyncRefState(const TemporalLayers::BufferFlags& flags,
296 BufferState* buffer_state) {
297 if (flags & TemporalLayers::kReference) {
298 if (buffer_state->temporal_idx == -1)
299 return true; // References key-frame.
300 if (buffer_state->temporal_idx == 0) {
301 // No more than one reference to TL0 frame.
302 EXPECT_EQ(nullptr, tl0_reference_);
303 tl0_reference_ = buffer_state;
304 return true;
305 }
306 return false; // References higher layer.
307 }
308 return true; // No reference, does not affect sync frame status.
309 }
310
311 void ValidateReference(const TemporalLayers::BufferFlags& flags,
312 const BufferState& buffer_state,
313 int temporal_layer) {
314 if (flags & TemporalLayers::kReference) {
315 if (temporal_layer > 0 && buffer_state.timestamp > 0) {
316 // Check that high layer reference does not go past last sync frame.
317 EXPECT_GE(buffer_state.timestamp, last_sync_timestamp_);
318 }
319 // No reference to buffer in higher layer.
320 EXPECT_LE(buffer_state.temporal_idx, temporal_layer);
321 }
322 }
323
324 uint32_t timestamp_ = 1;
325 uint32_t last_sync_timestamp_ = timestamp_;
326 BufferState* tl0_reference_;
327
328 BufferState last_state;
329 BufferState golden_state;
330 BufferState altref_state;
331 };
332
333 INSTANTIATE_TEST_CASE_P(DefaultTemporalLayersTest,
334 TemporalLayersReferenceTest,
335 ::testing::Range(1, kMaxTemporalStreams + 1));
336
337 TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) {
338 const int num_layers = GetParam();
339 DefaultTemporalLayers tl(num_layers, 0);
340 vpx_codec_enc_cfg_t cfg;
341 tl.OnRatesUpdated(500, 500, 30);
342 tl.UpdateConfiguration(&cfg);
343
344 // Run through the pattern and store the frame dependencies, plus keep track
345 // of the buffer state; which buffers references which temporal layers (if
346 // (any). If a given buffer is never updated, it is legal to reference it
347 // even for sync frames. In order to be general, don't assume TL0 always
348 // updates |last|.
349 std::vector<TemporalLayers::FrameConfig> tl_configs(kMaxPatternLength);
350 for (int i = 0; i < kMaxPatternLength; ++i) {
351 TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp_++);
352 EXPECT_FALSE(tl_config.drop_frame);
353 tl_configs.push_back(tl_config);
354 int temporal_idx = tl_config.encoder_layer_id;
355 // For the default layers, always keep encoder and rtp layers in sync.
356 EXPECT_EQ(tl_config.packetizer_temporal_idx, temporal_idx);
357
358 // Determine if this frame is in a higher layer but references only TL0
359 // or untouched buffers, if so verify it is marked as a layer sync.
360 bool is_sync_frame = true;
361 tl0_reference_ = nullptr;
362 if (temporal_idx <= 0) {
363 is_sync_frame = false; // TL0 by definition not a sync frame.
364 } else if (!UpdateSyncRefState(tl_config.last_buffer_flags, &last_state)) {
365 is_sync_frame = false;
366 } else if (!UpdateSyncRefState(tl_config.golden_buffer_flags,
367 &golden_state)) {
368 is_sync_frame = false;
369 } else if (!UpdateSyncRefState(tl_config.arf_buffer_flags, &altref_state)) {
370 is_sync_frame = false;
371 }
372 if (is_sync_frame) {
373 // Cache timestamp for last found sync frame, so that we can verify no
374 // references back past this frame.
375 ASSERT_TRUE(tl0_reference_);
376 last_sync_timestamp_ = tl0_reference_->timestamp;
377 }
378 EXPECT_EQ(tl_config.layer_sync, is_sync_frame);
379
380 // Validate no reference from lower to high temporal layer, or backwards
381 // past last reference frame.
382 ValidateReference(tl_config.last_buffer_flags, last_state, temporal_idx);
383 ValidateReference(tl_config.golden_buffer_flags, golden_state,
384 temporal_idx);
385 ValidateReference(tl_config.arf_buffer_flags, altref_state, temporal_idx);
386
387 // Update the current layer state.
388 BufferState state = {temporal_idx, timestamp_, is_sync_frame};
389 if (tl_config.last_buffer_flags & TemporalLayers::kUpdate)
390 last_state = state;
391 if (tl_config.golden_buffer_flags & TemporalLayers::kUpdate)
392 golden_state = state;
393 if (tl_config.arf_buffer_flags & TemporalLayers::kUpdate)
394 altref_state = state;
395 }
396 }
397 } // namespace test
238 } // namespace webrtc 398 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698