webrtc/api/test/pclf/media_configuration.cc
Jeremy Leconte e91d4bc517 Move media configuration classes out of PeerConnectionE2EQualityTestFixture.
The goal is to remove the dependency between PeerConfigurerImpl and PeerConnectionE2EQualityTestFixture so that PeerConfigurerImpl can be used in PeerConnectionE2EQualityTestFixture API.

Change-Id: I29ae44b9d0e39075d0c395ff9d9f8d313be12176
Bug: webrtc:14627
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281740
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Jeremy Leconte <jleconte@google.com>
Cr-Commit-Position: refs/heads/main@{#38560}
2022-11-07 09:34:59 +00:00

322 lines
11 KiB
C++

/*
* 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/pclf/media_configuration.h"
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/test/video/video_frame_writer.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "test/pc/e2e/analyzer/video/video_dumping.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/video_frame_writer.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
std::string SpecToString(VideoResolution::Spec spec) {
switch (spec) {
case VideoResolution::Spec::kNone:
return "None";
case VideoResolution::Spec::kMaxFromSender:
return "MaxFromSender";
}
}
void AppendResolution(const VideoResolution& resolution,
rtc::StringBuilder& builder) {
builder << "_" << resolution.width() << "x" << resolution.height() << "_"
<< resolution.fps();
}
} // namespace
ScrollingParams::ScrollingParams(TimeDelta duration,
size_t source_width,
size_t source_height)
: duration(duration),
source_width(source_width),
source_height(source_height) {
RTC_CHECK_GT(duration.ms(), 0);
}
ScreenShareConfig::ScreenShareConfig(TimeDelta slide_change_interval)
: slide_change_interval(slide_change_interval) {
RTC_CHECK_GT(slide_change_interval.ms(), 0);
}
VideoSimulcastConfig::VideoSimulcastConfig(int simulcast_streams_count)
: simulcast_streams_count(simulcast_streams_count) {
RTC_CHECK_GT(simulcast_streams_count, 1);
}
EmulatedSFUConfig::EmulatedSFUConfig(int target_layer_index)
: target_layer_index(target_layer_index) {
RTC_CHECK_GE(target_layer_index, 0);
}
EmulatedSFUConfig::EmulatedSFUConfig(absl::optional<int> target_layer_index,
absl::optional<int> target_temporal_index)
: target_layer_index(target_layer_index),
target_temporal_index(target_temporal_index) {
RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
if (target_temporal_index)
RTC_CHECK_GE(*target_temporal_index, 0);
}
VideoResolution::VideoResolution(size_t width, size_t height, int32_t fps)
: width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
VideoResolution::VideoResolution(Spec spec)
: width_(0), height_(0), fps_(0), spec_(spec) {}
bool VideoResolution::operator==(const VideoResolution& 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_;
}
bool VideoResolution::operator!=(const VideoResolution& other) const {
return !(*this == other);
}
bool VideoResolution::IsRegular() const {
return spec_ == Spec::kNone;
}
std::string VideoResolution::ToString() const {
rtc::StringBuilder out;
out << "{ width=" << width_ << ", height=" << height_ << ", fps=" << fps_
<< ", spec=" << SpecToString(spec_) << " }";
return out.Release();
}
VideoDumpOptions::VideoDumpOptions(
absl::string_view output_directory,
int sampling_modulo,
bool export_frame_ids,
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)> video_frame_writer_factory)
: output_directory_(output_directory),
sampling_modulo_(sampling_modulo),
export_frame_ids_(export_frame_ids),
video_frame_writer_factory_(video_frame_writer_factory) {
RTC_CHECK_GT(sampling_modulo, 0);
}
VideoDumpOptions::VideoDumpOptions(absl::string_view output_directory,
bool export_frame_ids)
: VideoDumpOptions(output_directory,
kDefaultSamplingModulo,
export_frame_ids) {}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::CreateInputDumpVideoFrameWriter(
absl::string_view stream_label,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetInputDumpFileName(stream_label, resolution), resolution);
absl::optional<std::string> frame_ids_file =
GetInputFrameIdsDumpFileName(stream_label, resolution);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::CreateOutputDumpVideoFrameWriter(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetOutputDumpFileName(stream_label, receiver, resolution), resolution);
absl::optional<std::string> frame_ids_file =
GetOutputFrameIdsDumpFileName(stream_label, receiver, resolution);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::Y4mVideoFrameWriterFactory(
absl::string_view file_name_prefix,
const VideoResolution& resolution) {
return std::make_unique<test::Y4mVideoFrameWriterImpl>(
std::string(file_name_prefix) + ".y4m", resolution.width(),
resolution.height(), resolution.fps());
}
std::string VideoDumpOptions::GetInputDumpFileName(
absl::string_view stream_label,
const VideoResolution& resolution) const {
rtc::StringBuilder file_name;
file_name << stream_label;
AppendResolution(resolution, file_name);
return test::JoinFilename(output_directory_, file_name.Release());
}
absl::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
absl::string_view stream_label,
const VideoResolution& resolution) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetInputDumpFileName(stream_label, resolution) + ".frame_ids.txt";
}
std::string VideoDumpOptions::GetOutputDumpFileName(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
rtc::StringBuilder file_name;
file_name << stream_label << "_" << receiver;
AppendResolution(resolution, file_name);
return test::JoinFilename(output_directory_, file_name.Release());
}
absl::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetOutputDumpFileName(stream_label, receiver, resolution) +
".frame_ids.txt";
}
std::string VideoDumpOptions::ToString() const {
rtc::StringBuilder out;
out << "{ output_directory_=" << output_directory_
<< ", sampling_modulo_=" << sampling_modulo_
<< ", export_frame_ids_=" << export_frame_ids_ << " }";
return out.Release();
}
VideoConfig::VideoConfig(const VideoResolution& resolution)
: width(resolution.width()),
height(resolution.height()),
fps(resolution.fps()) {
RTC_CHECK(resolution.IsRegular());
}
VideoConfig::VideoConfig(size_t width, size_t height, int32_t fps)
: width(width), height(height), fps(fps) {}
VideoConfig::VideoConfig(std::string stream_label,
size_t width,
size_t height,
int32_t fps)
: width(width),
height(height),
fps(fps),
stream_label(std::move(stream_label)) {}
AudioConfig::AudioConfig(std::string stream_label)
: stream_label(std::move(stream_label)) {}
VideoCodecConfig::VideoCodecConfig(std::string name)
: name(std::move(name)), required_params() {}
VideoCodecConfig::VideoCodecConfig(
std::string name,
std::map<std::string, std::string> required_params)
: name(std::move(name)), required_params(std::move(required_params)) {}
absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoConfig> video_configs) {
std::vector<VideoResolution> resolutions;
for (const auto& video_config : video_configs) {
resolutions.push_back(video_config.GetResolution());
}
return GetMaxResolution(resolutions);
}
absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoResolution> resolutions) {
if (resolutions.empty()) {
return absl::nullopt;
}
VideoResolution max_resolution;
for (const VideoResolution& resolution : resolutions) {
if (max_resolution.width() < resolution.width()) {
max_resolution.set_width(resolution.width());
}
if (max_resolution.height() < resolution.height()) {
max_resolution.set_height(resolution.height());
}
if (max_resolution.fps() < resolution.fps()) {
max_resolution.set_fps(resolution.fps());
}
}
return max_resolution;
}
bool VideoSubscription::operator==(const VideoSubscription& other) const {
return default_resolution_ == other.default_resolution_ &&
peers_resolution_ == other.peers_resolution_;
}
bool VideoSubscription::operator!=(const VideoSubscription& other) const {
return !(*this == other);
}
VideoSubscription& VideoSubscription::SubscribeToPeer(
absl::string_view peer_name,
VideoResolution resolution) {
peers_resolution_[std::string(peer_name)] = resolution;
return *this;
}
VideoSubscription& VideoSubscription::SubscribeToAllPeers(
VideoResolution resolution) {
default_resolution_ = resolution;
return *this;
}
absl::optional<VideoResolution> VideoSubscription::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;
}
std::vector<std::string> VideoSubscription::GetSubscribedPeers() const {
std::vector<std::string> subscribed_streams;
subscribed_streams.reserve(peers_resolution_.size());
for (const auto& entry : peers_resolution_) {
subscribed_streams.push_back(entry.first);
}
return subscribed_streams;
}
std::string VideoSubscription::ToString() const {
rtc::StringBuilder out;
out << "{ default_resolution_=[";
if (default_resolution_.has_value()) {
out << default_resolution_->ToString();
} else {
out << "undefined";
}
out << "], {";
for (const auto& [peer_name, resolution] : peers_resolution_) {
out << "[" << peer_name << ": " << resolution.ToString() << "], ";
}
out << "} }";
return out.Release();
}
} // namespace webrtc_pc_e2e
} // namespace webrtc