Request keyframe via setParameters
after the W3C changes in approach documented here: https://github.com/w3c/webrtc-extensions/pull/167 chromium CL: https://chromium-review.googlesource.com/c/chromium/src/+/4643591 Note that this does not follow the route taken by the W3C API but still considers this flag a part of the encodingParameters. BUG=chromium:1354101 Change-Id: If0f0ec09bebddea1f01dd8afbe4747c21afe6793 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/286741 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Philipp Hancke <phancke@microsoft.com> Cr-Commit-Position: refs/heads/main@{#40656}
This commit is contained in:
parent
36500ab634
commit
82c56ca794
@ -515,6 +515,7 @@ struct RTC_EXPORT RtpEncodingParameters {
|
||||
// Value to use for RID RTP header extension.
|
||||
// Called "encodingId" in ORTC.
|
||||
std::string rid;
|
||||
bool request_key_frame = false;
|
||||
|
||||
// Allow dynamic frame length changes for audio:
|
||||
// https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime
|
||||
|
||||
@ -383,6 +383,11 @@ void FakeVideoSendStream::SetSource(
|
||||
: rtc::VideoSinkWants());
|
||||
}
|
||||
|
||||
void FakeVideoSendStream::GenerateKeyFrame(
|
||||
const std::vector<std::string>& rids) {
|
||||
keyframes_requested_by_rid_ = rids;
|
||||
}
|
||||
|
||||
void FakeVideoSendStream::InjectVideoSinkWants(
|
||||
const rtc::VideoSinkWants& wants) {
|
||||
sink_wants_ = wants;
|
||||
|
||||
@ -188,7 +188,10 @@ class FakeVideoSendStream final
|
||||
rtc::VideoSourceInterface<webrtc::VideoFrame>* source() const {
|
||||
return source_;
|
||||
}
|
||||
void GenerateKeyFrame(const std::vector<std::string>& rids) override {}
|
||||
void GenerateKeyFrame(const std::vector<std::string>& rids);
|
||||
const std::vector<std::string>& GetKeyFramesRequested() const {
|
||||
return keyframes_requested_by_rid_;
|
||||
}
|
||||
|
||||
private:
|
||||
// rtc::VideoSinkInterface<VideoFrame> implementation.
|
||||
@ -231,6 +234,7 @@ class FakeVideoSendStream final
|
||||
absl::optional<webrtc::VideoFrame> last_frame_;
|
||||
webrtc::VideoSendStream::Stats stats_;
|
||||
int num_encoder_reconfigurations_ = 0;
|
||||
std::vector<std::string> keyframes_requested_by_rid_;
|
||||
};
|
||||
|
||||
class FakeVideoReceiveStream final
|
||||
|
||||
@ -1965,6 +1965,22 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::SetRtpParameters(
|
||||
stream_->SetSource(source_, GetDegradationPreference());
|
||||
}
|
||||
}
|
||||
// Check if a key frame was requested via setParameters.
|
||||
std::vector<std::string> key_frames_requested_by_rid;
|
||||
for (const auto& encoding : rtp_parameters_.encodings) {
|
||||
if (encoding.request_key_frame) {
|
||||
key_frames_requested_by_rid.push_back(encoding.rid);
|
||||
}
|
||||
}
|
||||
if (!key_frames_requested_by_rid.empty()) {
|
||||
if (key_frames_requested_by_rid.size() == 1 &&
|
||||
key_frames_requested_by_rid[0] == "") {
|
||||
// For non-simulcast cases there is no rid,
|
||||
// request a keyframe on all layers.
|
||||
key_frames_requested_by_rid.clear();
|
||||
}
|
||||
GenerateKeyFrame(key_frames_requested_by_rid);
|
||||
}
|
||||
return webrtc::InvokeSetParametersCallback(callback, webrtc::RTCError::OK());
|
||||
}
|
||||
|
||||
|
||||
@ -9540,6 +9540,84 @@ TEST_F(WebRtcVideoChannelTest,
|
||||
EXPECT_TRUE(stream->GetEncoderConfig().is_quality_scaling_allowed);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannelTest, GenerateKeyFrameSinglecast) {
|
||||
FakeVideoSendStream* stream = AddSendStream();
|
||||
|
||||
webrtc::RtpParameters rtp_parameters =
|
||||
send_channel_->GetRtpSendParameters(last_ssrc_);
|
||||
ASSERT_EQ(1u, rtp_parameters.encodings.size());
|
||||
EXPECT_EQ(rtp_parameters.encodings[0].rid, "");
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(), std::vector<std::string>({}));
|
||||
|
||||
// Manually set the key frames requested to check they are cleared by the next
|
||||
// call.
|
||||
stream->GenerateKeyFrame({"bogus"});
|
||||
rtp_parameters.encodings[0].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(),
|
||||
ElementsAreArray(std::vector<std::string>({})));
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannelTest, GenerateKeyFrameSimulcast) {
|
||||
StreamParams stream_params = CreateSimStreamParams("cname", {123, 456, 789});
|
||||
|
||||
std::vector<std::string> rids = {"f", "h", "q"};
|
||||
std::vector<cricket::RidDescription> rid_descriptions;
|
||||
for (const auto& rid : rids) {
|
||||
rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
|
||||
}
|
||||
stream_params.set_rids(rid_descriptions);
|
||||
FakeVideoSendStream* stream = AddSendStream(stream_params);
|
||||
|
||||
webrtc::RtpParameters rtp_parameters =
|
||||
send_channel_->GetRtpSendParameters(last_ssrc_);
|
||||
ASSERT_EQ(3u, rtp_parameters.encodings.size());
|
||||
EXPECT_EQ(rtp_parameters.encodings[0].rid, "f");
|
||||
EXPECT_EQ(rtp_parameters.encodings[1].rid, "h");
|
||||
EXPECT_EQ(rtp_parameters.encodings[2].rid, "q");
|
||||
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(),
|
||||
ElementsAreArray(std::vector<std::string>({})));
|
||||
|
||||
rtp_parameters.encodings[0].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(), ElementsAreArray({"f"}));
|
||||
|
||||
rtp_parameters.encodings[0].request_key_frame = true;
|
||||
rtp_parameters.encodings[1].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(), ElementsAreArray({"f", "h"}));
|
||||
|
||||
rtp_parameters.encodings[0].request_key_frame = true;
|
||||
rtp_parameters.encodings[1].request_key_frame = true;
|
||||
rtp_parameters.encodings[2].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(),
|
||||
ElementsAreArray({"f", "h", "q"}));
|
||||
|
||||
rtp_parameters.encodings[0].request_key_frame = true;
|
||||
rtp_parameters.encodings[1].request_key_frame = false;
|
||||
rtp_parameters.encodings[2].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(), ElementsAreArray({"f", "q"}));
|
||||
|
||||
rtp_parameters.encodings[0].request_key_frame = false;
|
||||
rtp_parameters.encodings[1].request_key_frame = false;
|
||||
rtp_parameters.encodings[2].request_key_frame = true;
|
||||
EXPECT_TRUE(
|
||||
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
|
||||
EXPECT_THAT(stream->GetKeyFramesRequested(), ElementsAreArray({"q"}));
|
||||
}
|
||||
|
||||
class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
|
||||
public:
|
||||
WebRtcVideoChannelSimulcastTest()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user