| 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 325e8a59412bfc388db3dda162bc3bd5bee0bf64..b8359ade391f158b3e8c61465230aacc027a33f2 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
|
| @@ -188,10 +245,16 @@ DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers,
|
| RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
|
| RTC_CHECK_GE(number_of_temporal_layers, 0);
|
| RTC_CHECK_LE(number_of_temporal_layers, 4);
|
| + // pattern_idx_ wraps around temporal_pattern_.size, this is incorrect if
|
| + // temporal_ids_ are ever longer. If this is no longer correct it needs to
|
| + // wrap at max(temporal_ids_.size(), temporal_pattern_.size()).
|
| + RTC_DCHECK_LE(temporal_ids_.size(), temporal_pattern_.size());
|
| }
|
|
|
| -int DefaultTemporalLayers::CurrentLayerId() const {
|
| - return temporal_ids_[pattern_idx_ % temporal_ids_.size()];
|
| +int DefaultTemporalLayers::GetTemporalLayerId(
|
| + const TemporalLayers::FrameConfig& tl_config) const {
|
| + RTC_DCHECK(!tl_config.drop_frame);
|
| + return temporal_ids_[tl_config.pattern_idx % temporal_ids_.size()];
|
| }
|
|
|
| uint8_t DefaultTemporalLayers::Tl0PicIdx() const {
|
| @@ -248,16 +311,19 @@ bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
|
| return true;
|
| }
|
|
|
| -// TODO(pbos): Name method so that it's obvious that it updates state.
|
| -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()];
|
| + pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size();
|
| + TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_];
|
| + tl_config.pattern_idx = pattern_idx_;
|
| + return tl_config;
|
| }
|
|
|
| void DefaultTemporalLayers::PopulateCodecSpecific(
|
| bool frame_is_keyframe,
|
| + const TemporalLayers::FrameConfig& tl_config,
|
| CodecSpecificInfoVP8* vp8_info,
|
| uint32_t timestamp) {
|
| RTC_DCHECK_GT(num_layers_, 0);
|
| @@ -271,11 +337,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
|
|
|