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