1/* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2* 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 5* tree. An additional intellectual property rights grant can be found 6* in the file PATENTS. All contributing project authors may 7* be found in the AUTHORS file in the root of the source tree. 8*/ 9 10#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" 11 12#include <assert.h> 13#include <stdlib.h> 14#include <string.h> 15 16#include "webrtc/modules/interface/module_common_types.h" 17#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" 18#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" 19 20#include "vpx/vpx_encoder.h" 21#include "vpx/vp8cx.h" 22 23namespace webrtc { 24 25DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers, 26 uint8_t initial_tl0_pic_idx) 27 : number_of_temporal_layers_(numberOfTemporalLayers), 28 temporal_ids_length_(0), 29 temporal_pattern_length_(0), 30 tl0_pic_idx_(initial_tl0_pic_idx), 31 pattern_idx_(255), 32 timestamp_(0), 33 last_base_layer_sync_(false) { 34 assert(kMaxTemporalStreams >= numberOfTemporalLayers); 35 memset(temporal_ids_, 0, sizeof(temporal_ids_)); 36 memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); 37} 38 39int DefaultTemporalLayers::CurrentLayerId() const { 40 assert(temporal_ids_length_ > 0); 41 int index = pattern_idx_ % temporal_ids_length_; 42 assert(index >= 0); 43 return temporal_ids_[index]; 44 } 45 46bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit, 47 int max_bitrate_kbit, 48 int framerate, 49 vpx_codec_enc_cfg_t* cfg) { 50 switch (number_of_temporal_layers_) { 51 case 0: 52 case 1: 53 temporal_ids_length_ = 1; 54 temporal_ids_[0] = 0; 55 cfg->ts_number_layers = number_of_temporal_layers_; 56 cfg->ts_periodicity = temporal_ids_length_; 57 cfg->ts_target_bitrate[0] = bitrateKbit; 58 cfg->ts_rate_decimator[0] = 1; 59 memcpy(cfg->ts_layer_id, 60 temporal_ids_, 61 sizeof(unsigned int) * temporal_ids_length_); 62 temporal_pattern_length_ = 1; 63 temporal_pattern_[0] = kTemporalUpdateLastRefAll; 64 break; 65 case 2: 66 temporal_ids_length_ = 2; 67 temporal_ids_[0] = 0; 68 temporal_ids_[1] = 1; 69 cfg->ts_number_layers = number_of_temporal_layers_; 70 cfg->ts_periodicity = temporal_ids_length_; 71 // Split stream 60% 40%. 72 // Bitrate API for VP8 is the agregated bitrate for all lower layers. 73 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[1][0]; 74 cfg->ts_target_bitrate[1] = bitrateKbit; 75 cfg->ts_rate_decimator[0] = 2; 76 cfg->ts_rate_decimator[1] = 1; 77 memcpy(cfg->ts_layer_id, 78 temporal_ids_, 79 sizeof(unsigned int) * temporal_ids_length_); 80 temporal_pattern_length_ = 8; 81 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; 82 temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; 83 temporal_pattern_[2] = kTemporalUpdateLastRefAltRef; 84 temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef; 85 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; 86 temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef; 87 temporal_pattern_[6] = kTemporalUpdateLastRefAltRef; 88 temporal_pattern_[7] = kTemporalUpdateNone; 89 break; 90 case 3: 91 temporal_ids_length_ = 4; 92 temporal_ids_[0] = 0; 93 temporal_ids_[1] = 2; 94 temporal_ids_[2] = 1; 95 temporal_ids_[3] = 2; 96 cfg->ts_number_layers = number_of_temporal_layers_; 97 cfg->ts_periodicity = temporal_ids_length_; 98 // Split stream 40% 20% 40%. 99 // Bitrate API for VP8 is the agregated bitrate for all lower layers. 100 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[2][0]; 101 cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[2][1]; 102 cfg->ts_target_bitrate[2] = bitrateKbit; 103 cfg->ts_rate_decimator[0] = 4; 104 cfg->ts_rate_decimator[1] = 2; 105 cfg->ts_rate_decimator[2] = 1; 106 memcpy(cfg->ts_layer_id, 107 temporal_ids_, 108 sizeof(unsigned int) * temporal_ids_length_); 109 temporal_pattern_length_ = 8; 110 temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef; 111 temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef; 112 temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef; 113 temporal_pattern_[3] = kTemporalUpdateNone; 114 temporal_pattern_[4] = kTemporalUpdateLastRefAltRef; 115 temporal_pattern_[5] = kTemporalUpdateNone; 116 temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef; 117 temporal_pattern_[7] = kTemporalUpdateNone; 118 break; 119 case 4: 120 temporal_ids_length_ = 8; 121 temporal_ids_[0] = 0; 122 temporal_ids_[1] = 3; 123 temporal_ids_[2] = 2; 124 temporal_ids_[3] = 3; 125 temporal_ids_[4] = 1; 126 temporal_ids_[5] = 3; 127 temporal_ids_[6] = 2; 128 temporal_ids_[7] = 3; 129 // Split stream 25% 15% 20% 40%. 130 // Bitrate API for VP8 is the agregated bitrate for all lower layers. 131 cfg->ts_number_layers = 4; 132 cfg->ts_periodicity = temporal_ids_length_; 133 cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[3][0]; 134 cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[3][1]; 135 cfg->ts_target_bitrate[2] = bitrateKbit * kVp8LayerRateAlloction[3][2]; 136 cfg->ts_target_bitrate[3] = bitrateKbit; 137 cfg->ts_rate_decimator[0] = 8; 138 cfg->ts_rate_decimator[1] = 4; 139 cfg->ts_rate_decimator[2] = 2; 140 cfg->ts_rate_decimator[3] = 1; 141 memcpy(cfg->ts_layer_id, 142 temporal_ids_, 143 sizeof(unsigned int) * temporal_ids_length_); 144 temporal_pattern_length_ = 16; 145 temporal_pattern_[0] = kTemporalUpdateLast; 146 temporal_pattern_[1] = kTemporalUpdateNone; 147 temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency; 148 temporal_pattern_[3] = kTemporalUpdateNone; 149 temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency; 150 temporal_pattern_[5] = kTemporalUpdateNone; 151 temporal_pattern_[6] = kTemporalUpdateAltref; 152 temporal_pattern_[7] = kTemporalUpdateNone; 153 temporal_pattern_[8] = kTemporalUpdateLast; 154 temporal_pattern_[9] = kTemporalUpdateNone; 155 temporal_pattern_[10] = kTemporalUpdateAltref; 156 temporal_pattern_[11] = kTemporalUpdateNone; 157 temporal_pattern_[12] = kTemporalUpdateGolden; 158 temporal_pattern_[13] = kTemporalUpdateNone; 159 temporal_pattern_[14] = kTemporalUpdateAltref; 160 temporal_pattern_[15] = kTemporalUpdateNone; 161 break; 162 default: 163 assert(false); 164 return false; 165 } 166 return true; 167} 168 169int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { 170 assert(number_of_temporal_layers_ > 0); 171 assert(kMaxTemporalPattern >= temporal_pattern_length_); 172 assert(0 < temporal_pattern_length_); 173 int flags = 0; 174 int patternIdx = ++pattern_idx_ % temporal_pattern_length_; 175 assert(kMaxTemporalPattern >= patternIdx); 176 switch (temporal_pattern_[patternIdx]) { 177 case kTemporalUpdateLast: 178 flags |= VP8_EFLAG_NO_UPD_GF; 179 flags |= VP8_EFLAG_NO_UPD_ARF; 180 flags |= VP8_EFLAG_NO_REF_GF; 181 flags |= VP8_EFLAG_NO_REF_ARF; 182 break; 183 case kTemporalUpdateGoldenWithoutDependency: 184 flags |= VP8_EFLAG_NO_REF_GF; 185 // Deliberately no break here. 186 case kTemporalUpdateGolden: 187 flags |= VP8_EFLAG_NO_REF_ARF; 188 flags |= VP8_EFLAG_NO_UPD_ARF; 189 flags |= VP8_EFLAG_NO_UPD_LAST; 190 break; 191 case kTemporalUpdateAltrefWithoutDependency: 192 flags |= VP8_EFLAG_NO_REF_ARF; 193 flags |= VP8_EFLAG_NO_REF_GF; 194 // Deliberately no break here. 195 case kTemporalUpdateAltref: 196 flags |= VP8_EFLAG_NO_UPD_GF; 197 flags |= VP8_EFLAG_NO_UPD_LAST; 198 break; 199 case kTemporalUpdateNoneNoRefAltref: 200 flags |= VP8_EFLAG_NO_REF_ARF; 201 // Deliberately no break here. 202 case kTemporalUpdateNone: 203 flags |= VP8_EFLAG_NO_UPD_GF; 204 flags |= VP8_EFLAG_NO_UPD_ARF; 205 flags |= VP8_EFLAG_NO_UPD_LAST; 206 flags |= VP8_EFLAG_NO_UPD_ENTROPY; 207 break; 208 case kTemporalUpdateNoneNoRefGoldenRefAltRef: 209 flags |= VP8_EFLAG_NO_REF_GF; 210 flags |= VP8_EFLAG_NO_UPD_GF; 211 flags |= VP8_EFLAG_NO_UPD_ARF; 212 flags |= VP8_EFLAG_NO_UPD_LAST; 213 flags |= VP8_EFLAG_NO_UPD_ENTROPY; 214 break; 215 case kTemporalUpdateGoldenWithoutDependencyRefAltRef: 216 flags |= VP8_EFLAG_NO_REF_GF; 217 flags |= VP8_EFLAG_NO_UPD_ARF; 218 flags |= VP8_EFLAG_NO_UPD_LAST; 219 break; 220 case kTemporalUpdateLastRefAltRef: 221 flags |= VP8_EFLAG_NO_UPD_GF; 222 flags |= VP8_EFLAG_NO_UPD_ARF; 223 flags |= VP8_EFLAG_NO_REF_GF; 224 break; 225 case kTemporalUpdateGoldenRefAltRef: 226 flags |= VP8_EFLAG_NO_UPD_ARF; 227 flags |= VP8_EFLAG_NO_UPD_LAST; 228 break; 229 case kTemporalUpdateLastAndGoldenRefAltRef: 230 flags |= VP8_EFLAG_NO_UPD_ARF; 231 flags |= VP8_EFLAG_NO_REF_GF; 232 break; 233 case kTemporalUpdateLastRefAll: 234 flags |= VP8_EFLAG_NO_UPD_ARF; 235 flags |= VP8_EFLAG_NO_UPD_GF; 236 break; 237 } 238 return flags; 239} 240 241void DefaultTemporalLayers::PopulateCodecSpecific( 242 bool base_layer_sync, 243 CodecSpecificInfoVP8 *vp8_info, 244 uint32_t timestamp) { 245 assert(number_of_temporal_layers_ > 0); 246 assert(0 < temporal_ids_length_); 247 248 if (number_of_temporal_layers_ == 1) { 249 vp8_info->temporalIdx = kNoTemporalIdx; 250 vp8_info->layerSync = false; 251 vp8_info->tl0PicIdx = kNoTl0PicIdx; 252 } else { 253 if (base_layer_sync) { 254 vp8_info->temporalIdx = 0; 255 vp8_info->layerSync = true; 256 } else { 257 vp8_info->temporalIdx = CurrentLayerId(); 258 TemporalReferences temporal_reference = 259 temporal_pattern_[pattern_idx_ % temporal_pattern_length_]; 260 261 if (temporal_reference == kTemporalUpdateAltrefWithoutDependency || 262 temporal_reference == kTemporalUpdateGoldenWithoutDependency || 263 temporal_reference == 264 kTemporalUpdateGoldenWithoutDependencyRefAltRef || 265 temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef || 266 (temporal_reference == kTemporalUpdateNone && 267 number_of_temporal_layers_ == 4)) { 268 vp8_info->layerSync = true; 269 } else { 270 vp8_info->layerSync = false; 271 } 272 } 273 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { 274 // Regardless of pattern the frame after a base layer sync will always 275 // be a layer sync. 276 vp8_info->layerSync = true; 277 } 278 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { 279 timestamp_ = timestamp; 280 tl0_pic_idx_++; 281 } 282 last_base_layer_sync_ = base_layer_sync; 283 vp8_info->tl0PicIdx = tl0_pic_idx_; 284 } 285} 286 287TemporalLayers* TemporalLayers::Factory::Create( 288 int temporal_layers, 289 uint8_t initial_tl0_pic_idx) const { 290 return new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); 291} 292} // namespace webrtc 293