aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorPhilipp Hancke <phancke@microsoft.com>2022-11-04 14:45:23 +0100
committerWebRTC LUCI CQ <webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-07 15:47:51 +0000
commita1b4eb2196b2c2292230faa9afc8c7b8388e936e (patch)
tree8201dd8afdce3c52d37658e10bbfa0380ed95073 /video
parent140eb82acd09f053780605710fc47d3b2f169021 (diff)
downloadwebrtc-a1b4eb2196b2c2292230faa9afc8c7b8388e936e.tar.gz
generateKeyFrame: add rids argument
and do the resolution of rids to layers. This has no effect yet since the simulcast encoder adapter (SimulcastEncoderAdapter::Encode), the VP8 encoder (LibvpxVp8Encoder::Encode) and the OpenH264 encoder (H264EncoderImpl::Encode) all generate a key frame for all layers whenever a key frame is requested on one layer. BUG=chromium:1354101 Change-Id: I13f5f1bf136839a68942b0f6bf4f2d5890415250 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/280945 Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Philipp Hancke <phancke@microsoft.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38565}
Diffstat (limited to 'video')
-rw-r--r--video/encoder_rtcp_feedback_unittest.cc8
-rw-r--r--video/test/mock_video_stream_encoder.h5
-rw-r--r--video/video_send_stream.cc19
-rw-r--r--video/video_send_stream.h3
-rw-r--r--video/video_stream_encoder.cc17
-rw-r--r--video/video_stream_encoder.h2
-rw-r--r--video/video_stream_encoder_interface.h6
7 files changed, 45 insertions, 15 deletions
diff --git a/video/encoder_rtcp_feedback_unittest.cc b/video/encoder_rtcp_feedback_unittest.cc
index 4cbb747e51..f1ac65d48f 100644
--- a/video/encoder_rtcp_feedback_unittest.cc
+++ b/video/encoder_rtcp_feedback_unittest.cc
@@ -16,6 +16,8 @@
#include "test/gtest.h"
#include "video/test/mock_video_stream_encoder.h"
+using ::testing::_;
+
namespace webrtc {
class VieKeyRequestTest : public ::testing::Test {
@@ -38,18 +40,18 @@ class VieKeyRequestTest : public ::testing::Test {
};
TEST_F(VieKeyRequestTest, CreateAndTriggerRequests) {
- EXPECT_CALL(encoder_, SendKeyFrame()).Times(1);
+ EXPECT_CALL(encoder_, SendKeyFrame(_)).Times(1);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
}
TEST_F(VieKeyRequestTest, TooManyOnReceivedIntraFrameRequest) {
- EXPECT_CALL(encoder_, SendKeyFrame()).Times(1);
+ EXPECT_CALL(encoder_, SendKeyFrame(_)).Times(1);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
simulated_clock_.AdvanceTimeMilliseconds(10);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
- EXPECT_CALL(encoder_, SendKeyFrame()).Times(1);
+ EXPECT_CALL(encoder_, SendKeyFrame(_)).Times(1);
simulated_clock_.AdvanceTimeMilliseconds(300);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
encoder_rtcp_feedback_.OnReceivedIntraFrameRequest(kSsrc);
diff --git a/video/test/mock_video_stream_encoder.h b/video/test/mock_video_stream_encoder.h
index ff246df253..2f982158f0 100644
--- a/video/test/mock_video_stream_encoder.h
+++ b/video/test/mock_video_stream_encoder.h
@@ -34,7 +34,10 @@ class MockVideoStreamEncoder : public VideoStreamEncoderInterface {
(override));
MOCK_METHOD(void, SetSink, (EncoderSink*, bool), (override));
MOCK_METHOD(void, SetStartBitrate, (int), (override));
- MOCK_METHOD(void, SendKeyFrame, (), (override));
+ MOCK_METHOD(void,
+ SendKeyFrame,
+ (const std::vector<VideoFrameType>&),
+ (override));
MOCK_METHOD(void,
OnLossNotification,
(const VideoEncoder::LossNotification&),
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index f245332753..bf5f99aca5 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -343,9 +343,24 @@ void VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
send_stream_.DeliverRtcp(packet, length);
}
-void VideoSendStream::GenerateKeyFrame() {
+void VideoSendStream::GenerateKeyFrame(const std::vector<std::string>& rids) {
+ // Map rids to layers. If rids is empty, generate a keyframe for all layers.
+ std::vector<VideoFrameType> next_frames(config_.rtp.ssrcs.size(),
+ VideoFrameType::kVideoFrameKey);
+ if (!config_.rtp.rids.empty() && !rids.empty()) {
+ std::fill(next_frames.begin(), next_frames.end(),
+ VideoFrameType::kVideoFrameDelta);
+ for (const auto& rid : rids) {
+ for (size_t i = 0; i < config_.rtp.rids.size(); i++) {
+ if (config_.rtp.rids[i] == rid) {
+ next_frames[i] = VideoFrameType::kVideoFrameKey;
+ break;
+ }
+ }
+ }
+ }
if (video_stream_encoder_) {
- video_stream_encoder_->SendKeyFrame();
+ video_stream_encoder_->SendKeyFrame(next_frames);
}
}
diff --git a/video/video_send_stream.h b/video/video_send_stream.h
index a7763731b7..4174d2e5c6 100644
--- a/video/video_send_stream.h
+++ b/video/video_send_stream.h
@@ -13,6 +13,7 @@
#include <map>
#include <memory>
+#include <string>
#include <vector>
#include "api/fec_controller.h"
@@ -93,7 +94,7 @@ class VideoSendStream : public webrtc::VideoSendStream {
void StopPermanentlyAndGetRtpStates(RtpStateMap* rtp_state_map,
RtpPayloadStateMap* payload_state_map);
- void GenerateKeyFrame() override;
+ void GenerateKeyFrame(const std::vector<std::string>& rids) override;
private:
friend class test::VideoSendStreamPeer;
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 746ee79473..de40ccf348 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -1981,9 +1981,10 @@ void VideoStreamEncoder::RequestRefreshFrame() {
}));
}
-void VideoStreamEncoder::SendKeyFrame() {
+void VideoStreamEncoder::SendKeyFrame(
+ const std::vector<VideoFrameType>& layers) {
if (!encoder_queue_.IsCurrent()) {
- encoder_queue_.PostTask([this] { SendKeyFrame(); });
+ encoder_queue_.PostTask([this, layers] { SendKeyFrame(layers); });
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
@@ -1998,9 +1999,15 @@ void VideoStreamEncoder::SendKeyFrame() {
return; // Shutting down, or not configured yet.
}
- // TODO(webrtc:10615): Map keyframe request to spatial layer.
- std::fill(next_frame_types_.begin(), next_frame_types_.end(),
- VideoFrameType::kVideoFrameKey);
+ if (!layers.empty()) {
+ RTC_DCHECK_EQ(layers.size(), next_frame_types_.size());
+ for (size_t i = 0; i < layers.size() && i < next_frame_types_.size(); i++) {
+ next_frame_types_[i] = layers[i];
+ }
+ } else {
+ std::fill(next_frame_types_.begin(), next_frame_types_.end(),
+ VideoFrameType::kVideoFrameKey);
+ }
}
void VideoStreamEncoder::OnLossNotification(
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 9af2e0bcff..e94c369a19 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -111,7 +111,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// guaranteed that no encoded frames will be delivered to the sink.
void Stop() override;
- void SendKeyFrame() override;
+ void SendKeyFrame(const std::vector<VideoFrameType>& layers = {}) override;
void OnLossNotification(
const VideoEncoder::LossNotification& loss_notification) override;
diff --git a/video/video_stream_encoder_interface.h b/video/video_stream_encoder_interface.h
index 38f180d121..e716572e68 100644
--- a/video/video_stream_encoder_interface.h
+++ b/video/video_stream_encoder_interface.h
@@ -97,8 +97,10 @@ class VideoStreamEncoderInterface {
// resolution. Should be replaced by a construction time setting.
virtual void SetStartBitrate(int start_bitrate_bps) = 0;
- // Request a key frame. Used for signalling from the remote receiver.
- virtual void SendKeyFrame() = 0;
+ // Request a key frame. Used for signalling from the remote receiver with
+ // no arguments and for RTCRtpSender.generateKeyFrame with a list of
+ // rids/layers.
+ virtual void SendKeyFrame(const std::vector<VideoFrameType>& layers = {}) = 0;
// Inform the encoder that a loss has occurred.
virtual void OnLossNotification(