Chromium Code Reviews| Index: webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc |
| diff --git a/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc |
| index 30374a3b33cabb629974aabbd1c2a5dea7c576e4..408daa05c9442624cff8f1ddfb696a84ca9f5470 100644 |
| --- a/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc |
| +++ b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc |
| @@ -25,27 +25,31 @@ |
| namespace webrtc { |
| -TemporalReferences::TemporalReferences(TemporalBufferFlags last, |
| - TemporalBufferFlags golden, |
| - TemporalBufferFlags arf) |
| - : TemporalReferences(last, golden, arf, false, false) {} |
| - |
| -TemporalReferences::TemporalReferences(TemporalBufferFlags last, |
| - TemporalBufferFlags golden, |
| - TemporalBufferFlags arf, |
| - int extra_flags) |
| - : TemporalReferences(last, |
| - golden, |
| - arf, |
| - (extra_flags & kLayerSync) != 0, |
| - (extra_flags & kFreezeEntropy) != 0) {} |
| - |
| -TemporalReferences::TemporalReferences(TemporalBufferFlags last, |
| - TemporalBufferFlags golden, |
| - TemporalBufferFlags arf, |
| - bool layer_sync, |
| - bool freeze_entropy) |
| - : drop_frame(last == kNone && golden == kNone && arf == kNone), |
| +TemporalLayers::FrameConfig::FrameConfig() {} |
| + |
| +TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, |
| + TemporalLayers::BufferFlags golden, |
| + TemporalLayers::BufferFlags arf) |
| + : FrameConfig(last, golden, arf, false, false) {} |
| + |
| +TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, |
| + TemporalLayers::BufferFlags golden, |
| + TemporalLayers::BufferFlags arf, |
| + int extra_flags) |
| + : FrameConfig(last, |
| + golden, |
| + arf, |
| + (extra_flags & kLayerSync) != 0, |
| + (extra_flags & kFreezeEntropy) != 0) {} |
| + |
| +TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, |
| + TemporalLayers::BufferFlags golden, |
| + TemporalLayers::BufferFlags arf, |
| + bool layer_sync, |
| + bool freeze_entropy) |
| + : drop_frame(last == TemporalLayers::kNone && |
| + golden == TemporalLayers::kNone && |
| + arf == TemporalLayers::kNone), |
| last_buffer_flags(last), |
| golden_buffer_flags(golden), |
| arf_buffer_flags(arf), |
| @@ -86,8 +90,7 @@ std::vector<unsigned int> GetTemporalIds(size_t num_layers) { |
| return {0}; |
| } |
| -std::vector<TemporalReferences> GetTemporalPattern( |
| - size_t num_layers) { |
| +std::vector<TemporalLayers::FrameConfig> GetTemporalPattern(size_t num_layers) { |
| // For indexing in the patterns described below (which temporal layers they |
| // belong to), see the diagram above. |
| // Layer sync is done similarly for all patterns (except single stream) and |
| @@ -104,74 +107,128 @@ std::vector<TemporalReferences> GetTemporalPattern( |
| switch (num_layers) { |
| case 1: |
| // All frames reference all buffers and the 'last' buffer is updated. |
| - return {TemporalReferences(kReferenceAndUpdate, kReference, kReference)}; |
| + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kReference, |
| + TemporalLayers::kReference)}; |
| case 2: |
| // All layers can reference but not update the 'alt' buffer, this means |
| // that the 'alt' buffer reference is effectively the last keyframe. |
| // TL0 also references and updates the 'last' buffer. |
| // TL1 also references 'last' and references and updates 'golden'. |
| - return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference), |
| - TemporalReferences(kReference, kUpdate, kReference, kLayerSync), |
| - TemporalReferences(kReferenceAndUpdate, kNone, kReference), |
| - TemporalReferences(kReference, kReferenceAndUpdate, kReference), |
| - TemporalReferences(kReferenceAndUpdate, kNone, kReference), |
| - TemporalReferences(kReference, kReferenceAndUpdate, kReference), |
| - TemporalReferences(kReferenceAndUpdate, kNone, kReference), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kFreezeEntropy)}; |
| + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kUpdate, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kUpdate, |
| + TemporalLayers::kReference, kLayerSync), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kFreezeEntropy)}; |
| case 3: |
| // All layers can reference but not update the 'alt' buffer, this means |
| // that the 'alt' buffer reference is effectively the last keyframe. |
| // TL0 also references and updates the 'last' buffer. |
| // TL1 also references 'last' and references and updates 'golden'. |
| // TL2 references both 'last' and 'golden' but updates no buffer. |
| - return {TemporalReferences(kReferenceAndUpdate, kUpdate, kReference), |
| - TemporalReferences(kReference, kNone, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kUpdate, kReference, kLayerSync), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kFreezeEntropy), |
| - TemporalReferences(kReferenceAndUpdate, kNone, kReference), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kFreezeEntropy), |
| - TemporalReferences(kReference, kReferenceAndUpdate, kReference), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kFreezeEntropy)}; |
| + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kUpdate, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kNone, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kUpdate, |
| + TemporalLayers::kReference, kLayerSync), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kReference), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kFreezeEntropy)}; |
| case 4: |
| // TL0 references and updates only the 'last' buffer. |
| // TL1 references 'last' and updates and references 'golden'. |
| // TL2 references 'last' and 'golden', and references and updates 'arf'. |
| // TL3 references all buffers but update none of them. |
| - return {TemporalReferences(kReferenceAndUpdate, kNone, kNone), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kNone, kUpdate, kLayerSync), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kUpdate, kNone, kLayerSync), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kReference, kReferenceAndUpdate), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReferenceAndUpdate, kNone, kNone), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kReference, kReferenceAndUpdate), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kReferenceAndUpdate, kNone), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy), |
| - TemporalReferences(kReference, kReference, kReferenceAndUpdate), |
| - TemporalReferences(kReference, kReference, kReference, |
| - kLayerSync | kFreezeEntropy)}; |
| + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kNone), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kUpdate, kLayerSync), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kUpdate, |
| + TemporalLayers::kNone, kLayerSync), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone, |
| + TemporalLayers::kNone), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate, |
| + TemporalLayers::kNone), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy), |
| + TemporalLayers::FrameConfig(TemporalLayers::kReference, |
| + TemporalLayers::kReference, |
| + TemporalLayers::kReferenceAndUpdate), |
| + TemporalLayers::FrameConfig( |
| + TemporalLayers::kReference, TemporalLayers::kReference, |
| + TemporalLayers::kReference, kLayerSync | kFreezeEntropy)}; |
| default: |
| RTC_NOTREACHED(); |
| break; |
| } |
| RTC_NOTREACHED(); |
| - return {TemporalReferences(kNone, kNone, kNone)}; |
| + return {TemporalLayers::FrameConfig( |
| + TemporalLayers::kNone, TemporalLayers::kNone, TemporalLayers::kNone)}; |
| } |
| } // namespace |
| @@ -190,8 +247,10 @@ DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers, |
| RTC_CHECK_LE(number_of_temporal_layers, 4); |
| } |
| -int DefaultTemporalLayers::CurrentLayerId() const { |
| - return temporal_ids_[pattern_idx_ % temporal_ids_.size()]; |
| +int DefaultTemporalLayers::GetTemporalLayerId( |
| + TemporalLayers::FrameConfig tl_config) const { |
| + RTC_DCHECK(!tl_config.drop_frame); |
| + return temporal_ids_[tl_config.pattern_idx % temporal_ids_.size()]; |
| } |
| std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated( |
| @@ -245,15 +304,20 @@ bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { |
| } |
| // TODO(pbos): Name method so that it's obvious that it updates state. |
|
sprang_webrtc
2017/05/03 15:18:43
Remove todo?
pbos-webrtc
2017/05/04 10:52:22
Done.
|
| -TemporalReferences DefaultTemporalLayers::UpdateLayerConfig( |
| +TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig( |
| uint32_t timestamp) { |
| RTC_DCHECK_GT(num_layers_, 0); |
| RTC_DCHECK_LT(0, temporal_pattern_.size()); |
| - return temporal_pattern_[++pattern_idx_ % temporal_pattern_.size()]; |
| + int pattern_idx = ++pattern_idx_; |
|
sprang_webrtc
2017/05/03 15:18:43
Is it intentional that we let pattern_idx_ go up t
pbos-webrtc
2017/05/04 10:52:22
Did as suggested (explicitly wrap). I added a DCHE
|
| + TemporalLayers::FrameConfig tl_config = |
| + temporal_pattern_[pattern_idx_ % temporal_pattern_.size()]; |
| + tl_config.pattern_idx = pattern_idx; |
| + return tl_config; |
| } |
| void DefaultTemporalLayers::PopulateCodecSpecific( |
| bool frame_is_keyframe, |
| + TemporalLayers::FrameConfig tl_config, |
| CodecSpecificInfoVP8* vp8_info, |
| uint32_t timestamp) { |
| RTC_DCHECK_GT(num_layers_, 0); |
| @@ -267,11 +331,9 @@ void DefaultTemporalLayers::PopulateCodecSpecific( |
| vp8_info->temporalIdx = 0; |
| vp8_info->layerSync = true; |
| } else { |
| - vp8_info->temporalIdx = CurrentLayerId(); |
| - TemporalReferences temporal_reference = |
| - temporal_pattern_[pattern_idx_ % temporal_pattern_.size()]; |
| + vp8_info->temporalIdx = GetTemporalLayerId(tl_config); |
| - vp8_info->layerSync = temporal_reference.layer_sync; |
| + vp8_info->layerSync = tl_config.layer_sync; |
| } |
| if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { |
| // Regardless of pattern the frame after a base layer sync will always |