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:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user