tor-browser

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

video_encoder_factory_template.h (5530B)


      1 /*
      2 *  Copyright (c) 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 #ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
     12 #define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
     13 
     14 #include <memory>
     15 #include <optional>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "absl/algorithm/container.h"
     20 #include "api/array_view.h"
     21 #include "api/environment/environment.h"
     22 #include "api/video_codecs/scalability_mode.h"
     23 #include "api/video_codecs/sdp_video_format.h"
     24 #include "api/video_codecs/video_encoder.h"
     25 #include "api/video_codecs/video_encoder_factory.h"
     26 #include "modules/video_coding/svc/scalability_mode_util.h"
     27 
     28 namespace webrtc {
     29 // The VideoEncoderFactoryTemplate supports encoders implementations given as
     30 // template arguments.
     31 //
     32 // To include an encoder in the factory it requires three static members
     33 // functions to be defined:
     34 //
     35 //   // Returns the supported SdpVideoFormats this encoder can produce.
     36 //   static std::vector<SdpVideoFormat> SupportedFormats();
     37 //
     38 //   // Creates an encoder instance for the given format.
     39 //   static std::unique_ptr<VideoEncoder>
     40 //       CreateEncoder(const Environment& env,
     41 //                     const SdpVideoFormat& format);
     42 //
     43 //   // Returns true if the encoder supports the given scalability mode.
     44 //   static bool
     45 //       IsScalabilityModeSupported(ScalabilityMode scalability_mode);
     46 //
     47 // Note that the order of the template arguments matter as the factory will
     48 // query/return the first encoder implementation supporting the given
     49 // SdpVideoFormat.
     50 template <typename... Ts>
     51 class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
     52 public:
     53  std::vector<SdpVideoFormat> GetSupportedFormats() const override {
     54    return GetSupportedFormatsInternal<Ts...>();
     55  }
     56 
     57  std::unique_ptr<VideoEncoder> Create(const Environment& env,
     58                                       const SdpVideoFormat& format) override {
     59    // We fuzzy match the specified format for both valid and not so valid
     60    // reasons. The valid reason is that there are many standardized codec
     61    // specific fmtp parameters that have not been implemented, and in those
     62    // cases we should not fail to instantiate an encoder just because we don't
     63    // recognize the parameter. The not so valid reason is that we have started
     64    // adding parameters completely unrelated to the SDP to the SdpVideoFormat.
     65    // TODO: bugs.webrtc.org/13868 - Remove FuzzyMatchSdpVideoFormat
     66    std::optional<SdpVideoFormat> matched =
     67        FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format);
     68    return CreateInternal<Ts...>(env, matched.value_or(format));
     69  }
     70 
     71  CodecSupport QueryCodecSupport(
     72      const SdpVideoFormat& format,
     73      std::optional<std::string> scalability_mode) const override {
     74    return QueryCodecSupportInternal<Ts...>(format, scalability_mode);
     75  }
     76 
     77 private:
     78  bool IsFormatInList(const SdpVideoFormat& format,
     79                      ArrayView<const SdpVideoFormat> supported_formats) const {
     80    return absl::c_any_of(
     81        supported_formats, [&](const SdpVideoFormat& supported_format) {
     82          return supported_format.name == format.name &&
     83                 supported_format.parameters == format.parameters;
     84        });
     85  }
     86 
     87  template <typename V>
     88  bool IsScalabilityModeSupported(
     89      const std::optional<std::string>& scalability_mode_string) const {
     90    if (!scalability_mode_string.has_value()) {
     91      return true;
     92    }
     93    std::optional<ScalabilityMode> scalability_mode =
     94        ScalabilityModeFromString(*scalability_mode_string);
     95    return scalability_mode.has_value() &&
     96           V::IsScalabilityModeSupported(*scalability_mode);
     97  }
     98 
     99  template <typename V, typename... Vs>
    100  std::vector<SdpVideoFormat> GetSupportedFormatsInternal() const {
    101    auto supported_formats = V::SupportedFormats();
    102 
    103    if constexpr (sizeof...(Vs) > 0) {
    104      // Supported formats may overlap between implementations, so duplicates
    105      // should be filtered out.
    106      for (const auto& other_format : GetSupportedFormatsInternal<Vs...>()) {
    107        if (!IsFormatInList(other_format, supported_formats)) {
    108          supported_formats.push_back(other_format);
    109        }
    110      }
    111    }
    112 
    113    return supported_formats;
    114  }
    115 
    116  template <typename V, typename... Vs>
    117  std::unique_ptr<VideoEncoder> CreateInternal(const Environment& env,
    118                                               const SdpVideoFormat& format) {
    119    if (IsFormatInList(format, V::SupportedFormats())) {
    120      return V::CreateEncoder(env, format);
    121    }
    122 
    123    if constexpr (sizeof...(Vs) > 0) {
    124      return CreateInternal<Vs...>(env, format);
    125    }
    126 
    127    return nullptr;
    128  }
    129 
    130  template <typename V, typename... Vs>
    131  CodecSupport QueryCodecSupportInternal(
    132      const SdpVideoFormat& format,
    133      const std::optional<std::string>& scalability_mode) const {
    134    if (IsFormatInList(format, V::SupportedFormats())) {
    135      return {.is_supported = IsScalabilityModeSupported<V>(scalability_mode)};
    136    }
    137 
    138    if constexpr (sizeof...(Vs) > 0) {
    139      return QueryCodecSupportInternal<Vs...>(format, scalability_mode);
    140    }
    141 
    142    return {.is_supported = false};
    143  }
    144 };
    145 
    146 }  // namespace webrtc
    147 
    148 #endif  // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_