Set inter_pic_predicted video codec flag in vp9 encoder correctly

This flag only needs to be set in kOn interlayer prediction mode, because
in all others, if new layer is enabled - a keyframe is generated.

Also, use external reference control in that case, because libvpx creates
rtp-incompatible references in that case.

Bug: webrtc:10180
Change-Id: I0fad188fa8cd424f831bac219769dbad3a788b1d
Reviewed-on: https://webrtc-review.googlesource.com/c/118041
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26316}
This commit is contained in:
Ilya Nikolaevskiy
2019-01-18 11:56:48 +01:00
committed by Commit Bot
parent baaf911c80
commit 2ec0c650e9
4 changed files with 289 additions and 39 deletions

View File

@ -574,6 +574,224 @@ TEST_F(TestVp9Impl,
}
}
TEST_F(TestVp9Impl,
EnablingUpperLayerUnsetsInterPicPredictedInInterlayerPredModeOn) {
const size_t num_spatial_layers = 3;
const size_t num_frames_to_encode = 2;
ConfigureSvc(num_spatial_layers);
codec_settings_.VP9()->frameDroppingOn = false;
codec_settings_.VP9()->flexibleMode = false;
const std::vector<InterLayerPredMode> inter_layer_pred_modes = {
InterLayerPredMode::kOff, InterLayerPredMode::kOn,
InterLayerPredMode::kOnKeyPic};
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
VideoBitrateAllocation bitrate_allocation;
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
bitrate_allocation.SetBitrate(
sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode;
++frame_num) {
SetWaitForEncodedFramesThreshold(sl_idx + 1);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info;
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), sl_idx + 1);
for (size_t i = 0; i <= sl_idx; ++i) {
const bool is_keyframe =
encoded_frame[0]._frameType == kVideoFrameKey;
const bool is_first_upper_layer_frame =
(i == sl_idx && frame_num == 0);
// Interframe references are there, unless it's a keyframe,
// or it's a first activated frame in a upper layer
const bool expect_no_references =
is_keyframe || (is_first_upper_layer_frame &&
inter_layer_pred == InterLayerPredMode::kOn);
EXPECT_EQ(
codec_specific_info[i].codecSpecific.VP9.inter_pic_predicted,
!expect_no_references);
}
}
}
}
}
TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) {
const size_t num_spatial_layers = 2;
const size_t num_temporal_layers = 2;
ConfigureSvc(num_spatial_layers, num_temporal_layers);
codec_settings_.VP9()->frameDroppingOn = false;
codec_settings_.VP9()->flexibleMode = false;
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
VideoBitrateAllocation bitrate_allocation;
// Enable both spatial and both temporal layers.
bitrate_allocation.SetBitrate(
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
0, 1, codec_settings_.spatialLayers[0].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info;
// Encode 3 frames.
for (int i = 0; i < 3; ++i) {
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 2u);
}
// Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(1);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 1u);
EXPECT_EQ(encoded_frame[0]._frameType, kVideoFrameDelta);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 1);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.inter_pic_predicted, true);
// Enable SL1 layer.
bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 2u);
EXPECT_EQ(encoded_frame[0]._frameType, kVideoFrameDelta);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 0);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.inter_pic_predicted, true);
EXPECT_EQ(codec_specific_info[1].codecSpecific.VP9.inter_pic_predicted, true);
}
TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) {
const size_t num_spatial_layers = 2;
const size_t num_temporal_layers = 2;
ConfigureSvc(num_spatial_layers, num_temporal_layers);
codec_settings_.VP9()->frameDroppingOn = false;
codec_settings_.VP9()->flexibleMode = false;
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
VideoBitrateAllocation bitrate_allocation;
// Enable both spatial and both temporal layers.
bitrate_allocation.SetBitrate(
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
0, 1, codec_settings_.spatialLayers[0].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info;
// Encode 3 frames.
for (int i = 0; i < 3; ++i) {
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 2u);
}
// Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 11 frames. More than Gof length 2, and odd to end at TL1 frame.
for (int i = 0; i < 11; ++i) {
SetWaitForEncodedFramesThreshold(1);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 1u);
EXPECT_EQ(encoded_frame[0]._frameType, kVideoFrameDelta);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 1 - i % 2);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.inter_pic_predicted,
true);
}
// Enable SL1 layer.
bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr, nullptr));
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
ASSERT_EQ(codec_specific_info.size(), 2u);
EXPECT_EQ(encoded_frame[0]._frameType, kVideoFrameDelta);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 0);
EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.inter_pic_predicted, true);
EXPECT_EQ(codec_specific_info[1].codecSpecific.VP9.inter_pic_predicted,
false);
}
TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
const size_t num_spatial_layers = 3;
// Chosen by hand, the 2nd frame is dropped with configured per-layer max

View File

@ -452,15 +452,12 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
config_->rc_buf_sz = 1000;
// Set the maximum target size of any key-frame.
rc_max_intra_target_ = MaxIntraTarget(config_->rc_buf_optimal_sz);
if (inst->VP9().keyFrameInterval > 0) {
config_->kf_mode = VPX_KF_AUTO;
config_->kf_max_dist = inst->VP9().keyFrameInterval;
// Needs to be set (in svc mode) to get correct periodic key frame interval
// (will have no effect in non-svc).
config_->kf_min_dist = config_->kf_max_dist;
} else {
config_->kf_mode = VPX_KF_DISABLED;
}
// Key-frame interval is enforced manually by this wrapper.
config_->kf_mode = VPX_KF_DISABLED;
// TODO(webm:1592): work-around for libvpx issue, as it can still
// put some key-frames at will even in VPX_KF_DISABLED kf_mode.
config_->kf_max_dist = inst->VP9().keyFrameInterval;
config_->kf_min_dist = config_->kf_max_dist;
config_->rc_resize_allowed = inst->VP9().automaticResizeOn ? 1 : 0;
// Determine number of threads based on the image size and #cores.
config_->g_threads =
@ -489,7 +486,8 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
// External reference control is required for different frame rate on spatial
// layers because libvpx generates rtp incompatible references in this case.
external_ref_control_ = field_trial::IsEnabled("WebRTC-Vp9ExternalRefCtrl") ||
different_framerates_used_;
different_framerates_used_ ||
inter_layer_pred_ == InterLayerPredMode::kOn;
if (num_temporal_layers_ == 1) {
gof_.SetGofInfoVP9(kTemporalStructureMode1);
@ -733,6 +731,11 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
}
}
if (pics_since_key_ + 1 ==
static_cast<size_t>(codec_.VP9()->keyFrameInterval)) {
force_key_frame_ = true;
}
vpx_svc_layer_id_t layer_id = {0};
if (!force_key_frame_) {
const size_t gof_idx = (pics_since_key_ + 1) % gof_.num_frames_in_gof;
@ -921,6 +924,9 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
vpx_svc_layer_id_t layer_id = {0};
vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
// Can't have keyframe with non-zero temporal layer.
RTC_DCHECK(pics_since_key_ != 0 || layer_id.temporal_layer_id == 0);
if (ss_info_needed_ && layer_id.temporal_layer_id == 0 &&
layer_id.spatial_layer_id == 0) {
// Force SS info after the layers configuration has changed.
@ -976,15 +982,16 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
vp9_info->num_spatial_layers = num_active_spatial_layers_;
vp9_info->num_ref_pics = 0;
FillReferenceIndices(pkt, pics_since_key_, vp9_info->inter_layer_predicted,
vp9_info);
if (vp9_info->flexible_mode) {
vp9_info->gof_idx = kNoGofIdx;
FillReferenceIndices(pkt, pics_since_key_, vp9_info->inter_layer_predicted,
vp9_info);
} else {
vp9_info->gof_idx =
static_cast<uint8_t>(pics_since_key_ % gof_.num_frames_in_gof);
vp9_info->temporal_up_switch = gof_.temporal_up_switch[vp9_info->gof_idx];
vp9_info->num_ref_pics = gof_.num_ref_pics[vp9_info->gof_idx];
RTC_DCHECK(vp9_info->num_ref_pics == gof_.num_ref_pics[vp9_info->gof_idx] ||
vp9_info->num_ref_pics == 0);
}
vp9_info->inter_pic_predicted = (!is_key_pic && vp9_info->num_ref_pics > 0);
@ -1133,7 +1140,6 @@ void VP9EncoderImpl::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt,
ref_buf_[i] = frame_buf;
}
}
} else {
RTC_DCHECK_EQ(num_spatial_layers_, 1);
RTC_DCHECK_EQ(num_temporal_layers_, 1);
@ -1284,9 +1290,7 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
input_image_->timestamp());
encoded_image_.SetSpatialIndex(spatial_index);
if (is_flexible_mode_) {
UpdateReferenceBuffers(*pkt, pics_since_key_);
}
UpdateReferenceBuffers(*pkt, pics_since_key_);
TRACE_COUNTER1("webrtc", "EncodedFrameSize", encoded_image_.size());
encoded_image_.SetTimestamp(input_image_->timestamp());

View File

@ -562,6 +562,11 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9(
}
}
// Override GOF references.
if (!codec_header.inter_pic_predicted) {
frame->num_references = 0;
}
UnwrapPictureIds(frame);
return kHandOff;
}

View File

@ -135,6 +135,7 @@ class TestRtpFrameReferenceFinder : public ::testing::Test,
uint8_t tid = kNoTemporalIdx,
int32_t tl0 = kNoTl0PicIdx,
bool up_switch = false,
bool inter_pic_predicted = true,
GofInfoVP9* ss = nullptr) {
VCMPacket packet;
auto& vp9_header =
@ -150,6 +151,7 @@ class TestRtpFrameReferenceFinder : public ::testing::Test,
vp9_header.spatial_idx = sid;
vp9_header.tl0_pic_idx = tl0;
vp9_header.temporal_up_switch = up_switch;
vp9_header.inter_pic_predicted = inter_pic_predicted && !keyframe;
if (ss != nullptr) {
vp9_header.ss_data_available = true;
vp9_header.gof = *ss;
@ -713,7 +715,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode1);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
CheckReferencesVp9(0, 0);
}
@ -751,7 +753,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode1); // Only 1 spatial layer.
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
@ -795,6 +797,27 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) {
CheckReferencesVp9(19, 0, 18);
}
TEST_F(TestRtpFrameReferenceFinder, Vp9GofSpatialLayers_2) {
uint16_t pid = Rand();
uint16_t sn = Rand();
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode1); // Only 1 spatial layer.
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false, true);
// Not inter_pic_predicted because it's the first frame with this layer.
InsertVp9Gof(sn + 2, sn + 2, false, pid + 1, 1, 0, 1, false, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 2, 0, 0, 1, false, true);
InsertVp9Gof(sn + 4, sn + 4, false, pid + 2, 1, 0, 1, false, true);
ASSERT_EQ(5UL, frames_from_callback_.size());
CheckReferencesVp9(0, 0);
CheckReferencesVp9(1, 0, 0);
CheckReferencesVp9(1, 1);
CheckReferencesVp9(2, 0, 1);
CheckReferencesVp9(2, 1, 1);
}
TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) {
uint16_t pid = Rand();
uint16_t sn = Rand();
@ -803,7 +826,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) {
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 4, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 0, 5, false);
@ -851,14 +874,14 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_01) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode2); // 0101 pattern
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
// Skip GOF with tl0 1
InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 2, false, &ss);
InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 2, false, true, &ss);
InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
// Skip GOF with tl0 3
// Skip GOF with tl0 4
InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false, &ss);
InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false, true, &ss);
InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
ASSERT_EQ(6UL, frames_from_callback_.size());
@ -876,7 +899,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode3); // 02120212 pattern
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
@ -889,7 +912,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) {
// Skip frames with tl0 = 1
InsertVp9Gof(sn + 8, sn + 8, true, pid + 8, 0, 0, 2, false, &ss);
InsertVp9Gof(sn + 8, sn + 8, true, pid + 8, 0, 0, 2, false, false, &ss);
InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
@ -901,7 +924,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) {
CheckReferencesVp9(11, 0, 10);
// Now insert frames with tl0 = 1
InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, &ss);
InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, true, &ss);
InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
ASSERT_EQ(9UL, frames_from_callback_.size());
@ -923,7 +946,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_01) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode2); // 0101 pattern
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
@ -974,7 +997,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01) {
ss.SetGofInfoVP9(kTemporalStructureMode2); // 01 pattern
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
@ -1023,7 +1046,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0212) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode3); // 0212 pattern
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
@ -1075,7 +1098,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) {
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, false);
InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
@ -1123,7 +1146,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode4); // 02120212 pattern
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
@ -1167,7 +1190,7 @@ TEST_F(TestRtpFrameReferenceFinder,
ss.SetGofInfoVP9(kTemporalStructureMode4); // 02120212 pattern
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
@ -1209,11 +1232,11 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01_0212) {
ss.SetGofInfoVP9(kTemporalStructureMode2); // 01 pattern
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 2, false);
ss.SetGofInfoVP9(kTemporalStructureMode3); // 0212 pattern
InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false, &ss);
InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false, true, &ss);
InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 2, false);
InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 3, false);
@ -1332,7 +1355,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofPidJump) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode3);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1000, 0, 0, 1);
}
@ -1342,8 +1365,8 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTl0Jump) {
GofInfoVP9 ss;
ss.SetGofInfoVP9(kTemporalStructureMode3);
InsertVp9Gof(sn, sn, true, pid + 0, 0, 0, 125, true, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid + 0, 0, 0, 125, true, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 0, false, true, &ss);
}
TEST_F(TestRtpFrameReferenceFinder, Vp9GofTidTooHigh) {
@ -1355,7 +1378,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTidTooHigh) {
ss.SetGofInfoVP9(kTemporalStructureMode2);
ss.temporal_idx[1] = kMaxTemporalLayers;
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1);
ASSERT_EQ(1UL, frames_from_callback_.size());
@ -1368,7 +1391,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofZeroFrames) {
GofInfoVP9 ss;
ss.num_frames_in_gof = 0;
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1);
ASSERT_EQ(2UL, frames_from_callback_.size());