OLD | NEW |
---|---|
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 Loading... | |
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 |
OLD | NEW |