[PCLF] Introduce API to subscribe to particular streams
Bug: b/213863770 Change-Id: If858686cd265ad48b4ea8be246651eff65fad4f3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/258981 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36570}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
d959f3a665
commit
0d510529e7
@ -433,9 +433,13 @@ rtc_source_set("peer_network_dependencies") {
|
||||
rtc_source_set("peer_connection_quality_test_fixture_api") {
|
||||
visibility = [ "*" ]
|
||||
testonly = true
|
||||
sources = [ "test/peerconnection_quality_test_fixture.h" ]
|
||||
sources = [
|
||||
"test/peerconnection_quality_test_fixture.cc",
|
||||
"test/peerconnection_quality_test_fixture.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":array_view",
|
||||
":audio_quality_analyzer_api",
|
||||
":callfactory_api",
|
||||
":fec_controller_api",
|
||||
@ -1176,6 +1180,7 @@ if (rtc_include_tests) {
|
||||
"scoped_refptr_unittest.cc",
|
||||
"sequence_checker_unittest.cc",
|
||||
"test/create_time_controller_unittest.cc",
|
||||
"test/peerconnection_quality_test_fixture_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@ -1185,6 +1190,7 @@ if (rtc_include_tests) {
|
||||
":field_trials_view",
|
||||
":function_view",
|
||||
":libjingle_peerconnection_api",
|
||||
":peer_connection_quality_test_fixture_api",
|
||||
":rtc_error",
|
||||
":rtc_event_log_output_file",
|
||||
":rtp_packet_info",
|
||||
@ -1212,6 +1218,7 @@ if (rtc_include_tests) {
|
||||
"video:rtp_video_frame_assembler_unittests",
|
||||
"video:video_unittests",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
rtc_library("compile_all_headers") {
|
||||
|
||||
73
api/test/peerconnection_quality_test_fixture.cc
Normal file
73
api/test/peerconnection_quality_test_fixture.cc
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2022 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/test/peerconnection_quality_test_fixture.h"
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_pc_e2e {
|
||||
|
||||
using VideoCodecConfig = ::webrtc::webrtc_pc_e2e::
|
||||
PeerConnectionE2EQualityTestFixture::VideoCodecConfig;
|
||||
using VideoSubscription = ::webrtc::webrtc_pc_e2e::
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription;
|
||||
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription::Resolution::Resolution(
|
||||
size_t width,
|
||||
size_t height,
|
||||
int32_t fps)
|
||||
: width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription::Resolution::Resolution(
|
||||
const VideoConfig& video_config)
|
||||
: width_(video_config.width),
|
||||
height_(video_config.height),
|
||||
fps_(video_config.fps),
|
||||
spec_(Spec::kNone) {}
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription::Resolution::Resolution(
|
||||
Spec spec)
|
||||
: width_(0), height_(0), fps_(0), spec_(spec) {}
|
||||
|
||||
bool PeerConnectionE2EQualityTestFixture::VideoSubscription::Resolution::
|
||||
operator==(const Resolution& other) const {
|
||||
if (spec_ != Spec::kNone && spec_ == other.spec_) {
|
||||
// If there is some particular spec set, then it doesn't matter what
|
||||
// values we have in other fields.
|
||||
return true;
|
||||
}
|
||||
return width_ == other.width_ && height_ == other.height_ &&
|
||||
fps_ == other.fps_ && spec_ == other.spec_;
|
||||
}
|
||||
|
||||
absl::optional<VideoSubscription::Resolution>
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription::GetMaxResolution(
|
||||
rtc::ArrayView<const VideoConfig> video_configs) {
|
||||
if (video_configs.empty()) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
VideoSubscription::Resolution max_resolution;
|
||||
for (const VideoConfig& config : video_configs) {
|
||||
if (max_resolution.width() < config.width) {
|
||||
max_resolution.set_width(config.width);
|
||||
}
|
||||
if (max_resolution.height() < config.height) {
|
||||
max_resolution.set_height(config.height);
|
||||
}
|
||||
if (max_resolution.fps() < config.fps) {
|
||||
max_resolution.set_fps(config.fps);
|
||||
}
|
||||
}
|
||||
return max_resolution;
|
||||
}
|
||||
|
||||
} // namespace webrtc_pc_e2e
|
||||
} // namespace webrtc
|
||||
@ -19,6 +19,7 @@
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/async_resolver_factory.h"
|
||||
#include "api/audio/audio_mixer.h"
|
||||
#include "api/call/call_factory_interface.h"
|
||||
@ -327,6 +328,99 @@ class PeerConnectionE2EQualityTestFixture {
|
||||
std::map<std::string, std::string> required_params;
|
||||
};
|
||||
|
||||
// Subscription to the remote video streams. It declares which remote stream
|
||||
// peer should receive and in which resolution (width x height x fps).
|
||||
class VideoSubscription {
|
||||
public:
|
||||
class Resolution {
|
||||
public:
|
||||
// Determines special resolutions, which can't be expressed in terms of
|
||||
// width, height and fps.
|
||||
enum class Spec {
|
||||
// No extra spec set. It describes a regular resolution described by
|
||||
// width, height and fps.
|
||||
kNone,
|
||||
// Describes resolution which contains max value among all sender's
|
||||
// video streams in each dimension (width, height, fps).
|
||||
kMaxFromSender
|
||||
};
|
||||
|
||||
Resolution(size_t width, size_t height, int32_t fps);
|
||||
explicit Resolution(const VideoConfig& video_config);
|
||||
explicit Resolution(Spec spec = Spec::kNone);
|
||||
|
||||
bool operator==(const Resolution& other) const;
|
||||
bool operator!=(const Resolution& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
size_t width() const { return width_; }
|
||||
void set_width(size_t width) { width_ = width; }
|
||||
size_t height() const { return height_; }
|
||||
void set_height(size_t height) { height_ = height; }
|
||||
int32_t fps() const { return fps_; }
|
||||
void set_fps(int32_t fps) { fps_ = fps; }
|
||||
|
||||
private:
|
||||
size_t width_ = 0;
|
||||
size_t height_ = 0;
|
||||
int32_t fps_ = 0;
|
||||
Spec spec_ = Spec::kNone;
|
||||
};
|
||||
|
||||
// Returns the resolution constructed as maximum from all resolution
|
||||
// dimensions: width, height and fps.
|
||||
static absl::optional<VideoSubscription::Resolution> GetMaxResolution(
|
||||
rtc::ArrayView<const VideoConfig> video_configs);
|
||||
|
||||
// Subscribes receiver to all streams sent by the specified peer with
|
||||
// specified resolution. It will override any resolution that was used in
|
||||
// `SubscribeToAll` independently from methods call order.
|
||||
VideoSubscription& SubscribeToPeer(
|
||||
absl::string_view peer_name,
|
||||
Resolution resolution = Resolution(Resolution::Spec::kMaxFromSender)) {
|
||||
peers_resolution_[std::string(peer_name)] = resolution;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Subscribes receiver to the all sent streams with specified resolution.
|
||||
// If any stream was subscribed to with `SubscribeTo` method that will
|
||||
// override resolution passed to this function independently from methods
|
||||
// call order.
|
||||
VideoSubscription& SubscribeToAllPeers(
|
||||
Resolution resolution = Resolution(Resolution::Spec::kMaxFromSender)) {
|
||||
default_resolution_ = resolution;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns resolution for specific sender. If no specific resolution was
|
||||
// set for this sender, then will return resolution used for all streams.
|
||||
// If subscription doesn't subscribe to all streams, `absl::nullopt` will be
|
||||
// returned.
|
||||
absl::optional<Resolution> GetResolutionForPeer(
|
||||
absl::string_view peer_name) const {
|
||||
auto it = peers_resolution_.find(std::string(peer_name));
|
||||
if (it == peers_resolution_.end()) {
|
||||
return default_resolution_;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Returns a maybe empty list of senders for which peer explicitly
|
||||
// subscribed to with specific resolution.
|
||||
std::vector<std::string> GetSubscribedPeers() const {
|
||||
std::vector<std::string> subscribed_streams;
|
||||
for (const auto& entry : peers_resolution_) {
|
||||
subscribed_streams.push_back(entry.first);
|
||||
}
|
||||
return subscribed_streams;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<Resolution> default_resolution_ = absl::nullopt;
|
||||
std::map<std::string, Resolution> peers_resolution_;
|
||||
};
|
||||
|
||||
// This class is used to fully configure one peer inside the call.
|
||||
class PeerConfigurer {
|
||||
public:
|
||||
@ -396,6 +490,11 @@ class PeerConnectionE2EQualityTestFixture {
|
||||
virtual PeerConfigurer* AddVideoConfig(
|
||||
VideoConfig config,
|
||||
CapturingDeviceIndex capturing_device_index) = 0;
|
||||
// Sets video subscription for the peer. By default subscription will
|
||||
// include all streams with `VideoSubscription::kSameAsSendStream`
|
||||
// resolution. To override this behavior use this method.
|
||||
virtual PeerConfigurer* SetVideoSubscription(
|
||||
VideoSubscription subscription) = 0;
|
||||
// Set the list of video codecs used by the peer during the test. These
|
||||
// codecs will be negotiated in SDP during offer/answer exchange. The order
|
||||
// of these codecs during negotiation will be the same as in `video_codecs`.
|
||||
|
||||
82
api/test/peerconnection_quality_test_fixture_unittest.cc
Normal file
82
api/test/peerconnection_quality_test_fixture_unittest.cc
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2022 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/test/peerconnection_quality_test_fixture.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_pc_e2e {
|
||||
namespace {
|
||||
|
||||
using VideoSubscription = ::webrtc::webrtc_pc_e2e::
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription;
|
||||
using VideoConfig =
|
||||
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;
|
||||
|
||||
TEST(PclfVideoSubscription, MaxFromSenderSpecEqualIndependentOfOtherFields) {
|
||||
VideoSubscription::Resolution r1(
|
||||
VideoSubscription::Resolution::Spec::kMaxFromSender);
|
||||
r1.set_width(1);
|
||||
r1.set_height(2);
|
||||
r1.set_fps(3);
|
||||
VideoSubscription::Resolution r2(
|
||||
VideoSubscription::Resolution::Spec::kMaxFromSender);
|
||||
r1.set_width(4);
|
||||
r1.set_height(5);
|
||||
r1.set_fps(6);
|
||||
EXPECT_EQ(r1, r2);
|
||||
}
|
||||
|
||||
TEST(PclfVideoSubscription, WhenSpecIsNotSetFieldsAreCompared) {
|
||||
VideoSubscription::Resolution test_resolution(/*width=*/1, /*height=*/2,
|
||||
/*fps=*/3);
|
||||
VideoSubscription::Resolution equal_resolution(/*width=*/1, /*height=*/2,
|
||||
/*fps=*/3);
|
||||
VideoSubscription::Resolution different_width(/*width=*/10, /*height=*/2,
|
||||
/*fps=*/3);
|
||||
VideoSubscription::Resolution different_height(/*width=*/1, /*height=*/20,
|
||||
/*fps=*/3);
|
||||
VideoSubscription::Resolution different_fps(/*width=*/1, /*height=*/20,
|
||||
/*fps=*/30);
|
||||
|
||||
EXPECT_EQ(test_resolution, equal_resolution);
|
||||
EXPECT_NE(test_resolution, different_width);
|
||||
EXPECT_NE(test_resolution, different_height);
|
||||
EXPECT_NE(test_resolution, different_fps);
|
||||
}
|
||||
|
||||
TEST(PclfVideoSubscription, GetMaxResolutionForEmptyReturnsNullopt) {
|
||||
absl::optional<VideoSubscription::Resolution> resolution =
|
||||
VideoSubscription::GetMaxResolution({});
|
||||
ASSERT_FALSE(resolution.has_value());
|
||||
}
|
||||
|
||||
TEST(PclfVideoSubscription, GetMaxResolutionSelectMaxForEachDimention) {
|
||||
VideoConfig max_width(/*width=*/1000, /*height=*/1, /*fps=*/1);
|
||||
VideoConfig max_height(/*width=*/1, /*height=*/100, /*fps=*/1);
|
||||
VideoConfig max_fps(/*width=*/1, /*height=*/1, /*fps=*/10);
|
||||
|
||||
absl::optional<VideoSubscription::Resolution> resolution =
|
||||
VideoSubscription::GetMaxResolution(
|
||||
std::vector<VideoConfig>{max_width, max_height, max_fps});
|
||||
ASSERT_TRUE(resolution.has_value());
|
||||
EXPECT_EQ(resolution->width(), static_cast<size_t>(1000));
|
||||
EXPECT_EQ(resolution->height(), static_cast<size_t>(100));
|
||||
EXPECT_EQ(resolution->fps(), 10);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc_pc_e2e
|
||||
} // namespace webrtc
|
||||
@ -145,6 +145,12 @@ class PeerConfigurerImpl final
|
||||
video_sources_.push_back(index);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetVideoSubscription(
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription subscription)
|
||||
override {
|
||||
params_->video_subscription = std::move(subscription);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetAudioConfig(
|
||||
PeerConnectionE2EQualityTestFixture::AudioConfig config) override {
|
||||
params_->audio_config = std::move(config);
|
||||
|
||||
@ -143,6 +143,9 @@ struct Params {
|
||||
BitrateSettings bitrate_settings;
|
||||
std::vector<PeerConnectionE2EQualityTestFixture::VideoCodecConfig>
|
||||
video_codecs;
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription video_subscription =
|
||||
PeerConnectionE2EQualityTestFixture::VideoSubscription()
|
||||
.SubscribeToAllPeers();
|
||||
};
|
||||
|
||||
} // namespace webrtc_pc_e2e
|
||||
|
||||
Reference in New Issue
Block a user