tor-browser

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

scalability_mode_util.cc (17322B)


      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 #include "modules/video_coding/svc/scalability_mode_util.h"
     12 
     13 #include <array>
     14 #include <cstddef>
     15 #include <optional>
     16 #include <type_traits>
     17 
     18 #include "absl/algorithm/container.h"
     19 #include "absl/strings/string_view.h"
     20 #include "api/video_codecs/scalability_mode.h"
     21 #include "api/video_codecs/video_codec.h"
     22 #include "rtc_base/checks.h"
     23 
     24 namespace webrtc {
     25 
     26 namespace {
     27 
     28 struct ScalabilityModeParameters {
     29  const ScalabilityMode scalability_mode;
     30  const absl::string_view name;
     31  const int num_spatial_layers;
     32  const int num_temporal_layers;
     33  const InterLayerPredMode inter_layer_pred;
     34  const std::optional<ScalabilityModeResolutionRatio> ratio =
     35      ScalabilityModeResolutionRatio::kTwoToOne;
     36  const bool shift = false;
     37 };
     38 
     39 constexpr size_t kNumScalabilityModes =
     40    static_cast<size_t>(ScalabilityMode::kS3T3h) + 1;
     41 
     42 constexpr ScalabilityModeParameters kScalabilityModeParams[] = {
     43    ScalabilityModeParameters{.scalability_mode = ScalabilityMode::kL1T1,
     44                              .name = "L1T1",
     45                              .num_spatial_layers = 1,
     46                              .num_temporal_layers = 1,
     47                              .inter_layer_pred = InterLayerPredMode::kOff,
     48                              .ratio = std::nullopt},
     49    ScalabilityModeParameters{.scalability_mode = ScalabilityMode::kL1T2,
     50                              .name = "L1T2",
     51                              .num_spatial_layers = 1,
     52                              .num_temporal_layers = 2,
     53                              .inter_layer_pred = InterLayerPredMode::kOff,
     54                              .ratio = std::nullopt},
     55    ScalabilityModeParameters{.scalability_mode = ScalabilityMode::kL1T3,
     56                              .name = "L1T3",
     57                              .num_spatial_layers = 1,
     58                              .num_temporal_layers = 3,
     59                              .inter_layer_pred = InterLayerPredMode::kOff,
     60                              .ratio = std::nullopt},
     61    ScalabilityModeParameters{
     62        .scalability_mode = ScalabilityMode::kL2T1,
     63        .name = "L2T1",
     64        .num_spatial_layers = 2,
     65        .num_temporal_layers = 1,
     66        .inter_layer_pred = InterLayerPredMode::kOn,
     67    },
     68    ScalabilityModeParameters{
     69        .scalability_mode = ScalabilityMode::kL2T1h,
     70        .name = "L2T1h",
     71        .num_spatial_layers = 2,
     72        .num_temporal_layers = 1,
     73        .inter_layer_pred = InterLayerPredMode::kOn,
     74        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
     75    },
     76    ScalabilityModeParameters{
     77        .scalability_mode = ScalabilityMode::kL2T1_KEY,
     78        .name = "L2T1_KEY",
     79        .num_spatial_layers = 2,
     80        .num_temporal_layers = 1,
     81        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
     82    },
     83    ScalabilityModeParameters{
     84        .scalability_mode = ScalabilityMode::kL2T2,
     85        .name = "L2T2",
     86        .num_spatial_layers = 2,
     87        .num_temporal_layers = 2,
     88        .inter_layer_pred = InterLayerPredMode::kOn,
     89    },
     90    ScalabilityModeParameters{
     91        .scalability_mode = ScalabilityMode::kL2T2h,
     92        .name = "L2T2h",
     93        .num_spatial_layers = 2,
     94        .num_temporal_layers = 2,
     95        .inter_layer_pred = InterLayerPredMode::kOn,
     96        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
     97    },
     98    ScalabilityModeParameters{
     99        .scalability_mode = ScalabilityMode::kL2T2_KEY,
    100        .name = "L2T2_KEY",
    101        .num_spatial_layers = 2,
    102        .num_temporal_layers = 2,
    103        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    104    },
    105    ScalabilityModeParameters{
    106        .scalability_mode = ScalabilityMode::kL2T2_KEY_SHIFT,
    107        .name = "L2T2_KEY_SHIFT",
    108        .num_spatial_layers = 2,
    109        .num_temporal_layers = 2,
    110        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    111        .shift = true},
    112    ScalabilityModeParameters{
    113        .scalability_mode = ScalabilityMode::kL2T3,
    114        .name = "L2T3",
    115        .num_spatial_layers = 2,
    116        .num_temporal_layers = 3,
    117        .inter_layer_pred = InterLayerPredMode::kOn,
    118    },
    119    ScalabilityModeParameters{
    120        .scalability_mode = ScalabilityMode::kL2T3h,
    121        .name = "L2T3h",
    122        .num_spatial_layers = 2,
    123        .num_temporal_layers = 3,
    124        .inter_layer_pred = InterLayerPredMode::kOn,
    125        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    126    },
    127    ScalabilityModeParameters{
    128        .scalability_mode = ScalabilityMode::kL2T3_KEY,
    129        .name = "L2T3_KEY",
    130        .num_spatial_layers = 2,
    131        .num_temporal_layers = 3,
    132        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    133    },
    134    ScalabilityModeParameters{
    135        .scalability_mode = ScalabilityMode::kL3T1,
    136        .name = "L3T1",
    137        .num_spatial_layers = 3,
    138        .num_temporal_layers = 1,
    139        .inter_layer_pred = InterLayerPredMode::kOn,
    140    },
    141    ScalabilityModeParameters{
    142        .scalability_mode = ScalabilityMode::kL3T1h,
    143        .name = "L3T1h",
    144        .num_spatial_layers = 3,
    145        .num_temporal_layers = 1,
    146        .inter_layer_pred = InterLayerPredMode::kOn,
    147        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    148    },
    149    ScalabilityModeParameters{
    150        .scalability_mode = ScalabilityMode::kL3T1_KEY,
    151        .name = "L3T1_KEY",
    152        .num_spatial_layers = 3,
    153        .num_temporal_layers = 1,
    154        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    155    },
    156    ScalabilityModeParameters{
    157        .scalability_mode = ScalabilityMode::kL3T2,
    158        .name = "L3T2",
    159        .num_spatial_layers = 3,
    160        .num_temporal_layers = 2,
    161        .inter_layer_pred = InterLayerPredMode::kOn,
    162    },
    163    ScalabilityModeParameters{
    164        .scalability_mode = ScalabilityMode::kL3T2h,
    165        .name = "L3T2h",
    166        .num_spatial_layers = 3,
    167        .num_temporal_layers = 2,
    168        .inter_layer_pred = InterLayerPredMode::kOn,
    169        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    170    },
    171    ScalabilityModeParameters{
    172        .scalability_mode = ScalabilityMode::kL3T2_KEY,
    173        .name = "L3T2_KEY",
    174        .num_spatial_layers = 3,
    175        .num_temporal_layers = 2,
    176        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    177    },
    178    ScalabilityModeParameters{
    179        .scalability_mode = ScalabilityMode::kL3T3,
    180        .name = "L3T3",
    181        .num_spatial_layers = 3,
    182        .num_temporal_layers = 3,
    183        .inter_layer_pred = InterLayerPredMode::kOn,
    184    },
    185    ScalabilityModeParameters{
    186        .scalability_mode = ScalabilityMode::kL3T3h,
    187        .name = "L3T3h",
    188        .num_spatial_layers = 3,
    189        .num_temporal_layers = 3,
    190        .inter_layer_pred = InterLayerPredMode::kOn,
    191        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    192    },
    193    ScalabilityModeParameters{
    194        .scalability_mode = ScalabilityMode::kL3T3_KEY,
    195        .name = "L3T3_KEY",
    196        .num_spatial_layers = 3,
    197        .num_temporal_layers = 3,
    198        .inter_layer_pred = InterLayerPredMode::kOnKeyPic,
    199    },
    200    ScalabilityModeParameters{
    201        .scalability_mode = ScalabilityMode::kS2T1,
    202        .name = "S2T1",
    203        .num_spatial_layers = 2,
    204        .num_temporal_layers = 1,
    205        .inter_layer_pred = InterLayerPredMode::kOff,
    206    },
    207    ScalabilityModeParameters{
    208        .scalability_mode = ScalabilityMode::kS2T1h,
    209        .name = "S2T1h",
    210        .num_spatial_layers = 2,
    211        .num_temporal_layers = 1,
    212        .inter_layer_pred = InterLayerPredMode::kOff,
    213        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    214    },
    215    ScalabilityModeParameters{
    216        .scalability_mode = ScalabilityMode::kS2T2,
    217        .name = "S2T2",
    218        .num_spatial_layers = 2,
    219        .num_temporal_layers = 2,
    220        .inter_layer_pred = InterLayerPredMode::kOff,
    221    },
    222    ScalabilityModeParameters{
    223        .scalability_mode = ScalabilityMode::kS2T2h,
    224        .name = "S2T2h",
    225        .num_spatial_layers = 2,
    226        .num_temporal_layers = 2,
    227        .inter_layer_pred = InterLayerPredMode::kOff,
    228        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    229    },
    230    ScalabilityModeParameters{
    231        .scalability_mode = ScalabilityMode::kS2T3,
    232        .name = "S2T3",
    233        .num_spatial_layers = 2,
    234        .num_temporal_layers = 3,
    235        .inter_layer_pred = InterLayerPredMode::kOff,
    236    },
    237    ScalabilityModeParameters{
    238        .scalability_mode = ScalabilityMode::kS2T3h,
    239        .name = "S2T3h",
    240        .num_spatial_layers = 2,
    241        .num_temporal_layers = 3,
    242        .inter_layer_pred = InterLayerPredMode::kOff,
    243        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    244    },
    245    ScalabilityModeParameters{
    246        .scalability_mode = ScalabilityMode::kS3T1,
    247        .name = "S3T1",
    248        .num_spatial_layers = 3,
    249        .num_temporal_layers = 1,
    250        .inter_layer_pred = InterLayerPredMode::kOff,
    251    },
    252    ScalabilityModeParameters{
    253        .scalability_mode = ScalabilityMode::kS3T1h,
    254        .name = "S3T1h",
    255        .num_spatial_layers = 3,
    256        .num_temporal_layers = 1,
    257        .inter_layer_pred = InterLayerPredMode::kOff,
    258        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    259    },
    260    ScalabilityModeParameters{
    261        .scalability_mode = ScalabilityMode::kS3T2,
    262        .name = "S3T2",
    263        .num_spatial_layers = 3,
    264        .num_temporal_layers = 2,
    265        .inter_layer_pred = InterLayerPredMode::kOff,
    266    },
    267    ScalabilityModeParameters{
    268        .scalability_mode = ScalabilityMode::kS3T2h,
    269        .name = "S3T2h",
    270        .num_spatial_layers = 3,
    271        .num_temporal_layers = 2,
    272        .inter_layer_pred = InterLayerPredMode::kOff,
    273        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    274    },
    275    ScalabilityModeParameters{
    276        .scalability_mode = ScalabilityMode::kS3T3,
    277        .name = "S3T3",
    278        .num_spatial_layers = 3,
    279        .num_temporal_layers = 3,
    280        .inter_layer_pred = InterLayerPredMode::kOff,
    281    },
    282    ScalabilityModeParameters{
    283        .scalability_mode = ScalabilityMode::kS3T3h,
    284        .name = "S3T3h",
    285        .num_spatial_layers = 3,
    286        .num_temporal_layers = 3,
    287        .inter_layer_pred = InterLayerPredMode::kOff,
    288        .ratio = ScalabilityModeResolutionRatio::kThreeToTwo,
    289    },
    290 };
    291 
    292 // This could be replaced with std::all_of in c++20.
    293 constexpr bool CheckScalabilityModeParams() {
    294  static_assert(std::size(kScalabilityModeParams) == kNumScalabilityModes);
    295  for (size_t s = 0; s < kNumScalabilityModes; ++s) {
    296    if (kScalabilityModeParams[s].scalability_mode !=
    297        static_cast<ScalabilityMode>(s)) {
    298      return false;
    299    }
    300  }
    301  return true;
    302 }
    303 
    304 static_assert(CheckScalabilityModeParams(),
    305              "There is a scalability mode mismatch in the array!");
    306 
    307 constexpr auto Idx(ScalabilityMode s) {
    308  const auto index = static_cast<std::underlying_type_t<ScalabilityMode>>(s);
    309  RTC_CHECK_LT(index, kNumScalabilityModes);
    310  return index;
    311 }
    312 
    313 }  // namespace
    314 
    315 std::optional<ScalabilityMode> MakeScalabilityMode(
    316    int num_spatial_layers,
    317    int num_temporal_layers,
    318    InterLayerPredMode inter_layer_pred,
    319    std::optional<ScalabilityModeResolutionRatio> ratio,
    320    bool shift) {
    321  for (const auto& candidate_mode : kScalabilityModeParams) {
    322    if (candidate_mode.num_spatial_layers == num_spatial_layers &&
    323        candidate_mode.num_temporal_layers == num_temporal_layers) {
    324      if (num_spatial_layers == 1 ||
    325          (candidate_mode.inter_layer_pred == inter_layer_pred &&
    326           candidate_mode.ratio == ratio && candidate_mode.shift == shift)) {
    327        return candidate_mode.scalability_mode;
    328      }
    329    }
    330  }
    331  return std::nullopt;
    332 }
    333 
    334 std::optional<ScalabilityMode> ScalabilityModeFromString(
    335    absl::string_view mode_string) {
    336  const auto it =
    337      absl::c_find_if(kScalabilityModeParams,
    338                      [&](const ScalabilityModeParameters& candidate_mode) {
    339                        return candidate_mode.name == mode_string;
    340                      });
    341  if (it != std::end(kScalabilityModeParams)) {
    342    return it->scalability_mode;
    343  }
    344  return std::nullopt;
    345 }
    346 
    347 InterLayerPredMode ScalabilityModeToInterLayerPredMode(
    348    ScalabilityMode scalability_mode) {
    349  return kScalabilityModeParams[Idx(scalability_mode)].inter_layer_pred;
    350 }
    351 
    352 int ScalabilityModeToNumSpatialLayers(ScalabilityMode scalability_mode) {
    353  return kScalabilityModeParams[Idx(scalability_mode)].num_spatial_layers;
    354 }
    355 
    356 int ScalabilityModeToNumTemporalLayers(ScalabilityMode scalability_mode) {
    357  return kScalabilityModeParams[Idx(scalability_mode)].num_temporal_layers;
    358 }
    359 
    360 std::optional<ScalabilityModeResolutionRatio> ScalabilityModeToResolutionRatio(
    361    ScalabilityMode scalability_mode) {
    362  return kScalabilityModeParams[Idx(scalability_mode)].ratio;
    363 }
    364 
    365 ScalabilityMode LimitNumSpatialLayers(ScalabilityMode scalability_mode,
    366                                      int max_spatial_layers) {
    367  int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode);
    368  if (max_spatial_layers >= num_spatial_layers) {
    369    return scalability_mode;
    370  }
    371 
    372  switch (scalability_mode) {
    373    case ScalabilityMode::kL1T1:
    374      return ScalabilityMode::kL1T1;
    375    case ScalabilityMode::kL1T2:
    376      return ScalabilityMode::kL1T2;
    377    case ScalabilityMode::kL1T3:
    378      return ScalabilityMode::kL1T3;
    379    case ScalabilityMode::kL2T1:
    380      return ScalabilityMode::kL1T1;
    381    case ScalabilityMode::kL2T1h:
    382      return ScalabilityMode::kL1T1;
    383    case ScalabilityMode::kL2T1_KEY:
    384      return ScalabilityMode::kL1T1;
    385    case ScalabilityMode::kL2T2:
    386      return ScalabilityMode::kL1T2;
    387    case ScalabilityMode::kL2T2h:
    388      return ScalabilityMode::kL1T2;
    389    case ScalabilityMode::kL2T2_KEY:
    390      return ScalabilityMode::kL1T2;
    391    case ScalabilityMode::kL2T2_KEY_SHIFT:
    392      return ScalabilityMode::kL1T2;
    393    case ScalabilityMode::kL2T3:
    394      return ScalabilityMode::kL1T3;
    395    case ScalabilityMode::kL2T3h:
    396      return ScalabilityMode::kL1T3;
    397    case ScalabilityMode::kL2T3_KEY:
    398      return ScalabilityMode::kL1T3;
    399    case ScalabilityMode::kL3T1:
    400      return max_spatial_layers == 2 ? ScalabilityMode::kL2T1
    401                                     : ScalabilityMode::kL1T1;
    402    case ScalabilityMode::kL3T1h:
    403      return max_spatial_layers == 2 ? ScalabilityMode::kL2T1h
    404                                     : ScalabilityMode::kL1T1;
    405    case ScalabilityMode::kL3T1_KEY:
    406      return max_spatial_layers == 2 ? ScalabilityMode::kL2T1_KEY
    407                                     : ScalabilityMode::kL1T1;
    408    case ScalabilityMode::kL3T2:
    409      return max_spatial_layers == 2 ? ScalabilityMode::kL2T2
    410                                     : ScalabilityMode::kL1T2;
    411    case ScalabilityMode::kL3T2h:
    412      return max_spatial_layers == 2 ? ScalabilityMode::kL2T2h
    413                                     : ScalabilityMode::kL1T2;
    414    case ScalabilityMode::kL3T2_KEY:
    415      return max_spatial_layers == 2 ? ScalabilityMode::kL2T2_KEY
    416                                     : ScalabilityMode::kL1T2;
    417    case ScalabilityMode::kL3T3:
    418      return max_spatial_layers == 2 ? ScalabilityMode::kL2T3
    419                                     : ScalabilityMode::kL1T3;
    420    case ScalabilityMode::kL3T3h:
    421      return max_spatial_layers == 2 ? ScalabilityMode::kL2T3h
    422                                     : ScalabilityMode::kL1T3;
    423    case ScalabilityMode::kL3T3_KEY:
    424      return max_spatial_layers == 2 ? ScalabilityMode::kL2T3_KEY
    425                                     : ScalabilityMode::kL1T3;
    426    case ScalabilityMode::kS2T1:
    427      return ScalabilityMode::kL1T1;
    428    case ScalabilityMode::kS2T1h:
    429      return ScalabilityMode::kL1T1;
    430    case ScalabilityMode::kS2T2:
    431      return ScalabilityMode::kL1T2;
    432    case ScalabilityMode::kS2T2h:
    433      return ScalabilityMode::kL1T2;
    434    case ScalabilityMode::kS2T3:
    435      return ScalabilityMode::kL1T3;
    436    case ScalabilityMode::kS2T3h:
    437      return ScalabilityMode::kL1T3;
    438    case ScalabilityMode::kS3T1:
    439      return max_spatial_layers == 2 ? ScalabilityMode::kS2T1
    440                                     : ScalabilityMode::kL1T1;
    441    case ScalabilityMode::kS3T1h:
    442      return max_spatial_layers == 2 ? ScalabilityMode::kS2T1h
    443                                     : ScalabilityMode::kL1T1;
    444    case ScalabilityMode::kS3T2:
    445      return max_spatial_layers == 2 ? ScalabilityMode::kS2T2
    446                                     : ScalabilityMode::kL1T2;
    447    case ScalabilityMode::kS3T2h:
    448      return max_spatial_layers == 2 ? ScalabilityMode::kS2T2h
    449                                     : ScalabilityMode::kL1T2;
    450    case ScalabilityMode::kS3T3:
    451      return max_spatial_layers == 2 ? ScalabilityMode::kS2T3
    452                                     : ScalabilityMode::kL1T3;
    453    case ScalabilityMode::kS3T3h:
    454      return max_spatial_layers == 2 ? ScalabilityMode::kS2T3h
    455                                     : ScalabilityMode::kL1T3;
    456  }
    457  RTC_CHECK_NOTREACHED();
    458 }
    459 
    460 bool ScalabilityModeIsShiftMode(ScalabilityMode scalability_mode) {
    461  return kScalabilityModeParams[Idx(scalability_mode)].shift;
    462 }
    463 
    464 }  // namespace webrtc