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

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

Issue 2747123005: Simplify default temporal layers. (Closed)
Patch Set: nits + add comments Created 3 years, 9 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
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
2 * 2 *
3 * Use of this source code is governed by a BSD-style license 3 * Use of this source code is governed by a BSD-style license
4 * that can be found in the LICENSE file in the root of the source 4 * that can be found in the LICENSE file in the root of the source
5 * tree. An additional intellectual property rights grant can be found 5 * tree. An additional intellectual property rights grant can be found
6 * in the file PATENTS. All contributing project authors may 6 * in the file PATENTS. All contributing project authors may
7 * be found in the AUTHORS file in the root of the source tree. 7 * be found in the AUTHORS file in the root of the source tree.
8 */ 8 */
9 9
10 #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" 10 #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
11 11
12 #include <assert.h>
13 #include <stdlib.h> 12 #include <stdlib.h>
14 #include <string.h> 13 #include <string.h>
15 14
16 #include <algorithm> 15 #include <algorithm>
17 #include <vector> 16 #include <vector>
18 17
19 #include "webrtc/base/checks.h" 18 #include "webrtc/base/checks.h"
20 #include "webrtc/modules/include/module_common_types.h" 19 #include "webrtc/modules/include/module_common_types.h"
21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 20 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" 21 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
23 22
24 #include "vpx/vpx_encoder.h" 23 #include "vpx/vpx_encoder.h"
25 #include "vpx/vp8cx.h" 24 #include "vpx/vp8cx.h"
26 25
27 namespace webrtc { 26 namespace webrtc {
28 27
28 TemporalReferences::TemporalReferences(TemporalBufferUsage last,
29 TemporalBufferUsage golden,
30 TemporalBufferUsage arf)
31 : TemporalReferences(last, golden, arf, false, false) {}
32
33 TemporalReferences::TemporalReferences(TemporalBufferUsage last,
34 TemporalBufferUsage golden,
35 TemporalBufferUsage arf,
36 int extra_flags)
37 : TemporalReferences(last,
38 golden,
39 arf,
40 (extra_flags & kLayerSync) != 0,
41 (extra_flags & kFreezeEntropy) != 0) {}
42
43 TemporalReferences::TemporalReferences(TemporalBufferUsage last,
44 TemporalBufferUsage golden,
45 TemporalBufferUsage arf,
46 bool layer_sync,
47 bool freeze_entropy)
48 : reference_last((last & kReference) != 0),
49 update_last((last & kUpdate) != 0),
50 reference_golden((golden & kReference) != 0),
51 update_golden((golden & kUpdate) != 0),
52 reference_arf((arf & kReference) != 0),
53 update_arf((arf & kUpdate) != 0),
54 layer_sync(layer_sync),
55 freeze_entropy(freeze_entropy) {}
56
57 namespace {
58
59 std::vector<unsigned int> GetTemporalIds(size_t num_layers) {
60 switch (num_layers) {
61 case 1:
62 // Temporal layer structure (single layer):
63 // 0 0 0 0 ...
64 return {0};
65 case 2:
66 // Temporal layer structure:
67 // 1 1 ...
68 // 0 0 ...
69 return {0, 1};
70 case 3:
71 // Temporal layer structure:
72 // 2 2 2 2 ...
73 // 1 1 ...
74 // 0 0 ...
75 return {0, 2, 1, 2};
76 case 4:
77 // Temporal layer structure:
78 // 3 3 3 3 3 3 3 3 ...
79 // 2 2 2 2 ...
80 // 1 1 ...
81 // 0 0 ...
82 return {0, 3, 2, 3, 1, 3, 2, 3};
83 default:
84 RTC_NOTREACHED();
85 break;
86 }
87 RTC_NOTREACHED();
88 return {0};
89 }
90
91 std::vector<TemporalReferences> GetTemporalPattern(
92 size_t num_layers) {
93 // For indexing in the patterns described below (which temporal layers they
94 // belong to), see the diagram above.
95 // Layer sync is done similarly for all patterns (except single stream):
96 // TL1 layer syncs by periodically not referencing (but still updating) the
97 // 'golden' and by doing so only depending on TL0.
98 // TL2 layer syncs just before TL1 by not depending on TL1's buffer before TL1
99 // has layer synced as well.
100 // TODO(pbos): Consider cyclically updating 'arf' and 'golden' for the base
101 // layer in 1-3TL instead of 'last' periodically on longer intervals (say
102 // every 8 and 32th frame).
103 switch (num_layers) {
104 case 1:
105 // All frames reference all buffers and the 'last' buffer is updated.
106 return {TemporalReferences(kReferenceAndUpdate, kReference, kReference)};
107 case 2:
108 // All layers can reference but not update the 'alt' buffer, this means
109 // that the 'alt' buffer reference is effectively the last keyframe.
110 // TL0 can also reference and update the 'last' buffer.
111 // TL1 can also reference 'last' and reference and update 'golden'.
112 // TL1 layer syncs by periodically not referencing (but still updating)
113 // the 'golden' and by doing so only depending on TL0.
114 return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference),
115 TemporalReferences(kReference, kUpdate, kReference, kLayerSync),
116 TemporalReferences(kReferenceAndUpdate, kNone, kReference),
117 TemporalReferences(kReference, kReferenceAndUpdate, kReference),
118 TemporalReferences(kReferenceAndUpdate, kNone, kReference),
119 TemporalReferences(kReference, kReferenceAndUpdate, kReference),
120 TemporalReferences(kReferenceAndUpdate, kNone, kReference),
121 TemporalReferences(kReference, kReference, kReference,
122 kFreezeEntropy)};
123 case 3:
124 // All layers can reference but not update the 'alt' buffer, this means
125 // that the 'alt' buffer reference is effectively the last keyframe.
126 // TL0 can also reference and update the 'last' buffer.
127 // TL1 can also reference 'last' and reference and update 'golden'.
128 // TL2 references both 'last' and 'golden' but updates no buffer.
129 return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference),
130 TemporalReferences(kReference, kNone, kReference,
131 kLayerSync | kFreezeEntropy),
132 TemporalReferences(kReference, kUpdate, kReference, kLayerSync),
133 TemporalReferences(kReference, kReference, kReference,
134 kFreezeEntropy),
135 TemporalReferences(kReferenceAndUpdate, kNone, kReference),
136 TemporalReferences(kReference, kReference, kReference,
137 kFreezeEntropy),
138 TemporalReferences(kReference, kReferenceAndUpdate, kReference),
139 TemporalReferences(kReference, kReference, kReference,
140 kFreezeEntropy)};
141 case 4:
142 // TL0 references and updates only the 'last' buffer.
143 // TL1 references 'last' and updates and references 'golden'.
144 // TL2 references 'last' and 'golden', and references and updates 'arf'.
145 // TL3 references all buffers but update none of them.
146 return {TemporalReferences(kReferenceAndUpdate, kNone, kNone),
147 TemporalReferences(kReference, kReference, kReference,
pbos-webrtc 2017/03/21 17:37:46 marpan@: This does not look like a proper layer sy
148 kLayerSync | kFreezeEntropy),
149 TemporalReferences(kReference, kNone, kUpdate, kLayerSync),
150 TemporalReferences(kReference, kReference, kReference,
151 kLayerSync | kFreezeEntropy),
152 TemporalReferences(kReference, kUpdate, kNone, kLayerSync),
153 TemporalReferences(kReference, kReference, kReference,
154 kLayerSync | kFreezeEntropy),
155 TemporalReferences(kReference, kReference, kReferenceAndUpdate),
156 TemporalReferences(kReference, kReference, kReference,
157 kLayerSync | kFreezeEntropy),
158 TemporalReferences(kReferenceAndUpdate, kNone, kNone),
159 TemporalReferences(kReference, kReference, kReference,
160 kLayerSync | kFreezeEntropy),
161 TemporalReferences(kReference, kReference, kReferenceAndUpdate),
162 TemporalReferences(kReference, kReference, kReference,
163 kLayerSync | kFreezeEntropy),
164 TemporalReferences(kReference, kReferenceAndUpdate, kNone),
165 TemporalReferences(kReference, kReference, kReference,
166 kLayerSync | kFreezeEntropy),
167 TemporalReferences(kReference, kReference, kReferenceAndUpdate),
168 TemporalReferences(kReference, kReference, kReference,
169 kLayerSync | kFreezeEntropy)};
170 default:
171 RTC_NOTREACHED();
172 break;
173 }
174 RTC_NOTREACHED();
175 return {TemporalReferences(kNone, kNone, kNone)};
176 }
177
178 } // namespace
179
29 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, 180 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers,
30 uint8_t initial_tl0_pic_idx) 181 uint8_t initial_tl0_pic_idx)
31 : number_of_temporal_layers_(number_of_temporal_layers), 182 : num_layers_(std::max(1, number_of_temporal_layers)),
32 temporal_ids_length_(0), 183 temporal_ids_(GetTemporalIds(num_layers_)),
33 temporal_pattern_length_(0), 184 temporal_pattern_(GetTemporalPattern(num_layers_)),
34 tl0_pic_idx_(initial_tl0_pic_idx), 185 tl0_pic_idx_(initial_tl0_pic_idx),
35 pattern_idx_(255), 186 pattern_idx_(255),
36 timestamp_(0), 187 timestamp_(0),
37 last_base_layer_sync_(false) { 188 last_base_layer_sync_(false) {
38 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); 189 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
39 RTC_CHECK_GE(number_of_temporal_layers, 0); 190 RTC_CHECK_GE(number_of_temporal_layers, 0);
40 memset(temporal_ids_, 0, sizeof(temporal_ids_)); 191 RTC_CHECK_LE(number_of_temporal_layers, 4);
41 memset(temporal_pattern_, 0, sizeof(temporal_pattern_));
42 } 192 }
43 193
44 int DefaultTemporalLayers::CurrentLayerId() const { 194 int DefaultTemporalLayers::CurrentLayerId() const {
45 assert(temporal_ids_length_ > 0); 195 return temporal_ids_[pattern_idx_ % temporal_ids_.size()];
46 int index = pattern_idx_ % temporal_ids_length_;
47 assert(index >= 0);
48 return temporal_ids_[index];
49 } 196 }
50 197
51 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( 198 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated(
52 int bitrate_kbps, 199 int bitrate_kbps,
53 int max_bitrate_kbps, 200 int max_bitrate_kbps,
54 int framerate) { 201 int framerate) {
55 std::vector<uint32_t> bitrates; 202 std::vector<uint32_t> bitrates;
56 const int num_layers = std::max(1, number_of_temporal_layers_); 203 for (size_t i = 0; i < num_layers_; ++i) {
57 for (int i = 0; i < num_layers; ++i) {
58 float layer_bitrate = 204 float layer_bitrate =
59 bitrate_kbps * kVp8LayerRateAlloction[num_layers - 1][i]; 205 bitrate_kbps * kVp8LayerRateAlloction[num_layers_ - 1][i];
60 bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5)); 206 bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5));
61 } 207 }
62 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates); 208 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates);
63 209
64 // Allocation table is of aggregates, transform to individual rates. 210 // Allocation table is of aggregates, transform to individual rates.
65 uint32_t sum = 0; 211 uint32_t sum = 0;
66 for (int i = 0; i < num_layers; ++i) { 212 for (size_t i = 0; i < num_layers_; ++i) {
67 uint32_t layer_bitrate = bitrates[i]; 213 uint32_t layer_bitrate = bitrates[i];
68 RTC_DCHECK_LE(sum, bitrates[i]); 214 RTC_DCHECK_LE(sum, bitrates[i]);
69 bitrates[i] -= sum; 215 bitrates[i] -= sum;
70 sum = layer_bitrate; 216 sum = layer_bitrate;
71 217
72 if (sum >= static_cast<uint32_t>(bitrate_kbps)) { 218 if (sum >= static_cast<uint32_t>(bitrate_kbps)) {
73 // Sum adds up; any subsequent layers will be 0. 219 // Sum adds up; any subsequent layers will be 0.
74 bitrates.resize(i + 1); 220 bitrates.resize(i + 1);
75 break; 221 break;
76 } 222 }
77 } 223 }
78 224
79 return bitrates; 225 return bitrates;
80 } 226 }
81 227
82 bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { 228 bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
83 if (!new_bitrates_kbps_) 229 if (!new_bitrates_kbps_)
84 return false; 230 return false;
85 231
86 switch (number_of_temporal_layers_) { 232 for (size_t i = 0; i < num_layers_; ++i) {
87 case 0: 233 cfg->ts_target_bitrate[i] = (*new_bitrates_kbps_)[i];
88 FALLTHROUGH(); 234 // ..., 4, 2, 1
89 case 1: 235 cfg->ts_rate_decimator[i] = 1 << (num_layers_ - i - 1);
90 temporal_ids_length_ = 1;
91 temporal_ids_[0] = 0;
92 cfg->ts_number_layers = number_of_temporal_layers_;
93 cfg->ts_periodicity = temporal_ids_length_;
94 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
95 cfg->ts_rate_decimator[0] = 1;
96 memcpy(cfg->ts_layer_id, temporal_ids_,
97 sizeof(unsigned int) * temporal_ids_length_);
98 temporal_pattern_length_ = 1;
99 temporal_pattern_[0] = kTemporalUpdateLastRefAll;
100 break;
101 case 2:
102 temporal_ids_length_ = 2;
103 temporal_ids_[0] = 0;
104 temporal_ids_[1] = 1;
105 cfg->ts_number_layers = number_of_temporal_layers_;
106 cfg->ts_periodicity = temporal_ids_length_;
107 // Split stream 60% 40%.
108 // Bitrate API for VP8 is the agregated bitrate for all lower layers.
109 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
110 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
111 cfg->ts_rate_decimator[0] = 2;
112 cfg->ts_rate_decimator[1] = 1;
113 memcpy(cfg->ts_layer_id, temporal_ids_,
114 sizeof(unsigned int) * temporal_ids_length_);
115 temporal_pattern_length_ = 8;
116 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
117 temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
118 temporal_pattern_[2] = kTemporalUpdateLastRefAltRef;
119 temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef;
120 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
121 temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef;
122 temporal_pattern_[6] = kTemporalUpdateLastRefAltRef;
123 temporal_pattern_[7] = kTemporalUpdateNone;
124 break;
125 case 3:
126 temporal_ids_length_ = 4;
127 temporal_ids_[0] = 0;
128 temporal_ids_[1] = 2;
129 temporal_ids_[2] = 1;
130 temporal_ids_[3] = 2;
131 cfg->ts_number_layers = number_of_temporal_layers_;
132 cfg->ts_periodicity = temporal_ids_length_;
133 // Split stream 40% 20% 40%.
134 // Bitrate API for VP8 is the agregated bitrate for all lower layers.
135 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
136 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
137 cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2];
138 cfg->ts_rate_decimator[0] = 4;
139 cfg->ts_rate_decimator[1] = 2;
140 cfg->ts_rate_decimator[2] = 1;
141 memcpy(cfg->ts_layer_id, temporal_ids_,
142 sizeof(unsigned int) * temporal_ids_length_);
143 temporal_pattern_length_ = 8;
144 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
145 temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
146 temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
147 temporal_pattern_[3] = kTemporalUpdateNone;
148 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
149 temporal_pattern_[5] = kTemporalUpdateNone;
150 temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef;
151 temporal_pattern_[7] = kTemporalUpdateNone;
152 break;
153 case 4:
154 temporal_ids_length_ = 8;
155 temporal_ids_[0] = 0;
156 temporal_ids_[1] = 3;
157 temporal_ids_[2] = 2;
158 temporal_ids_[3] = 3;
159 temporal_ids_[4] = 1;
160 temporal_ids_[5] = 3;
161 temporal_ids_[6] = 2;
162 temporal_ids_[7] = 3;
163 // Split stream 25% 15% 20% 40%.
164 // Bitrate API for VP8 is the agregated bitrate for all lower layers.
165 cfg->ts_number_layers = 4;
166 cfg->ts_periodicity = temporal_ids_length_;
167 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
168 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
169 cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2];
170 cfg->ts_target_bitrate[3] = (*new_bitrates_kbps_)[3];
171 cfg->ts_rate_decimator[0] = 8;
172 cfg->ts_rate_decimator[1] = 4;
173 cfg->ts_rate_decimator[2] = 2;
174 cfg->ts_rate_decimator[3] = 1;
175 memcpy(cfg->ts_layer_id, temporal_ids_,
176 sizeof(unsigned int) * temporal_ids_length_);
177 temporal_pattern_length_ = 16;
178 temporal_pattern_[0] = kTemporalUpdateLast;
179 temporal_pattern_[1] = kTemporalUpdateNone;
180 temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency;
181 temporal_pattern_[3] = kTemporalUpdateNone;
182 temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency;
183 temporal_pattern_[5] = kTemporalUpdateNone;
184 temporal_pattern_[6] = kTemporalUpdateAltref;
185 temporal_pattern_[7] = kTemporalUpdateNone;
186 temporal_pattern_[8] = kTemporalUpdateLast;
187 temporal_pattern_[9] = kTemporalUpdateNone;
188 temporal_pattern_[10] = kTemporalUpdateAltref;
189 temporal_pattern_[11] = kTemporalUpdateNone;
190 temporal_pattern_[12] = kTemporalUpdateGolden;
191 temporal_pattern_[13] = kTemporalUpdateNone;
192 temporal_pattern_[14] = kTemporalUpdateAltref;
193 temporal_pattern_[15] = kTemporalUpdateNone;
194 break;
195 default:
196 RTC_NOTREACHED();
197 return false;
198 } 236 }
199 237
238 cfg->ts_number_layers = num_layers_;
239 cfg->ts_periodicity = temporal_ids_.size();
240 memcpy(cfg->ts_layer_id, &temporal_ids_[0],
241 sizeof(unsigned int) * temporal_ids_.size());
242
200 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(); 243 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>();
201 244
202 return true; 245 return true;
203 } 246 }
204 247
205 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { 248 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) {
206 assert(number_of_temporal_layers_ > 0); 249 RTC_DCHECK_GT(num_layers_, 0);
207 assert(kMaxTemporalPattern >= temporal_pattern_length_); 250 RTC_DCHECK_LT(0, temporal_pattern_.size());
208 assert(0 < temporal_pattern_length_);
209 int flags = 0; 251 int flags = 0;
210 int patternIdx = ++pattern_idx_ % temporal_pattern_length_; 252 // TODO(pbos): Move pattern-update out of EncodeFlags. It's not obvious that
211 assert(kMaxTemporalPattern >= patternIdx); 253 // EncodeFlags() is non-const.
212 switch (temporal_pattern_[patternIdx]) { 254 const TemporalReferences& references =
213 case kTemporalUpdateLast: 255 temporal_pattern_[++pattern_idx_ % temporal_pattern_.size()];
214 flags |= VP8_EFLAG_NO_UPD_GF; 256
215 flags |= VP8_EFLAG_NO_UPD_ARF; 257 if (!references.reference_last)
216 flags |= VP8_EFLAG_NO_REF_GF; 258 flags |= VP8_EFLAG_NO_REF_LAST;
217 flags |= VP8_EFLAG_NO_REF_ARF; 259 if (!references.update_last)
218 break; 260 flags |= VP8_EFLAG_NO_UPD_LAST;
219 case kTemporalUpdateGoldenWithoutDependency: 261 if (!references.reference_golden)
220 flags |= VP8_EFLAG_NO_REF_GF; 262 flags |= VP8_EFLAG_NO_REF_GF;
221 // Deliberately no break here. 263 if (!references.update_golden)
222 FALLTHROUGH(); 264 flags |= VP8_EFLAG_NO_UPD_GF;
223 case kTemporalUpdateGolden: 265 if (!references.reference_arf)
224 flags |= VP8_EFLAG_NO_REF_ARF; 266 flags |= VP8_EFLAG_NO_REF_ARF;
225 flags |= VP8_EFLAG_NO_UPD_ARF; 267 if (!references.update_arf)
226 flags |= VP8_EFLAG_NO_UPD_LAST; 268 flags |= VP8_EFLAG_NO_UPD_ARF;
227 break; 269 if (references.freeze_entropy)
228 case kTemporalUpdateAltrefWithoutDependency: 270 flags |= VP8_EFLAG_NO_UPD_ENTROPY;
229 flags |= VP8_EFLAG_NO_REF_ARF; 271
230 flags |= VP8_EFLAG_NO_REF_GF;
231 // Deliberately no break here.
232 FALLTHROUGH();
233 case kTemporalUpdateAltref:
234 flags |= VP8_EFLAG_NO_UPD_GF;
235 flags |= VP8_EFLAG_NO_UPD_LAST;
236 break;
237 case kTemporalUpdateNoneNoRefAltref:
238 flags |= VP8_EFLAG_NO_REF_ARF;
239 // Deliberately no break here.
240 FALLTHROUGH();
241 case kTemporalUpdateNone:
242 flags |= VP8_EFLAG_NO_UPD_GF;
243 flags |= VP8_EFLAG_NO_UPD_ARF;
244 flags |= VP8_EFLAG_NO_UPD_LAST;
245 flags |= VP8_EFLAG_NO_UPD_ENTROPY;
246 break;
247 case kTemporalUpdateNoneNoRefGoldenRefAltRef:
248 flags |= VP8_EFLAG_NO_REF_GF;
249 flags |= VP8_EFLAG_NO_UPD_GF;
250 flags |= VP8_EFLAG_NO_UPD_ARF;
251 flags |= VP8_EFLAG_NO_UPD_LAST;
252 flags |= VP8_EFLAG_NO_UPD_ENTROPY;
253 break;
254 case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
255 flags |= VP8_EFLAG_NO_REF_GF;
256 flags |= VP8_EFLAG_NO_UPD_ARF;
257 flags |= VP8_EFLAG_NO_UPD_LAST;
258 break;
259 case kTemporalUpdateLastRefAltRef:
260 flags |= VP8_EFLAG_NO_UPD_GF;
261 flags |= VP8_EFLAG_NO_UPD_ARF;
262 flags |= VP8_EFLAG_NO_REF_GF;
263 break;
264 case kTemporalUpdateGoldenRefAltRef:
265 flags |= VP8_EFLAG_NO_UPD_ARF;
266 flags |= VP8_EFLAG_NO_UPD_LAST;
267 break;
268 case kTemporalUpdateLastAndGoldenRefAltRef:
269 flags |= VP8_EFLAG_NO_UPD_ARF;
270 flags |= VP8_EFLAG_NO_REF_GF;
271 break;
272 case kTemporalUpdateLastRefAll:
273 flags |= VP8_EFLAG_NO_UPD_ARF;
274 flags |= VP8_EFLAG_NO_UPD_GF;
275 break;
276 }
277 return flags; 272 return flags;
278 } 273 }
279 274
280 void DefaultTemporalLayers::PopulateCodecSpecific( 275 void DefaultTemporalLayers::PopulateCodecSpecific(
281 bool base_layer_sync, 276 bool base_layer_sync,
282 CodecSpecificInfoVP8* vp8_info, 277 CodecSpecificInfoVP8* vp8_info,
283 uint32_t timestamp) { 278 uint32_t timestamp) {
284 assert(number_of_temporal_layers_ > 0); 279 RTC_DCHECK_GT(num_layers_, 0);
285 assert(0 < temporal_ids_length_);
286 280
287 if (number_of_temporal_layers_ == 1) { 281 if (num_layers_ == 1) {
288 vp8_info->temporalIdx = kNoTemporalIdx; 282 vp8_info->temporalIdx = kNoTemporalIdx;
289 vp8_info->layerSync = false; 283 vp8_info->layerSync = false;
290 vp8_info->tl0PicIdx = kNoTl0PicIdx; 284 vp8_info->tl0PicIdx = kNoTl0PicIdx;
291 } else { 285 } else {
292 if (base_layer_sync) { 286 if (base_layer_sync) {
293 vp8_info->temporalIdx = 0; 287 vp8_info->temporalIdx = 0;
294 vp8_info->layerSync = true; 288 vp8_info->layerSync = true;
295 } else { 289 } else {
296 vp8_info->temporalIdx = CurrentLayerId(); 290 vp8_info->temporalIdx = CurrentLayerId();
297 TemporalReferences temporal_reference = 291 TemporalReferences temporal_reference =
298 temporal_pattern_[pattern_idx_ % temporal_pattern_length_]; 292 temporal_pattern_[pattern_idx_ % temporal_pattern_.size()];
299 293
300 if (temporal_reference == kTemporalUpdateAltrefWithoutDependency || 294 vp8_info->layerSync = temporal_reference.layer_sync;
301 temporal_reference == kTemporalUpdateGoldenWithoutDependency ||
302 temporal_reference ==
303 kTemporalUpdateGoldenWithoutDependencyRefAltRef ||
304 temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef ||
305 (temporal_reference == kTemporalUpdateNone &&
306 number_of_temporal_layers_ == 4)) {
307 vp8_info->layerSync = true;
308 } else {
309 vp8_info->layerSync = false;
310 }
311 } 295 }
312 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { 296 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
313 // Regardless of pattern the frame after a base layer sync will always 297 // Regardless of pattern the frame after a base layer sync will always
314 // be a layer sync. 298 // be a layer sync.
315 vp8_info->layerSync = true; 299 vp8_info->layerSync = true;
316 } 300 }
317 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { 301 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) {
318 timestamp_ = timestamp; 302 timestamp_ = timestamp;
319 tl0_pic_idx_++; 303 tl0_pic_idx_++;
320 } 304 }
(...skipping 11 matching lines...) Expand all
332 if (listener_) 316 if (listener_)
333 listener_->OnTemporalLayersCreated(simulcast_id, tl); 317 listener_->OnTemporalLayersCreated(simulcast_id, tl);
334 return tl; 318 return tl;
335 } 319 }
336 320
337 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { 321 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) {
338 listener_ = listener; 322 listener_ = listener;
339 } 323 }
340 324
341 } // namespace webrtc 325 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698