tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

media_configuration.cc (10817B)


      1 /*
      2 *  Copyright 2022 The WebRTC Project Authors. All rights reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "api/test/pclf/media_configuration.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <functional>
     16 #include <map>
     17 #include <memory>
     18 #include <optional>
     19 #include <string>
     20 #include <utility>
     21 #include <vector>
     22 
     23 #include "absl/strings/string_view.h"
     24 #include "api/array_view.h"
     25 #include "api/test/video/video_frame_writer.h"
     26 #include "api/units/time_delta.h"
     27 #include "rtc_base/checks.h"
     28 #include "rtc_base/strings/string_builder.h"
     29 #include "test/pc/e2e/analyzer/video/video_dumping.h"
     30 #include "test/testsupport/file_utils.h"
     31 #include "test/testsupport/video_frame_writer.h"
     32 
     33 namespace webrtc {
     34 namespace webrtc_pc_e2e {
     35 namespace {
     36 
     37 absl::string_view SpecToString(VideoResolution::Spec spec) {
     38  switch (spec) {
     39    case VideoResolution::Spec::kNone:
     40      return "None";
     41    case VideoResolution::Spec::kMaxFromSender:
     42      return "MaxFromSender";
     43  }
     44 }
     45 
     46 void AppendResolution(const VideoResolution& resolution,
     47                      StringBuilder& builder) {
     48  builder << "_" << resolution.width() << "x" << resolution.height() << "_"
     49          << resolution.fps();
     50 }
     51 
     52 }  // namespace
     53 
     54 ScreenShareConfig::ScreenShareConfig(TimeDelta slide_change_interval)
     55    : slide_change_interval(slide_change_interval) {
     56  RTC_CHECK_GT(slide_change_interval.ms(), 0);
     57 }
     58 VideoSimulcastConfig::VideoSimulcastConfig(int simulcast_streams_count)
     59    : simulcast_streams_count(simulcast_streams_count) {
     60  RTC_CHECK_GT(simulcast_streams_count, 1);
     61 }
     62 EmulatedSFUConfig::EmulatedSFUConfig(int target_layer_index)
     63    : target_layer_index(target_layer_index) {
     64  RTC_CHECK_GE(target_layer_index, 0);
     65 }
     66 
     67 EmulatedSFUConfig::EmulatedSFUConfig(std::optional<int> target_layer_index,
     68                                     std::optional<int> target_temporal_index)
     69    : target_layer_index(target_layer_index),
     70      target_temporal_index(target_temporal_index) {
     71  RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
     72  if (target_temporal_index)
     73    RTC_CHECK_GE(*target_temporal_index, 0);
     74 }
     75 
     76 VideoResolution::VideoResolution(size_t width, size_t height, int32_t fps)
     77    : width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
     78 VideoResolution::VideoResolution(Spec spec)
     79    : width_(0), height_(0), fps_(0), spec_(spec) {}
     80 
     81 bool VideoResolution::operator==(const VideoResolution& other) const {
     82  if (spec_ != Spec::kNone && spec_ == other.spec_) {
     83    // If there is some particular spec set, then it doesn't matter what
     84    // values we have in other fields.
     85    return true;
     86  }
     87  return width_ == other.width_ && height_ == other.height_ &&
     88         fps_ == other.fps_ && spec_ == other.spec_;
     89 }
     90 bool VideoResolution::operator!=(const VideoResolution& other) const {
     91  return !(*this == other);
     92 }
     93 
     94 bool VideoResolution::IsRegular() const {
     95  return spec_ == Spec::kNone;
     96 }
     97 std::string VideoResolution::ToString() const {
     98  StringBuilder out;
     99  out << "{ width=" << width_ << ", height=" << height_ << ", fps=" << fps_
    100      << ", spec=" << SpecToString(spec_) << " }";
    101  return out.Release();
    102 }
    103 
    104 VideoDumpOptions::VideoDumpOptions(
    105    absl::string_view output_directory,
    106    int sampling_modulo,
    107    bool export_frame_ids,
    108    std::function<std::unique_ptr<test::VideoFrameWriter>(
    109        absl::string_view file_name_prefix,
    110        const VideoResolution& resolution)> video_frame_writer_factory)
    111    : output_directory_(output_directory),
    112      sampling_modulo_(sampling_modulo),
    113      export_frame_ids_(export_frame_ids),
    114      video_frame_writer_factory_(video_frame_writer_factory) {
    115  RTC_CHECK_GT(sampling_modulo, 0);
    116 }
    117 
    118 VideoDumpOptions::VideoDumpOptions(absl::string_view output_directory,
    119                                   bool export_frame_ids)
    120    : VideoDumpOptions(output_directory,
    121                       kDefaultSamplingModulo,
    122                       export_frame_ids) {}
    123 
    124 std::unique_ptr<test::VideoFrameWriter>
    125 VideoDumpOptions::CreateInputDumpVideoFrameWriter(
    126    absl::string_view stream_label,
    127    const VideoResolution& resolution) const {
    128  std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
    129      GetInputDumpFileName(stream_label, resolution), resolution);
    130  std::optional<std::string> frame_ids_file =
    131      GetInputFrameIdsDumpFileName(stream_label, resolution);
    132  if (frame_ids_file.has_value()) {
    133    writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
    134  }
    135  return writer;
    136 }
    137 
    138 std::unique_ptr<test::VideoFrameWriter>
    139 VideoDumpOptions::CreateOutputDumpVideoFrameWriter(
    140    absl::string_view stream_label,
    141    absl::string_view receiver,
    142    const VideoResolution& resolution) const {
    143  std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
    144      GetOutputDumpFileName(stream_label, receiver, resolution), resolution);
    145  std::optional<std::string> frame_ids_file =
    146      GetOutputFrameIdsDumpFileName(stream_label, receiver, resolution);
    147  if (frame_ids_file.has_value()) {
    148    writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
    149  }
    150  return writer;
    151 }
    152 
    153 std::unique_ptr<test::VideoFrameWriter>
    154 VideoDumpOptions::Y4mVideoFrameWriterFactory(
    155    absl::string_view file_name_prefix,
    156    const VideoResolution& resolution) {
    157  return std::make_unique<test::Y4mVideoFrameWriterImpl>(
    158      std::string(file_name_prefix) + ".y4m", resolution.width(),
    159      resolution.height(), resolution.fps());
    160 }
    161 
    162 std::string VideoDumpOptions::GetInputDumpFileName(
    163    absl::string_view stream_label,
    164    const VideoResolution& resolution) const {
    165  StringBuilder file_name;
    166  file_name << stream_label;
    167  AppendResolution(resolution, file_name);
    168  return test::JoinFilename(output_directory_, file_name.Release());
    169 }
    170 
    171 std::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
    172    absl::string_view stream_label,
    173    const VideoResolution& resolution) const {
    174  if (!export_frame_ids_) {
    175    return std::nullopt;
    176  }
    177  return GetInputDumpFileName(stream_label, resolution) + ".frame_ids.txt";
    178 }
    179 
    180 std::string VideoDumpOptions::GetOutputDumpFileName(
    181    absl::string_view stream_label,
    182    absl::string_view receiver,
    183    const VideoResolution& resolution) const {
    184  StringBuilder file_name;
    185  file_name << stream_label << "_" << receiver;
    186  AppendResolution(resolution, file_name);
    187  return test::JoinFilename(output_directory_, file_name.Release());
    188 }
    189 
    190 std::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
    191    absl::string_view stream_label,
    192    absl::string_view receiver,
    193    const VideoResolution& resolution) const {
    194  if (!export_frame_ids_) {
    195    return std::nullopt;
    196  }
    197  return GetOutputDumpFileName(stream_label, receiver, resolution) +
    198         ".frame_ids.txt";
    199 }
    200 
    201 std::string VideoDumpOptions::ToString() const {
    202  StringBuilder out;
    203  out << "{ output_directory_=" << output_directory_
    204      << ", sampling_modulo_=" << sampling_modulo_
    205      << ", export_frame_ids_=" << export_frame_ids_ << " }";
    206  return out.Release();
    207 }
    208 
    209 VideoConfig::VideoConfig(const VideoResolution& resolution)
    210    : width(resolution.width()),
    211      height(resolution.height()),
    212      fps(resolution.fps()) {
    213  RTC_CHECK(resolution.IsRegular());
    214 }
    215 VideoConfig::VideoConfig(size_t width, size_t height, int32_t fps)
    216    : width(width), height(height), fps(fps) {}
    217 VideoConfig::VideoConfig(absl::string_view stream_label,
    218                         size_t width,
    219                         size_t height,
    220                         int32_t fps)
    221    : width(width), height(height), fps(fps), stream_label(stream_label) {}
    222 
    223 VideoCodecConfig::VideoCodecConfig(absl::string_view name)
    224    : name(name), required_params() {}
    225 
    226 VideoCodecConfig::VideoCodecConfig(
    227    absl::string_view name,
    228    std::map<std::string, std::string> required_params)
    229    : name(name), required_params(std::move(required_params)) {}
    230 
    231 std::optional<VideoResolution> VideoSubscription::GetMaxResolution(
    232    ArrayView<const VideoConfig> video_configs) {
    233  std::vector<VideoResolution> resolutions;
    234  for (const auto& video_config : video_configs) {
    235    resolutions.push_back(video_config.GetResolution());
    236  }
    237  return GetMaxResolution(resolutions);
    238 }
    239 
    240 std::optional<VideoResolution> VideoSubscription::GetMaxResolution(
    241    ArrayView<const VideoResolution> resolutions) {
    242  if (resolutions.empty()) {
    243    return std::nullopt;
    244  }
    245 
    246  VideoResolution max_resolution;
    247  for (const VideoResolution& resolution : resolutions) {
    248    if (max_resolution.width() < resolution.width()) {
    249      max_resolution.set_width(resolution.width());
    250    }
    251    if (max_resolution.height() < resolution.height()) {
    252      max_resolution.set_height(resolution.height());
    253    }
    254    if (max_resolution.fps() < resolution.fps()) {
    255      max_resolution.set_fps(resolution.fps());
    256    }
    257  }
    258  return max_resolution;
    259 }
    260 
    261 bool VideoSubscription::operator==(const VideoSubscription& other) const {
    262  return default_resolution_ == other.default_resolution_ &&
    263         peers_resolution_ == other.peers_resolution_;
    264 }
    265 bool VideoSubscription::operator!=(const VideoSubscription& other) const {
    266  return !(*this == other);
    267 }
    268 
    269 VideoSubscription& VideoSubscription::SubscribeToPeer(
    270    absl::string_view peer_name,
    271    VideoResolution resolution) {
    272  peers_resolution_[std::string(peer_name)] = resolution;
    273  return *this;
    274 }
    275 
    276 VideoSubscription& VideoSubscription::SubscribeToAllPeers(
    277    VideoResolution resolution) {
    278  default_resolution_ = resolution;
    279  return *this;
    280 }
    281 
    282 std::optional<VideoResolution> VideoSubscription::GetResolutionForPeer(
    283    absl::string_view peer_name) const {
    284  auto it = peers_resolution_.find(std::string(peer_name));
    285  if (it == peers_resolution_.end()) {
    286    return default_resolution_;
    287  }
    288  return it->second;
    289 }
    290 
    291 std::vector<std::string> VideoSubscription::GetSubscribedPeers() const {
    292  std::vector<std::string> subscribed_streams;
    293  subscribed_streams.reserve(peers_resolution_.size());
    294  for (const auto& entry : peers_resolution_) {
    295    subscribed_streams.push_back(entry.first);
    296  }
    297  return subscribed_streams;
    298 }
    299 
    300 std::string VideoSubscription::ToString() const {
    301  StringBuilder out;
    302  out << "{ default_resolution_=[";
    303  if (default_resolution_.has_value()) {
    304    out << default_resolution_->ToString();
    305  } else {
    306    out << "undefined";
    307  }
    308  out << "], {";
    309  for (const auto& [peer_name, resolution] : peers_resolution_) {
    310    out << "[" << peer_name << ": " << resolution.ToString() << "], ";
    311  }
    312  out << "} }";
    313  return out.Release();
    314 }
    315 }  // namespace webrtc_pc_e2e
    316 }  // namespace webrtc