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> | |
17 #include <vector> | |
18 | |
19 #include "webrtc/base/checks.h" | |
20 #include "webrtc/modules/include/module_common_types.h" | 16 #include "webrtc/modules/include/module_common_types.h" |
21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 18 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
23 | 19 |
24 #include "vpx/vpx_encoder.h" | 20 #include "vpx/vpx_encoder.h" |
25 #include "vpx/vp8cx.h" | 21 #include "vpx/vp8cx.h" |
26 | 22 |
27 namespace webrtc { | 23 namespace webrtc { |
28 | 24 |
29 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, | 25 DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers, |
30 uint8_t initial_tl0_pic_idx) | 26 uint8_t initial_tl0_pic_idx) |
31 : number_of_temporal_layers_(number_of_temporal_layers), | 27 : number_of_temporal_layers_(numberOfTemporalLayers), |
32 temporal_ids_length_(0), | 28 temporal_ids_length_(0), |
33 temporal_pattern_length_(0), | 29 temporal_pattern_length_(0), |
34 tl0_pic_idx_(initial_tl0_pic_idx), | 30 tl0_pic_idx_(initial_tl0_pic_idx), |
35 pattern_idx_(255), | 31 pattern_idx_(255), |
36 timestamp_(0), | 32 timestamp_(0), |
37 last_base_layer_sync_(false) { | 33 last_base_layer_sync_(false) { |
38 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); | 34 assert(kMaxTemporalStreams >= numberOfTemporalLayers); |
39 RTC_CHECK_GE(number_of_temporal_layers, 0); | |
40 memset(temporal_ids_, 0, sizeof(temporal_ids_)); | 35 memset(temporal_ids_, 0, sizeof(temporal_ids_)); |
41 memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); | 36 memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); |
42 } | 37 } |
43 | 38 |
44 int DefaultTemporalLayers::CurrentLayerId() const { | 39 int DefaultTemporalLayers::CurrentLayerId() const { |
45 assert(temporal_ids_length_ > 0); | 40 assert(temporal_ids_length_ > 0); |
46 int index = pattern_idx_ % temporal_ids_length_; | 41 int index = pattern_idx_ % temporal_ids_length_; |
47 assert(index >= 0); | 42 assert(index >= 0); |
48 return temporal_ids_[index]; | 43 return temporal_ids_[index]; |
49 } | 44 } |
50 | 45 |
51 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( | 46 bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit, |
52 int bitrate_kbps, | 47 int max_bitrate_kbit, |
53 int max_bitrate_kbps, | 48 int framerate, |
54 int framerate) { | 49 vpx_codec_enc_cfg_t* cfg) { |
55 std::vector<uint32_t> bitrates; | |
56 const int num_layers = std::max(1, number_of_temporal_layers_); | |
57 for (int i = 0; i < num_layers; ++i) { | |
58 float layer_bitrate = | |
59 bitrate_kbps * kVp8LayerRateAlloction[num_layers - 1][i]; | |
60 bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5)); | |
61 } | |
62 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates); | |
63 | |
64 // Allocation table is of aggregates, transform to individual rates. | |
65 uint32_t sum = 0; | |
66 for (int i = 0; i < num_layers; ++i) { | |
67 uint32_t layer_bitrate = bitrates[i]; | |
68 RTC_DCHECK_LE(sum, bitrates[i]); | |
69 bitrates[i] -= sum; | |
70 sum = layer_bitrate; | |
71 | |
72 if (sum >= static_cast<uint32_t>(bitrate_kbps)) { | |
73 // Sum adds up; any subsequent layers will be 0. | |
74 bitrates.resize(i + 1); | |
75 break; | |
76 } | |
77 } | |
78 | |
79 return bitrates; | |
80 } | |
81 | |
82 bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { | |
83 if (!new_bitrates_kbps_) | |
84 return false; | |
85 | |
86 switch (number_of_temporal_layers_) { | 50 switch (number_of_temporal_layers_) { |
87 case 0: | 51 case 0: |
88 FALLTHROUGH(); | |
89 case 1: | 52 case 1: |
90 temporal_ids_length_ = 1; | 53 temporal_ids_length_ = 1; |
91 temporal_ids_[0] = 0; | 54 temporal_ids_[0] = 0; |
92 cfg->ts_number_layers = number_of_temporal_layers_; | 55 cfg->ts_number_layers = number_of_temporal_layers_; |
93 cfg->ts_periodicity = temporal_ids_length_; | 56 cfg->ts_periodicity = temporal_ids_length_; |
94 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0]; | 57 cfg->ts_target_bitrate[0] = bitrateKbit; |
95 cfg->ts_rate_decimator[0] = 1; | 58 cfg->ts_rate_decimator[0] = 1; |
96 memcpy(cfg->ts_layer_id, temporal_ids_, | 59 memcpy(cfg->ts_layer_id, temporal_ids_, |
97 sizeof(unsigned int) * temporal_ids_length_); | 60 sizeof(unsigned int) * temporal_ids_length_); |
98 temporal_pattern_length_ = 1; | 61 temporal_pattern_length_ = 1; |
99 temporal_pattern_[0] = kTemporalUpdateLastRefAll; | 62 temporal_pattern_[0] = kTemporalUpdateLastRefAll; |
100 break; | 63 break; |
101 case 2: | 64 case 2: |
102 temporal_ids_length_ = 2; | 65 temporal_ids_length_ = 2; |
103 temporal_ids_[0] = 0; | 66 temporal_ids_[0] = 0; |
104 temporal_ids_[1] = 1; | 67 temporal_ids_[1] = 1; |
105 cfg->ts_number_layers = number_of_temporal_layers_; | 68 cfg->ts_number_layers = number_of_temporal_layers_; |
106 cfg->ts_periodicity = temporal_ids_length_; | 69 cfg->ts_periodicity = temporal_ids_length_; |
107 // Split stream 60% 40%. | 70 // Split stream 60% 40%. |
108 // Bitrate API for VP8 is the agregated bitrate for all lower layers. | 71 // Bitrate API for VP8 is the agregated bitrate for all lower layers. |
109 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0]; | 72 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[1][0]; |
110 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1]; | 73 cfg->ts_target_bitrate[1] = bitrateKbit; |
111 cfg->ts_rate_decimator[0] = 2; | 74 cfg->ts_rate_decimator[0] = 2; |
112 cfg->ts_rate_decimator[1] = 1; | 75 cfg->ts_rate_decimator[1] = 1; |
113 memcpy(cfg->ts_layer_id, temporal_ids_, | 76 memcpy(cfg->ts_layer_id, temporal_ids_, |
114 sizeof(unsigned int) * temporal_ids_length_); | 77 sizeof(unsigned int) * temporal_ids_length_); |
115 temporal_pattern_length_ = 8; | 78 temporal_pattern_length_ = 8; |
116 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; | 79 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; |
117 temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; | 80 temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; |
118 temporal_pattern_[2] = kTemporalUpdateLastRefAltRef; | 81 temporal_pattern_[2] = kTemporalUpdateLastRefAltRef; |
119 temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef; | 82 temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef; |
120 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; | 83 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; |
121 temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef; | 84 temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef; |
122 temporal_pattern_[6] = kTemporalUpdateLastRefAltRef; | 85 temporal_pattern_[6] = kTemporalUpdateLastRefAltRef; |
123 temporal_pattern_[7] = kTemporalUpdateNone; | 86 temporal_pattern_[7] = kTemporalUpdateNone; |
124 break; | 87 break; |
125 case 3: | 88 case 3: |
126 temporal_ids_length_ = 4; | 89 temporal_ids_length_ = 4; |
127 temporal_ids_[0] = 0; | 90 temporal_ids_[0] = 0; |
128 temporal_ids_[1] = 2; | 91 temporal_ids_[1] = 2; |
129 temporal_ids_[2] = 1; | 92 temporal_ids_[2] = 1; |
130 temporal_ids_[3] = 2; | 93 temporal_ids_[3] = 2; |
131 cfg->ts_number_layers = number_of_temporal_layers_; | 94 cfg->ts_number_layers = number_of_temporal_layers_; |
132 cfg->ts_periodicity = temporal_ids_length_; | 95 cfg->ts_periodicity = temporal_ids_length_; |
133 // Split stream 40% 20% 40%. | 96 // Split stream 40% 20% 40%. |
134 // Bitrate API for VP8 is the agregated bitrate for all lower layers. | 97 // Bitrate API for VP8 is the agregated bitrate for all lower layers. |
135 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0]; | 98 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[2][0]; |
136 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1]; | 99 cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[2][1]; |
137 cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2]; | 100 cfg->ts_target_bitrate[2] = bitrateKbit; |
138 cfg->ts_rate_decimator[0] = 4; | 101 cfg->ts_rate_decimator[0] = 4; |
139 cfg->ts_rate_decimator[1] = 2; | 102 cfg->ts_rate_decimator[1] = 2; |
140 cfg->ts_rate_decimator[2] = 1; | 103 cfg->ts_rate_decimator[2] = 1; |
141 memcpy(cfg->ts_layer_id, temporal_ids_, | 104 memcpy(cfg->ts_layer_id, temporal_ids_, |
142 sizeof(unsigned int) * temporal_ids_length_); | 105 sizeof(unsigned int) * temporal_ids_length_); |
143 temporal_pattern_length_ = 8; | 106 temporal_pattern_length_ = 8; |
144 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; | 107 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; |
145 temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef; | 108 temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef; |
146 temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; | 109 temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; |
147 temporal_pattern_[3] = kTemporalUpdateNone; | 110 temporal_pattern_[3] = kTemporalUpdateNone; |
148 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; | 111 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; |
149 temporal_pattern_[5] = kTemporalUpdateNone; | 112 temporal_pattern_[5] = kTemporalUpdateNone; |
150 temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef; | 113 temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef; |
151 temporal_pattern_[7] = kTemporalUpdateNone; | 114 temporal_pattern_[7] = kTemporalUpdateNone; |
152 break; | 115 break; |
153 case 4: | 116 case 4: |
154 temporal_ids_length_ = 8; | 117 temporal_ids_length_ = 8; |
155 temporal_ids_[0] = 0; | 118 temporal_ids_[0] = 0; |
156 temporal_ids_[1] = 3; | 119 temporal_ids_[1] = 3; |
157 temporal_ids_[2] = 2; | 120 temporal_ids_[2] = 2; |
158 temporal_ids_[3] = 3; | 121 temporal_ids_[3] = 3; |
159 temporal_ids_[4] = 1; | 122 temporal_ids_[4] = 1; |
160 temporal_ids_[5] = 3; | 123 temporal_ids_[5] = 3; |
161 temporal_ids_[6] = 2; | 124 temporal_ids_[6] = 2; |
162 temporal_ids_[7] = 3; | 125 temporal_ids_[7] = 3; |
163 // Split stream 25% 15% 20% 40%. | 126 // Split stream 25% 15% 20% 40%. |
164 // Bitrate API for VP8 is the agregated bitrate for all lower layers. | 127 // Bitrate API for VP8 is the agregated bitrate for all lower layers. |
165 cfg->ts_number_layers = 4; | 128 cfg->ts_number_layers = 4; |
166 cfg->ts_periodicity = temporal_ids_length_; | 129 cfg->ts_periodicity = temporal_ids_length_; |
167 cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0]; | 130 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[3][0]; |
168 cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1]; | 131 cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[3][1]; |
169 cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2]; | 132 cfg->ts_target_bitrate[2] = bitrateKbit * kVp8LayerRateAlloction[3][2]; |
170 cfg->ts_target_bitrate[3] = (*new_bitrates_kbps_)[3]; | 133 cfg->ts_target_bitrate[3] = bitrateKbit; |
171 cfg->ts_rate_decimator[0] = 8; | 134 cfg->ts_rate_decimator[0] = 8; |
172 cfg->ts_rate_decimator[1] = 4; | 135 cfg->ts_rate_decimator[1] = 4; |
173 cfg->ts_rate_decimator[2] = 2; | 136 cfg->ts_rate_decimator[2] = 2; |
174 cfg->ts_rate_decimator[3] = 1; | 137 cfg->ts_rate_decimator[3] = 1; |
175 memcpy(cfg->ts_layer_id, temporal_ids_, | 138 memcpy(cfg->ts_layer_id, temporal_ids_, |
176 sizeof(unsigned int) * temporal_ids_length_); | 139 sizeof(unsigned int) * temporal_ids_length_); |
177 temporal_pattern_length_ = 16; | 140 temporal_pattern_length_ = 16; |
178 temporal_pattern_[0] = kTemporalUpdateLast; | 141 temporal_pattern_[0] = kTemporalUpdateLast; |
179 temporal_pattern_[1] = kTemporalUpdateNone; | 142 temporal_pattern_[1] = kTemporalUpdateNone; |
180 temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency; | 143 temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency; |
181 temporal_pattern_[3] = kTemporalUpdateNone; | 144 temporal_pattern_[3] = kTemporalUpdateNone; |
182 temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency; | 145 temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency; |
183 temporal_pattern_[5] = kTemporalUpdateNone; | 146 temporal_pattern_[5] = kTemporalUpdateNone; |
184 temporal_pattern_[6] = kTemporalUpdateAltref; | 147 temporal_pattern_[6] = kTemporalUpdateAltref; |
185 temporal_pattern_[7] = kTemporalUpdateNone; | 148 temporal_pattern_[7] = kTemporalUpdateNone; |
186 temporal_pattern_[8] = kTemporalUpdateLast; | 149 temporal_pattern_[8] = kTemporalUpdateLast; |
187 temporal_pattern_[9] = kTemporalUpdateNone; | 150 temporal_pattern_[9] = kTemporalUpdateNone; |
188 temporal_pattern_[10] = kTemporalUpdateAltref; | 151 temporal_pattern_[10] = kTemporalUpdateAltref; |
189 temporal_pattern_[11] = kTemporalUpdateNone; | 152 temporal_pattern_[11] = kTemporalUpdateNone; |
190 temporal_pattern_[12] = kTemporalUpdateGolden; | 153 temporal_pattern_[12] = kTemporalUpdateGolden; |
191 temporal_pattern_[13] = kTemporalUpdateNone; | 154 temporal_pattern_[13] = kTemporalUpdateNone; |
192 temporal_pattern_[14] = kTemporalUpdateAltref; | 155 temporal_pattern_[14] = kTemporalUpdateAltref; |
193 temporal_pattern_[15] = kTemporalUpdateNone; | 156 temporal_pattern_[15] = kTemporalUpdateNone; |
194 break; | 157 break; |
195 default: | 158 default: |
196 RTC_NOTREACHED(); | 159 assert(false); |
197 return false; | 160 return false; |
198 } | 161 } |
199 | |
200 new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(); | |
201 | |
202 return true; | 162 return true; |
203 } | 163 } |
204 | 164 |
205 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { | 165 int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { |
206 assert(number_of_temporal_layers_ > 0); | 166 assert(number_of_temporal_layers_ > 0); |
207 assert(kMaxTemporalPattern >= temporal_pattern_length_); | 167 assert(kMaxTemporalPattern >= temporal_pattern_length_); |
208 assert(0 < temporal_pattern_length_); | 168 assert(0 < temporal_pattern_length_); |
209 int flags = 0; | 169 int flags = 0; |
210 int patternIdx = ++pattern_idx_ % temporal_pattern_length_; | 170 int patternIdx = ++pattern_idx_ % temporal_pattern_length_; |
211 assert(kMaxTemporalPattern >= patternIdx); | 171 assert(kMaxTemporalPattern >= patternIdx); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { | 277 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { |
318 timestamp_ = timestamp; | 278 timestamp_ = timestamp; |
319 tl0_pic_idx_++; | 279 tl0_pic_idx_++; |
320 } | 280 } |
321 last_base_layer_sync_ = base_layer_sync; | 281 last_base_layer_sync_ = base_layer_sync; |
322 vp8_info->tl0PicIdx = tl0_pic_idx_; | 282 vp8_info->tl0PicIdx = tl0_pic_idx_; |
323 } | 283 } |
324 } | 284 } |
325 | 285 |
326 TemporalLayers* TemporalLayersFactory::Create( | 286 TemporalLayers* TemporalLayersFactory::Create( |
327 int simulcast_id, | |
328 int temporal_layers, | 287 int temporal_layers, |
329 uint8_t initial_tl0_pic_idx) const { | 288 uint8_t initial_tl0_pic_idx) const { |
330 TemporalLayers* tl = | 289 return new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); |
331 new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); | |
332 if (listener_) | |
333 listener_->OnTemporalLayersCreated(simulcast_id, tl); | |
334 return tl; | |
335 } | 290 } |
336 | |
337 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { | |
338 listener_ = listener; | |
339 } | |
340 | |
341 } // namespace webrtc | 291 } // namespace webrtc |
OLD | NEW |