| 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" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, | 42 TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, |
| 43 TemporalLayers::BufferFlags golden, | 43 TemporalLayers::BufferFlags golden, |
| 44 TemporalLayers::BufferFlags arf, | 44 TemporalLayers::BufferFlags arf, |
| 45 bool freeze_entropy) | 45 bool freeze_entropy) |
| 46 : drop_frame(last == TemporalLayers::kNone && | 46 : drop_frame(last == TemporalLayers::kNone && |
| 47 golden == TemporalLayers::kNone && | 47 golden == TemporalLayers::kNone && |
| 48 arf == TemporalLayers::kNone), | 48 arf == TemporalLayers::kNone), |
| 49 last_buffer_flags(last), | 49 last_buffer_flags(last), |
| 50 golden_buffer_flags(golden), | 50 golden_buffer_flags(golden), |
| 51 arf_buffer_flags(arf), | 51 arf_buffer_flags(arf), |
| 52 encoder_layer_id(0), |
| 53 packetizer_temporal_idx(kNoTemporalIdx), |
| 52 layer_sync(false), | 54 layer_sync(false), |
| 53 freeze_entropy(freeze_entropy), | 55 freeze_entropy(freeze_entropy) {} |
| 54 pattern_idx(0) {} | |
| 55 | 56 |
| 56 namespace { | 57 namespace { |
| 57 | 58 |
| 58 std::vector<unsigned int> GetTemporalIds(size_t num_layers) { | 59 std::vector<unsigned int> GetTemporalIds(size_t num_layers) { |
| 59 switch (num_layers) { | 60 switch (num_layers) { |
| 60 case 1: | 61 case 1: |
| 61 // Temporal layer structure (single layer): | 62 // Temporal layer structure (single layer): |
| 62 // 0 0 0 0 ... | 63 // 0 0 0 0 ... |
| 63 return {0}; | 64 return {0}; |
| 64 case 2: | 65 case 2: |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 } // namespace | 251 } // namespace |
| 251 | 252 |
| 252 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, | 253 DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, |
| 253 uint8_t initial_tl0_pic_idx) | 254 uint8_t initial_tl0_pic_idx) |
| 254 : num_layers_(std::max(1, number_of_temporal_layers)), | 255 : num_layers_(std::max(1, number_of_temporal_layers)), |
| 255 temporal_ids_(GetTemporalIds(num_layers_)), | 256 temporal_ids_(GetTemporalIds(num_layers_)), |
| 256 temporal_layer_sync_(GetTemporalLayerSync(num_layers_)), | 257 temporal_layer_sync_(GetTemporalLayerSync(num_layers_)), |
| 257 temporal_pattern_(GetTemporalPattern(num_layers_)), | 258 temporal_pattern_(GetTemporalPattern(num_layers_)), |
| 258 tl0_pic_idx_(initial_tl0_pic_idx), | 259 tl0_pic_idx_(initial_tl0_pic_idx), |
| 259 pattern_idx_(255), | 260 pattern_idx_(255), |
| 260 timestamp_(0), | |
| 261 last_base_layer_sync_(false) { | 261 last_base_layer_sync_(false) { |
| 262 RTC_DCHECK_EQ(temporal_pattern_.size(), temporal_layer_sync_.size()); | 262 RTC_DCHECK_EQ(temporal_pattern_.size(), temporal_layer_sync_.size()); |
| 263 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); | 263 RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers); |
| 264 RTC_CHECK_GE(number_of_temporal_layers, 0); | 264 RTC_CHECK_GE(number_of_temporal_layers, 0); |
| 265 RTC_CHECK_LE(number_of_temporal_layers, 4); | 265 RTC_CHECK_LE(number_of_temporal_layers, 4); |
| 266 // pattern_idx_ wraps around temporal_pattern_.size, this is incorrect if | 266 // pattern_idx_ wraps around temporal_pattern_.size, this is incorrect if |
| 267 // temporal_ids_ are ever longer. If this is no longer correct it needs to | 267 // temporal_ids_ are ever longer. If this is no longer correct it needs to |
| 268 // wrap at max(temporal_ids_.size(), temporal_pattern_.size()). | 268 // wrap at max(temporal_ids_.size(), temporal_pattern_.size()). |
| 269 RTC_DCHECK_LE(temporal_ids_.size(), temporal_pattern_.size()); | 269 RTC_DCHECK_LE(temporal_ids_.size(), temporal_pattern_.size()); |
| 270 } | 270 } |
| 271 | 271 |
| 272 int DefaultTemporalLayers::GetTemporalLayerId( | |
| 273 const TemporalLayers::FrameConfig& tl_config) const { | |
| 274 RTC_DCHECK(!tl_config.drop_frame); | |
| 275 return temporal_ids_[tl_config.pattern_idx % temporal_ids_.size()]; | |
| 276 } | |
| 277 | |
| 278 uint8_t DefaultTemporalLayers::Tl0PicIdx() const { | 272 uint8_t DefaultTemporalLayers::Tl0PicIdx() const { |
| 279 return tl0_pic_idx_; | 273 return tl0_pic_idx_; |
| 280 } | 274 } |
| 281 | 275 |
| 282 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( | 276 std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( |
| 283 int bitrate_kbps, | 277 int bitrate_kbps, |
| 284 int max_bitrate_kbps, | 278 int max_bitrate_kbps, |
| 285 int framerate) { | 279 int framerate) { |
| 286 std::vector<uint32_t> bitrates; | 280 std::vector<uint32_t> bitrates; |
| 287 for (size_t i = 0; i < num_layers_; ++i) { | 281 for (size_t i = 0; i < num_layers_; ++i) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 322 |
| 329 return true; | 323 return true; |
| 330 } | 324 } |
| 331 | 325 |
| 332 TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig( | 326 TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig( |
| 333 uint32_t timestamp) { | 327 uint32_t timestamp) { |
| 334 RTC_DCHECK_GT(num_layers_, 0); | 328 RTC_DCHECK_GT(num_layers_, 0); |
| 335 RTC_DCHECK_LT(0, temporal_pattern_.size()); | 329 RTC_DCHECK_LT(0, temporal_pattern_.size()); |
| 336 pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size(); | 330 pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size(); |
| 337 TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_]; | 331 TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_]; |
| 338 tl_config.pattern_idx = pattern_idx_; | 332 tl_config.layer_sync = |
| 333 temporal_layer_sync_[pattern_idx_ % temporal_layer_sync_.size()]; |
| 334 tl_config.encoder_layer_id = tl_config.packetizer_temporal_idx = |
| 335 temporal_ids_[pattern_idx_ % temporal_ids_.size()]; |
| 339 return tl_config; | 336 return tl_config; |
| 340 } | 337 } |
| 341 | 338 |
| 342 void DefaultTemporalLayers::PopulateCodecSpecific( | 339 void DefaultTemporalLayers::PopulateCodecSpecific( |
| 343 bool frame_is_keyframe, | 340 bool frame_is_keyframe, |
| 344 const TemporalLayers::FrameConfig& tl_config, | 341 const TemporalLayers::FrameConfig& tl_config, |
| 345 CodecSpecificInfoVP8* vp8_info, | 342 CodecSpecificInfoVP8* vp8_info, |
| 346 uint32_t timestamp) { | 343 uint32_t timestamp) { |
| 347 RTC_DCHECK_GT(num_layers_, 0); | 344 RTC_DCHECK_GT(num_layers_, 0); |
| 348 | 345 |
| 349 if (num_layers_ == 1) { | 346 if (num_layers_ == 1) { |
| 350 vp8_info->temporalIdx = kNoTemporalIdx; | 347 vp8_info->temporalIdx = kNoTemporalIdx; |
| 351 vp8_info->layerSync = false; | 348 vp8_info->layerSync = false; |
| 352 vp8_info->tl0PicIdx = kNoTl0PicIdx; | 349 vp8_info->tl0PicIdx = kNoTl0PicIdx; |
| 353 } else { | 350 } else { |
| 351 vp8_info->temporalIdx = tl_config.packetizer_temporal_idx; |
| 352 vp8_info->layerSync = tl_config.layer_sync; |
| 354 if (frame_is_keyframe) { | 353 if (frame_is_keyframe) { |
| 355 vp8_info->temporalIdx = 0; | 354 vp8_info->temporalIdx = 0; |
| 356 vp8_info->layerSync = true; | 355 vp8_info->layerSync = true; |
| 357 } else { | |
| 358 vp8_info->temporalIdx = GetTemporalLayerId(tl_config); | |
| 359 | |
| 360 vp8_info->layerSync = temporal_layer_sync_[tl_config.pattern_idx % | |
| 361 temporal_layer_sync_.size()]; | |
| 362 } | 356 } |
| 363 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { | 357 if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { |
| 364 // Regardless of pattern the frame after a base layer sync will always | 358 // Regardless of pattern the frame after a base layer sync will always |
| 365 // be a layer sync. | 359 // be a layer sync. |
| 366 vp8_info->layerSync = true; | 360 vp8_info->layerSync = true; |
| 367 } | 361 } |
| 368 if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { | 362 if (vp8_info->temporalIdx == 0) |
| 369 timestamp_ = timestamp; | |
| 370 tl0_pic_idx_++; | 363 tl0_pic_idx_++; |
| 371 } | |
| 372 last_base_layer_sync_ = frame_is_keyframe; | 364 last_base_layer_sync_ = frame_is_keyframe; |
| 373 vp8_info->tl0PicIdx = tl0_pic_idx_; | 365 vp8_info->tl0PicIdx = tl0_pic_idx_; |
| 374 } | 366 } |
| 375 } | 367 } |
| 376 | 368 |
| 377 TemporalLayers* TemporalLayersFactory::Create( | 369 TemporalLayers* TemporalLayersFactory::Create( |
| 378 int simulcast_id, | 370 int simulcast_id, |
| 379 int temporal_layers, | 371 int temporal_layers, |
| 380 uint8_t initial_tl0_pic_idx) const { | 372 uint8_t initial_tl0_pic_idx) const { |
| 381 TemporalLayers* tl = | 373 TemporalLayers* tl = |
| 382 new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); | 374 new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); |
| 383 if (listener_) | 375 if (listener_) |
| 384 listener_->OnTemporalLayersCreated(simulcast_id, tl); | 376 listener_->OnTemporalLayersCreated(simulcast_id, tl); |
| 385 return tl; | 377 return tl; |
| 386 } | 378 } |
| 387 | 379 |
| 388 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { | 380 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { |
| 389 listener_ = listener; | 381 listener_ = listener; |
| 390 } | 382 } |
| 391 | 383 |
| 392 } // namespace webrtc | 384 } // namespace webrtc |
| OLD | NEW |