From e62a08a87a6f21672b2ae8ba25632007f417a3f1 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Mon, 13 May 2019 13:45:39 +0200 Subject: [PATCH] Request key frame on all layers. Explicitly request key frame on all layers until proper mapping is implemented (webrtc:10615). Bug: webrtc:10585 Change-Id: I9722610920a753c50700d925ff6a1babf0011e2f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/136682 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/master@{#27934} --- modules/video_coding/codecs/h264/h264_encoder_impl.cc | 10 ++++++---- video/video_stream_encoder.cc | 9 +++++++-- video/video_stream_encoder_unittest.cc | 7 +++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc index 495c11ab7f..a8135bc6c7 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -409,11 +409,13 @@ int32_t H264EncoderImpl::Encode( break; } } + if (!send_key_frame && frame_types) { - for (size_t i = 0; i < frame_types->size() && i < configurations_.size(); - ++i) { - if ((*frame_types)[i] == VideoFrameType::kVideoFrameKey && - configurations_[i].sending) { + for (size_t i = 0; i < configurations_.size(); ++i) { + const size_t simulcast_idx = + static_cast(configurations_[i].simulcast_idx); + if (configurations_[i].sending && simulcast_idx < frame_types->size() && + (*frame_types)[simulcast_idx] == VideoFrameType::kVideoFrameKey) { send_key_frame = true; break; } diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 289a7b9dbd..579c144394 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -1358,7 +1358,11 @@ void VideoStreamEncoder::SendKeyFrame() { RTC_DCHECK_RUN_ON(&encoder_queue_); TRACE_EVENT0("webrtc", "OnKeyFrameRequest"); RTC_DCHECK(!next_frame_types_.empty()); - next_frame_types_[0] = VideoFrameType::kVideoFrameKey; + + // TODO(webrtc:10615): Map keyframe request to spatial layer. + std::fill(next_frame_types_.begin(), next_frame_types_.end(), + VideoFrameType::kVideoFrameKey); + if (HasInternalSource()) { // Try to request the frame if we have an external encoder with // internal source since AddVideoFrame never will be called. @@ -1377,7 +1381,8 @@ void VideoStreamEncoder::SendKeyFrame() { .build(), &next_frame_types_) == WEBRTC_VIDEO_CODEC_OK) { // Try to remove just-performed keyframe request, if stream still exists. - next_frame_types_[0] = VideoFrameType::kVideoFrameDelta; + std::fill(next_frame_types_.begin(), next_frame_types_.end(), + VideoFrameType::kVideoFrameDelta); } } } diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index 18ab5b90b0..19451ecf92 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -3752,10 +3752,13 @@ TEST_F(VideoStreamEncoderTest, SetsFrameTypesSimulcast) { video_stream_encoder_->SendKeyFrame(); video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr)); WaitForEncodedFrame(3); + + // TODO(webrtc:10615): Map keyframe request to spatial layer. Currently + // keyframe request on any layer triggers keyframe on all layers. EXPECT_THAT(fake_encoder_.LastFrameTypes(), ::testing::ElementsAreArray({VideoFrameType::kVideoFrameKey, - VideoFrameType::kVideoFrameDelta, - VideoFrameType::kVideoFrameDelta})); + VideoFrameType::kVideoFrameKey, + VideoFrameType::kVideoFrameKey})); video_stream_encoder_->Stop(); }