tor-browser

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

framerate_controller.cc (2792B)


      1 /*
      2 *  Copyright 2021 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 "common_video/framerate_controller.h"
     12 
     13 #include <cstdint>
     14 #include <cstdlib>
     15 #include <limits>
     16 #include <optional>
     17 
     18 #include "rtc_base/time_utils.h"
     19 
     20 namespace webrtc {
     21 namespace {
     22 constexpr double kMinFramerate = 0.5;
     23 }  // namespace
     24 
     25 FramerateController::FramerateController()
     26    : FramerateController(std::numeric_limits<double>::max()) {}
     27 
     28 FramerateController::FramerateController(double max_framerate)
     29    : max_framerate_(max_framerate) {}
     30 
     31 FramerateController::~FramerateController() {}
     32 
     33 void FramerateController::SetMaxFramerate(double max_framerate) {
     34  max_framerate_ = max_framerate;
     35 }
     36 
     37 double FramerateController::GetMaxFramerate() const {
     38  return max_framerate_;
     39 }
     40 
     41 bool FramerateController::ShouldDropFrame(int64_t in_timestamp_ns) {
     42  if (max_framerate_ < kMinFramerate)
     43    return true;
     44 
     45  // If `max_framerate_` is not set (i.e. maxdouble), `frame_interval_ns` is
     46  // rounded to 0.
     47  int64_t frame_interval_ns = kNumNanosecsPerSec / max_framerate_;
     48  if (frame_interval_ns <= 0) {
     49    // Frame rate throttling not enabled.
     50    return false;
     51  }
     52 
     53  if (next_frame_timestamp_ns_) {
     54    // Time until next frame should be outputted.
     55    const int64_t time_until_next_frame_ns =
     56        (*next_frame_timestamp_ns_ - in_timestamp_ns);
     57    // Continue if timestamp is within expected range.
     58    if (std::abs(time_until_next_frame_ns) < 2 * frame_interval_ns) {
     59      // Drop if a frame shouldn't be outputted yet.
     60      if (time_until_next_frame_ns > 0)
     61        return true;
     62      // Time to output new frame.
     63      *next_frame_timestamp_ns_ += frame_interval_ns;
     64      return false;
     65    }
     66  }
     67 
     68  // First timestamp received or timestamp is way outside expected range, so
     69  // reset. Set first timestamp target to just half the interval to prefer
     70  // keeping frames in case of jitter.
     71  next_frame_timestamp_ns_ = in_timestamp_ns + frame_interval_ns / 2;
     72  return false;
     73 }
     74 
     75 void FramerateController::Reset() {
     76  max_framerate_ = std::numeric_limits<double>::max();
     77  next_frame_timestamp_ns_ = std::nullopt;
     78 }
     79 
     80 void FramerateController::KeepFrame(int64_t in_timestamp_ns) {
     81  if (ShouldDropFrame(in_timestamp_ns)) {
     82    if (max_framerate_ < kMinFramerate)
     83      return;
     84 
     85    int64_t frame_interval_ns = kNumNanosecsPerSec / max_framerate_;
     86    if (next_frame_timestamp_ns_)
     87      *next_frame_timestamp_ns_ += frame_interval_ns;
     88  }
     89 }
     90 
     91 }  // namespace webrtc