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> | 12 #include <assert.h> |
13 #include <stdlib.h> | 13 #include <stdlib.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #include <algorithm> | 16 #include <algorithm> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
20 #include "webrtc/modules/include/module_common_types.h" | 20 #include "webrtc/modules/include/module_common_types.h" |
21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
23 | 23 |
24 #include "vpx/vpx_encoder.h" | 24 #include "vpx/vpx_encoder.h" |
25 #include "vpx/vp8cx.h" | 25 #include "vpx/vp8cx.h" |
26 | 26 |
27 namespace webrtc { | 27 namespace webrtc { |
28 | 28 |
29 TemporalReferences::TemporalReferences(TemporalBufferUsage last, | |
30 TemporalBufferUsage golden, | |
31 TemporalBufferUsage arf) | |
32 : TemporalReferences(last, golden, arf, false, false) {} | |
33 | |
34 TemporalReferences::TemporalReferences(TemporalBufferUsage last, | |
35 TemporalBufferUsage golden, | |
36 TemporalBufferUsage arf, | |
37 int extra_flags) | |
38 : TemporalReferences(last, | |
39 golden, | |
40 arf, | |
41 (extra_flags & kLayerSync) != 0, | |
42 (extra_flags & kFreezeEntropy) != 0) {} | |
43 | |
44 TemporalReferences::TemporalReferences(TemporalBufferUsage last, | |
45 TemporalBufferUsage golden, | |
46 TemporalBufferUsage arf, | |
47 bool layer_sync, | |
48 bool freeze_entropy) | |
49 : reference_last((last & kReference) != 0), | |
50 update_last((last & kUpdate) != 0), | |
51 reference_golden((golden & kReference) != 0), | |
52 update_golden((golden & kUpdate) != 0), | |
53 reference_arf((arf & kReference) != 0), | |
54 update_arf((arf & kUpdate) != 0), | |
55 layer_sync(layer_sync), | |
56 freeze_entropy(freeze_entropy) {} | |
57 | |
58 namespace { | |
brandtr
2017/03/21 12:20:09
nit: New line between l58 and l59. (Or remove spac
pbos-webrtc
2017/03/21 17:37:46
Done.
| |
59 std::vector<unsigned int> GetTemporalIds(size_t num_layers) { | |
60 switch (num_layers) { | |
61 case 1: | |
62 return {0}; | |
63 case 2: | |
64 return {0, 1}; | |
65 case 3: | |
66 return {0, 2, 1, 2}; | |
67 case 4: | |
brandtr
2017/03/21 12:20:09
Might be good to add a diagram showing these IDs v
sprang_webrtc
2017/03/21 13:50:38
Do we ever use 4 temporal layers in practice?
pbos-webrtc
2017/03/21 17:37:46
Done.
pbos-webrtc
2017/03/21 17:37:46
No, but they are supported in RTP, hardware encode
| |
68 return {0, 3, 2, 3, 1, 3, 2, 3}; | |
69 default: | |
70 RTC_NOTREACHED(); | |
71 break; | |
72 } | |
73 RTC_NOTREACHED(); | |
74 return {0}; | |
75 } | |
76 | |
77 std::vector<TemporalReferences> GetTemporalPattern( | |
78 size_t num_layers) { | |
79 switch (num_layers) { | |
80 case 1: | |
81 return {TemporalReferences(kReferenceAndUpdate, kReference, kReference)}; | |
brandtr
2017/03/21 12:20:09
It would be great with some simple ASCII art here,
pbos-webrtc
2017/03/21 17:37:46
Since this contains all references drawing this is
brandtr
2017/03/22 08:44:42
Much easier to read through the lists now, thanks.
| |
82 case 2: | |
83 return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference), | |
84 TemporalReferences(kReference, kUpdate, kReference, kLayerSync), | |
85 TemporalReferences(kReferenceAndUpdate, kNone, kReference), | |
86 TemporalReferences(kReference, kReferenceAndUpdate, kReference), | |
87 TemporalReferences(kReferenceAndUpdate, kNone, kReference), | |
88 TemporalReferences(kReference, kReferenceAndUpdate, kReference), | |
89 TemporalReferences(kReferenceAndUpdate, kNone, kReference), | |
90 TemporalReferences(kReference, kReference, kReference, | |
91 kFreezeEntropy)}; | |
92 case 3: | |
93 return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference), | |
94 TemporalReferences(kReference, kNone, kReference, | |
95 kLayerSync | kFreezeEntropy), | |
96 TemporalReferences(kReference, kUpdate, kReference, kLayerSync), | |
97 TemporalReferences(kReference, kReference, kReference, | |
98 kFreezeEntropy), | |
99 TemporalReferences(kReferenceAndUpdate, kNone, kReference), | |
100 TemporalReferences(kReference, kReference, kReference, | |
101 kFreezeEntropy), | |
102 TemporalReferences(kReference, kReferenceAndUpdate, kReference), | |
103 TemporalReferences(kReference, kReference, kReference, | |
104 kFreezeEntropy)}; | |
105 case 4: | |
106 return {TemporalReferences(kReferenceAndUpdate, kNone, kNone), | |
107 TemporalReferences(kReference, kReference, kReference, | |
108 kLayerSync | kFreezeEntropy), | |
109 TemporalReferences(kReference, kNone, kUpdate, kLayerSync), | |
110 TemporalReferences(kReference, kReference, kReference, | |
111 kLayerSync | kFreezeEntropy), | |
112 TemporalReferences(kReference, kUpdate, kNone, kLayerSync), | |
113 TemporalReferences(kReference, kReference, kReference, | |
114 kLayerSync | kFreezeEntropy), | |
115 TemporalReferences(kReference, kReference, kReferenceAndUpdate), | |
116 TemporalReferences(kReference, kReference, kReference, | |
117 kLayerSync | kFreezeEntropy), | |
118 TemporalReferences(kReferenceAndUpdate, kNone, kNone), | |
119 TemporalReferences(kReference, kReference, kReference, | |
120 kLayerSync | kFreezeEntropy), | |
121 TemporalReferences(kReference, kReference, kReferenceAndUpdate), | |
122 TemporalReferences(kReference, kReference, kReference, | |
123 kLayerSync | kFreezeEntropy), | |
124 TemporalReferences(kReference, kReferenceAndUpdate, kNone), | |
125 TemporalReferences(kReference, kReference, kReference, | |
126 kLayerSync | kFreezeEntropy), | |
127 TemporalReferences(kReference, kReference, kReferenceAndUpdate), | |
128 TemporalReferences(kReference, kReference, kReference, | |
129 kLayerSync | kFreezeEntropy)}; | |
130 default: | |
131 RTC_NOTREACHED(); | |
132 break; | |
133 } | |
134 RTC_NOTREACHED(); | |
135 return {TemporalReferences(kNone, kNone, kNone)}; | |
136 } | |
137 | |
138 } // namespace | |
139 | |
29 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, | 140 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, |
30 uint8_t initial_tl0_pic_idx) | 141 uint8_t initial_tl0_pic_idx) |
31 : number_of_temporal_layers_(number_of_temporal_layers), | 142 : num_layers_(std::max(1, number_of_temporal_layers)), |
32 temporal_ids_length_(0), | 143 temporal_ids_(GetTemporalIds(num_layers_)), |
33 temporal_pattern_length_(0), | 144 temporal_pattern_(GetTemporalPattern(num_layers_)), |
34 tl0_pic_idx_(initial_tl0_pic_idx), | 145 tl0_pic_idx_(initial_tl0_pic_idx), |
35 pattern_idx_(255), | 146 pattern_idx_(255), |
36 timestamp_(0), | 147 timestamp_(0), |
37 last_base_layer_sync_(false) { | 148 last_base_layer_sync_(false) { |
38 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); | 149 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); |
39 RTC_CHECK_GE(number_of_temporal_layers, 0); | 150 RTC_CHECK_GE(number_of_temporal_layers, 0); |
40 memset(temporal_ids_, 0, sizeof(temporal_ids_)); | 151 RTC_CHECK_LE(number_of_temporal_layers, 4); |
41 memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); | |
42 } | 152 } |
43 | 153 |
44 int DefaultTemporalLayers::CurrentLayerId() const { | 154 int DefaultTemporalLayers::CurrentLayerId() const { |
45 assert(temporal_ids_length_ > 0); | 155 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 } | 156 } |
50 | 157 |
51 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( | 158 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( |
52 int bitrate_kbps, | 159 int bitrate_kbps, |
53 int max_bitrate_kbps, | 160 int max_bitrate_kbps, |
54 int framerate) { | 161 int framerate) { |
55 std::vector<uint32_t> bitrates; | 162 std::vector<uint32_t> bitrates; |
56 const int num_layers = std::max(1, number_of_temporal_layers_); | 163 for (size_t i = 0; i < num_layers_; ++i) { |
57 for (int i = 0; i < num_layers; ++i) { | |
58 float layer_bitrate = | 164 float layer_bitrate = |
59 bitrate_kbps * kVp8LayerRateAlloction[num_layers - 1][i]; | 165 bitrate_kbps * kVp8LayerRateAlloction[num_layers_ - 1][i]; |
60 bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5)); | 166 bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5)); |
61 } | 167 } |
62 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates); | 168 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates); |
63 | 169 |
64 // Allocation table is of aggregates, transform to individual rates. | 170 // Allocation table is of aggregates, transform to individual rates. |
65 uint32_t sum = 0; | 171 uint32_t sum = 0; |
66 for (int i = 0; i < num_layers; ++i) { | 172 for (size_t i = 0; i < num_layers_; ++i) { |
67 uint32_t layer_bitrate = bitrates[i]; | 173 uint32_t layer_bitrate = bitrates[i]; |
68 RTC_DCHECK_LE(sum, bitrates[i]); | 174 RTC_DCHECK_LE(sum, bitrates[i]); |
69 bitrates[i] -= sum; | 175 bitrates[i] -= sum; |
70 sum = layer_bitrate; | 176 sum = layer_bitrate; |
71 | 177 |
72 if (sum >= static_cast<uint32_t>(bitrate_kbps)) { | 178 if (sum >= static_cast<uint32_t>(bitrate_kbps)) { |
73 // Sum adds up; any subsequent layers will be 0. | 179 // Sum adds up; any subsequent layers will be 0. |
74 bitrates.resize(i + 1); | 180 bitrates.resize(i + 1); |
75 break; | 181 break; |
76 } | 182 } |
77 } | 183 } |
78 | 184 |
79 return bitrates; | 185 return bitrates; |
80 } | 186 } |
81 | 187 |
82 bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { | 188 bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { |
83 if (!new_bitrates_kbps_) | 189 if (!new_bitrates_kbps_) |
84 return false; | 190 return false; |
85 | 191 |
86 switch (number_of_temporal_layers_) { | 192 for (size_t i = 0; i < num_layers_; ++i) { |
87 case 0: | 193 cfg->ts_target_bitrate[i] = (*new_bitrates_kbps_)[i]; |
88 FALLTHROUGH(); | 194 // ..., 4, 2, 1 |
89 case 1: | 195 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 } | 196 } |
199 | 197 |
198 cfg->ts_number_layers = num_layers_; | |
199 cfg->ts_periodicity = temporal_ids_.size(); | |
200 memcpy(cfg->ts_layer_id, &temporal_ids_[0], | |
201 sizeof(unsigned int) * temporal_ids_.size()); | |
202 | |
200 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(); | 203 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(); |
201 | 204 |
202 return true; | 205 return true; |
203 } | 206 } |
204 | 207 |
205 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { | 208 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { |
206 assert(number_of_temporal_layers_ > 0); | 209 assert(num_layers_ > 0); |
207 assert(kMaxTemporalPattern >= temporal_pattern_length_); | 210 assert(0 < temporal_pattern_.size()); |
208 assert(0 < temporal_pattern_length_); | |
209 int flags = 0; | 211 int flags = 0; |
210 int patternIdx = ++pattern_idx_ % temporal_pattern_length_; | 212 int patternIdx = ++pattern_idx_ % temporal_pattern_.size(); |
sprang_webrtc
2017/03/21 13:50:38
Why not just update pattern_idx_ itself?
pbos-webrtc
2017/03/21 17:37:46
pattern_idx_ is used for both temporal_pattern_.si
| |
211 assert(kMaxTemporalPattern >= patternIdx); | 213 const TemporalReferences& references = temporal_pattern_[patternIdx]; |
212 switch (temporal_pattern_[patternIdx]) { | 214 |
213 case kTemporalUpdateLast: | 215 if (!references.reference_last) |
214 flags |= VP8_EFLAG_NO_UPD_GF; | 216 flags |= VP8_EFLAG_NO_REF_LAST; |
215 flags |= VP8_EFLAG_NO_UPD_ARF; | 217 if (!references.update_last) |
216 flags |= VP8_EFLAG_NO_REF_GF; | 218 flags |= VP8_EFLAG_NO_UPD_LAST; |
217 flags |= VP8_EFLAG_NO_REF_ARF; | 219 if (!references.reference_golden) |
218 break; | 220 flags |= VP8_EFLAG_NO_REF_GF; |
219 case kTemporalUpdateGoldenWithoutDependency: | 221 if (!references.update_golden) |
220 flags |= VP8_EFLAG_NO_REF_GF; | 222 flags |= VP8_EFLAG_NO_UPD_GF; |
221 // Deliberately no break here. | 223 if (!references.reference_arf) |
222 FALLTHROUGH(); | 224 flags |= VP8_EFLAG_NO_REF_ARF; |
223 case kTemporalUpdateGolden: | 225 if (!references.update_arf) |
224 flags |= VP8_EFLAG_NO_REF_ARF; | 226 flags |= VP8_EFLAG_NO_UPD_ARF; |
225 flags |= VP8_EFLAG_NO_UPD_ARF; | 227 if (references.freeze_entropy) |
226 flags |= VP8_EFLAG_NO_UPD_LAST; | 228 flags |= VP8_EFLAG_NO_UPD_ENTROPY; |
227 break; | 229 |
228 case kTemporalUpdateAltrefWithoutDependency: | |
229 flags |= VP8_EFLAG_NO_REF_ARF; | |
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; | 230 return flags; |
278 } | 231 } |
279 | 232 |
280 void DefaultTemporalLayers::PopulateCodecSpecific( | 233 void DefaultTemporalLayers::PopulateCodecSpecific( |
281 bool base_layer_sync, | 234 bool base_layer_sync, |
282 CodecSpecificInfoVP8* vp8_info, | 235 CodecSpecificInfoVP8* vp8_info, |
283 uint32_t timestamp) { | 236 uint32_t timestamp) { |
284 assert(number_of_temporal_layers_ > 0); | 237 assert(num_layers_ > 0); |
sprang_webrtc
2017/03/21 13:50:38
nit: RTC_[D]CHECK_GT
pbos-webrtc
2017/03/21 17:37:46
Done.
| |
285 assert(0 < temporal_ids_length_); | |
286 | 238 |
287 if (number_of_temporal_layers_ == 1) { | 239 if (num_layers_ == 1) { |
288 vp8_info->temporalIdx = kNoTemporalIdx; | 240 vp8_info->temporalIdx = kNoTemporalIdx; |
289 vp8_info->layerSync = false; | 241 vp8_info->layerSync = false; |
290 vp8_info->tl0PicIdx = kNoTl0PicIdx; | 242 vp8_info->tl0PicIdx = kNoTl0PicIdx; |
291 } else { | 243 } else { |
292 if (base_layer_sync) { | 244 if (base_layer_sync) { |
293 vp8_info->temporalIdx = 0; | 245 vp8_info->temporalIdx = 0; |
294 vp8_info->layerSync = true; | 246 vp8_info->layerSync = true; |
295 } else { | 247 } else { |
296 vp8_info->temporalIdx = CurrentLayerId(); | 248 vp8_info->temporalIdx = CurrentLayerId(); |
297 TemporalReferences temporal_reference = | 249 TemporalReferences temporal_reference = |
298 temporal_pattern_[pattern_idx_ % temporal_pattern_length_]; | 250 temporal_pattern_[pattern_idx_ % temporal_pattern_.size()]; |
299 | 251 |
300 if (temporal_reference == kTemporalUpdateAltrefWithoutDependency || | 252 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 } | 253 } |
312 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { | 254 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { |
313 // Regardless of pattern the frame after a base layer sync will always | 255 // Regardless of pattern the frame after a base layer sync will always |
314 // be a layer sync. | 256 // be a layer sync. |
315 vp8_info->layerSync = true; | 257 vp8_info->layerSync = true; |
316 } | 258 } |
317 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { | 259 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { |
318 timestamp_ = timestamp; | 260 timestamp_ = timestamp; |
319 tl0_pic_idx_++; | 261 tl0_pic_idx_++; |
320 } | 262 } |
(...skipping 11 matching lines...) Expand all Loading... | |
332 if (listener_) | 274 if (listener_) |
333 listener_->OnTemporalLayersCreated(simulcast_id, tl); | 275 listener_->OnTemporalLayersCreated(simulcast_id, tl); |
334 return tl; | 276 return tl; |
335 } | 277 } |
336 | 278 |
337 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { | 279 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { |
338 listener_ = listener; | 280 listener_ = listener; |
339 } | 281 } |
340 | 282 |
341 } // namespace webrtc | 283 } // namespace webrtc |
OLD | NEW |