diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc index b84084080..ad8a98825 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc +++ b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc @@ -28,7 +28,8 @@ TemporalLayers::TemporalLayers(int numberOfTemporalLayers) temporal_pattern_length_(0), tl0_pic_idx_(rand()), pattern_idx_(255), - timestamp_(0) { + timestamp_(0), + last_base_layer_sync_(false) { assert(kMaxTemporalStreams >= numberOfTemporalLayers); memset(temporal_ids_, 0, sizeof(temporal_ids_)); memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); @@ -214,35 +215,41 @@ int TemporalLayers::EncodeFlags() { return flags; } -void TemporalLayers::PopulateCodecSpecific(bool key_frame, +void TemporalLayers::PopulateCodecSpecific(bool base_layer_sync, CodecSpecificInfoVP8 *vp8_info, uint32_t timestamp) { assert(number_of_temporal_layers_ > 1); assert(0 < temporal_ids_length_); - if (key_frame) { - // Keyframe is always temporal layer 0 + if (base_layer_sync) { vp8_info->temporalIdx = 0; - } else { - vp8_info->temporalIdx = temporal_ids_[pattern_idx_ % temporal_ids_length_]; - } - TemporalReferences temporal_reference = - temporal_pattern_[pattern_idx_ % temporal_pattern_length_]; - - if (temporal_reference == kTemporalUpdateAltrefWithoutDependency || - temporal_reference == kTemporalUpdateGoldenWithoutDependency || - temporal_reference == kTemporalUpdateGoldenWithoutDependencyRefAltRef || - temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef || - (temporal_reference == kTemporalUpdateNone && - number_of_temporal_layers_ == 4)) { vp8_info->layerSync = true; } else { - vp8_info->layerSync = false; + vp8_info->temporalIdx = temporal_ids_[pattern_idx_ % temporal_ids_length_]; + TemporalReferences temporal_reference = + temporal_pattern_[pattern_idx_ % temporal_pattern_length_]; + + if (temporal_reference == kTemporalUpdateAltrefWithoutDependency || + temporal_reference == kTemporalUpdateGoldenWithoutDependency || + temporal_reference == kTemporalUpdateGoldenWithoutDependencyRefAltRef || + temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef || + (temporal_reference == kTemporalUpdateNone && + number_of_temporal_layers_ == 4)) { + vp8_info->layerSync = true; + } else { + vp8_info->layerSync = false; + } + } + if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { + // Regardless of pattern the frame after a base layer sync will always + // be a layer sync. + vp8_info->layerSync = true; } if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) { timestamp_ = timestamp; tl0_pic_idx_++; } + last_base_layer_sync_ = base_layer_sync; vp8_info->tl0PicIdx = tl0_pic_idx_; } } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h index fd061911e..c1366b59f 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h +++ b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h @@ -31,7 +31,8 @@ class TemporalLayers { bool ConfigureBitrates(int bitrate_kbit, vpx_codec_enc_cfg_t* cfg); - void PopulateCodecSpecific(bool key_frame, CodecSpecificInfoVP8 *vp8_info, + void PopulateCodecSpecific(bool base_layer_sync, + CodecSpecificInfoVP8* vp8_info, uint32_t timestamp); private: @@ -75,6 +76,7 @@ class TemporalLayers { uint8_t tl0_pic_idx_; uint8_t pattern_idx_; uint32_t timestamp_; + bool last_base_layer_sync_; }; } // namespace webrtc #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc index 153a3a21f..5c57319fc 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc @@ -195,19 +195,16 @@ TEST(TemporalLayersTest, KeyFrame) { int expected_temporal_idx[8] = { 0, 0, 0, 0, 0, 0, 0, 2}; - bool expected_layer_sync[8] = - { false, true, true, false, false, false, false, false }; - for (int i = 0; i < 7; ++i) { EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); tl.PopulateCodecSpecific(true, &vp8_info, 0); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); - EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); + EXPECT_EQ(true, vp8_info.layerSync); } EXPECT_EQ(expected_flags[7], tl.EncodeFlags()); tl.PopulateCodecSpecific(false, &vp8_info, 0); EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx); - EXPECT_EQ(expected_layer_sync[7], vp8_info.layerSync); + EXPECT_EQ(true, vp8_info.layerSync); } } // namespace webrtc