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