tor-browser

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

fec_controller_default.cc (8566B)


      1 /*
      2 *  Copyright (c) 2016 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/fec_controller_default.h"  // NOLINT
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <cstdlib>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "api/environment/environment.h"
     20 #include "api/fec_controller.h"
     21 #include "api/field_trials_view.h"
     22 #include "api/video/video_frame_type.h"
     23 #include "modules/include/module_fec_types.h"
     24 #include "modules/video_coding/media_opt_util.h"
     25 #include "rtc_base/logging.h"
     26 #include "rtc_base/synchronization/mutex.h"
     27 #include "system_wrappers/include/clock.h"
     28 
     29 namespace webrtc {
     30 
     31 const float kProtectionOverheadRateThreshold = 0.5;
     32 
     33 FecControllerDefault::FecControllerDefault(
     34    const Environment& env,
     35    VCMProtectionCallback* protection_callback)
     36    : env_(env),
     37      protection_callback_(protection_callback),
     38      loss_prot_logic_(new media_optimization::VCMLossProtectionLogic(env_)),
     39      max_payload_size_(1460),
     40      overhead_threshold_(GetProtectionOverheadRateThreshold()) {}
     41 
     42 FecControllerDefault::FecControllerDefault(const Environment& env)
     43    : FecControllerDefault(env, nullptr) {}
     44 
     45 FecControllerDefault::~FecControllerDefault(void) {
     46  loss_prot_logic_->Release();
     47 }
     48 
     49 void FecControllerDefault::SetProtectionCallback(
     50    VCMProtectionCallback* protection_callback) {
     51  protection_callback_ = protection_callback;
     52 }
     53 
     54 void FecControllerDefault::SetEncodingData(size_t width,
     55                                           size_t height,
     56                                           size_t num_temporal_layers,
     57                                           size_t max_payload_size) {
     58  MutexLock lock(&mutex_);
     59  loss_prot_logic_->UpdateFrameSize(width, height);
     60  loss_prot_logic_->UpdateNumLayers(num_temporal_layers);
     61  max_payload_size_ = max_payload_size;
     62 }
     63 
     64 float FecControllerDefault::GetProtectionOverheadRateThreshold() {
     65  float overhead_threshold =
     66      strtof(env_.field_trials()
     67                 .Lookup("WebRTC-ProtectionOverheadRateThreshold")
     68                 .c_str(),
     69             nullptr);
     70  if (overhead_threshold > 0 && overhead_threshold <= 1) {
     71    RTC_LOG(LS_INFO) << "ProtectionOverheadRateThreshold is set to "
     72                     << overhead_threshold;
     73    return overhead_threshold;
     74  } else if (overhead_threshold < 0 || overhead_threshold > 1) {
     75    RTC_LOG(LS_WARNING)
     76        << "ProtectionOverheadRateThreshold field trial is set to "
     77           "an invalid value, expecting a value between (0, 1].";
     78  }
     79  // WebRTC-ProtectionOverheadRateThreshold field trial string is not found, use
     80  // the default value.
     81  return kProtectionOverheadRateThreshold;
     82 }
     83 
     84 uint32_t FecControllerDefault::UpdateFecRates(
     85    uint32_t estimated_bitrate_bps,
     86    int actual_framerate_fps,
     87    uint8_t fraction_lost,
     88    std::vector<bool> /* loss_mask_vector */,
     89    int64_t round_trip_time_ms) {
     90  float target_bitrate_kbps =
     91      static_cast<float>(estimated_bitrate_bps) / 1000.0f;
     92  // Sanity check.
     93  if (actual_framerate_fps < 1.0) {
     94    actual_framerate_fps = 1.0;
     95  }
     96  FecProtectionParams delta_fec_params;
     97  FecProtectionParams key_fec_params;
     98  {
     99    MutexLock lock(&mutex_);
    100    loss_prot_logic_->UpdateBitRate(target_bitrate_kbps);
    101    loss_prot_logic_->UpdateRtt(round_trip_time_ms);
    102    // Update frame rate for the loss protection logic class: frame rate should
    103    // be the actual/sent rate.
    104    loss_prot_logic_->UpdateFrameRate(actual_framerate_fps);
    105    // Returns the filtered packet loss, used for the protection setting.
    106    // The filtered loss may be the received loss (no filter), or some
    107    // filtered value (average or max window filter).
    108    // Use max window filter for now.
    109    media_optimization::FilterPacketLossMode filter_mode =
    110        media_optimization::kMaxFilter;
    111    uint8_t packet_loss_enc = loss_prot_logic_->FilteredLoss(
    112        env_.clock().TimeInMilliseconds(), filter_mode, fraction_lost);
    113    // For now use the filtered loss for computing the robustness settings.
    114    loss_prot_logic_->UpdateFilteredLossPr(packet_loss_enc);
    115    if (loss_prot_logic_->SelectedType() == media_optimization::kNone) {
    116      return estimated_bitrate_bps;
    117    }
    118    // Update method will compute the robustness settings for the given
    119    // protection method and the overhead cost
    120    // the protection method is set by the user via SetVideoProtection.
    121    loss_prot_logic_->UpdateMethod();
    122    // Get the bit cost of protection method, based on the amount of
    123    // overhead data actually transmitted (including headers) the last
    124    // second.
    125    // Get the FEC code rate for Key frames (set to 0 when NA).
    126    key_fec_params.fec_rate =
    127        loss_prot_logic_->SelectedMethod()->RequiredProtectionFactorK();
    128    // Get the FEC code rate for Delta frames (set to 0 when NA).
    129    delta_fec_params.fec_rate =
    130        loss_prot_logic_->SelectedMethod()->RequiredProtectionFactorD();
    131    // The RTP module currently requires the same `max_fec_frames` for both
    132    // key and delta frames.
    133    delta_fec_params.max_fec_frames =
    134        loss_prot_logic_->SelectedMethod()->MaxFramesFec();
    135    key_fec_params.max_fec_frames =
    136        loss_prot_logic_->SelectedMethod()->MaxFramesFec();
    137  }
    138  // Set the FEC packet mask type. `kFecMaskBursty` is more effective for
    139  // consecutive losses and little/no packet re-ordering. As we currently
    140  // do not have feedback data on the degree of correlated losses and packet
    141  // re-ordering, we keep default setting to `kFecMaskRandom` for now.
    142  delta_fec_params.fec_mask_type = kFecMaskRandom;
    143  key_fec_params.fec_mask_type = kFecMaskRandom;
    144  // Update protection callback with protection settings.
    145  uint32_t sent_video_rate_bps = 0;
    146  uint32_t sent_nack_rate_bps = 0;
    147  uint32_t sent_fec_rate_bps = 0;
    148  // Rate cost of the protection methods.
    149  float protection_overhead_rate = 0.0f;
    150  // TODO(Marco): Pass FEC protection values per layer.
    151  protection_callback_->ProtectionRequest(
    152      &delta_fec_params, &key_fec_params, &sent_video_rate_bps,
    153      &sent_nack_rate_bps, &sent_fec_rate_bps);
    154  uint32_t sent_total_rate_bps =
    155      sent_video_rate_bps + sent_nack_rate_bps + sent_fec_rate_bps;
    156  // Estimate the overhead costs of the next second as staying the same
    157  // wrt the source bitrate.
    158  if (sent_total_rate_bps > 0) {
    159    protection_overhead_rate =
    160        static_cast<float>(sent_nack_rate_bps + sent_fec_rate_bps) /
    161        sent_total_rate_bps;
    162  }
    163  // Cap the overhead estimate to a threshold, default is 50%.
    164  protection_overhead_rate =
    165      std::min(protection_overhead_rate, overhead_threshold_);
    166  // Source coding rate: total rate - protection overhead.
    167  return estimated_bitrate_bps * (1.0 - protection_overhead_rate);
    168 }
    169 
    170 void FecControllerDefault::SetProtectionMethod(bool enable_fec,
    171                                               bool enable_nack) {
    172  media_optimization::VCMProtectionMethodEnum method(media_optimization::kNone);
    173  if (enable_fec && enable_nack) {
    174    method = media_optimization::kNackFec;
    175  } else if (enable_nack) {
    176    method = media_optimization::kNack;
    177  } else if (enable_fec) {
    178    method = media_optimization::kFec;
    179  }
    180  MutexLock lock(&mutex_);
    181  loss_prot_logic_->SetMethod(method);
    182 }
    183 
    184 void FecControllerDefault::UpdateWithEncodedData(
    185    const size_t encoded_image_length,
    186    const VideoFrameType encoded_image_frametype) {
    187  const size_t encoded_length = encoded_image_length;
    188  MutexLock lock(&mutex_);
    189  if (encoded_length > 0) {
    190    const bool delta_frame =
    191        encoded_image_frametype != VideoFrameType::kVideoFrameKey;
    192    if (max_payload_size_ > 0 && encoded_length > 0) {
    193      const float min_packets_per_frame =
    194          encoded_length / static_cast<float>(max_payload_size_);
    195      if (delta_frame) {
    196        loss_prot_logic_->UpdatePacketsPerFrame(
    197            min_packets_per_frame, env_.clock().TimeInMilliseconds());
    198      } else {
    199        loss_prot_logic_->UpdatePacketsPerFrameKey(
    200            min_packets_per_frame, env_.clock().TimeInMilliseconds());
    201      }
    202    }
    203    if (!delta_frame && encoded_length > 0) {
    204      loss_prot_logic_->UpdateKeyFrameSize(static_cast<float>(encoded_length));
    205    }
    206  }
    207 }
    208 
    209 bool FecControllerDefault::UseLossVectorMask() {
    210  return false;
    211 }
    212 
    213 }  // namespace webrtc