Don't drop keyframes even if TemporalLayers says so.

This CL is a minimum effort/low risk fix.
Later CLs take a more thorough approach.

Bug: webrtc:9634
Change-Id: I728a061a4e71b38a559ee438646de83cd2cb3517
Reviewed-on: https://webrtc-review.googlesource.com/94760
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24326}
This commit is contained in:
Erik Språng
2018-08-17 13:21:48 +02:00
committed by Commit Bot
parent adc4879909
commit 506c569443
4 changed files with 61 additions and 4 deletions

View File

@ -55,9 +55,16 @@ class TestVp8Impl : public VideoCodecUnitTest {
void EncodeAndWaitForFrame(const VideoFrame& input_frame,
EncodedImage* encoded_frame,
CodecSpecificInfo* codec_specific_info) {
CodecSpecificInfo* codec_specific_info,
bool keyframe = false) {
std::vector<FrameType> frame_types;
if (keyframe) {
frame_types.emplace_back(FrameType::kVideoFrameKey);
} else {
frame_types.emplace_back(FrameType::kVideoFrameDelta);
}
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(input_frame, nullptr, nullptr));
encoder_->Encode(input_frame, nullptr, &frame_types));
ASSERT_TRUE(WaitForEncodedFrame(encoded_frame, codec_specific_info));
VerifyQpParser(*encoded_frame);
EXPECT_STREQ("libvpx", codec_specific_info->codec_name);
@ -66,10 +73,12 @@ class TestVp8Impl : public VideoCodecUnitTest {
}
void EncodeAndExpectFrameWith(const VideoFrame& input_frame,
uint8_t temporal_idx) {
uint8_t temporal_idx,
bool keyframe = false) {
EncodedImage encoded_frame;
CodecSpecificInfo codec_specific_info;
EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info);
EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info,
keyframe);
EXPECT_EQ(temporal_idx, codec_specific_info.codecSpecific.VP8.temporalIdx);
}
@ -330,4 +339,44 @@ TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) {
EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
}
TEST_F(TestVp8Impl, DontDropKeyframes) {
// Set very high resolution to trigger overuse more easily.
const int kScreenWidth = 1920;
const int kScreenHeight = 1080;
codec_settings_.width = kScreenWidth;
codec_settings_.height = kScreenHeight;
// Screensharing has the internal frame dropper off, and instead per frame
// asks ScreenshareLayers to decide if it should be dropped or not.
codec_settings_.VP8()->frameDroppingOn = false;
codec_settings_.mode = VideoCodecMode::kScreensharing;
// ScreenshareLayers triggers on 2 temporal layers and 1000kbps max bitrate.
codec_settings_.VP8()->numberOfTemporalLayers = 2;
codec_settings_.maxBitrate = 1000;
// Reset the frame generator with large number of squares, leading to lots of
// details and high probability of overshoot.
input_frame_generator_ = test::FrameGenerator::CreateSquareGenerator(
codec_settings_.width, codec_settings_.height,
test::FrameGenerator::OutputType::I420,
/* num_squares = */ absl::optional<int>(300));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
VideoBitrateAllocation bitrate_allocation;
// Bitrate only enough for TL0.
bitrate_allocation.SetBitrate(0, 0, 200000);
encoder_->SetRateAllocation(bitrate_allocation, 5);
EncodedImage encoded_frame;
CodecSpecificInfo codec_specific_info;
EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame, &codec_specific_info,
true);
EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
}
} // namespace webrtc