Commit 18228481 authored by Michael Froman's avatar Michael Froman Committed by Connor Sheehan
Browse files

Bug 1766646 - Vendor libwebrtc from ea72ee6350

Upstream commit: https://webrtc.googlesource.com/src/+/ea72ee635016279e5fe12eebaff6d34900119154
    Add ClippingPredictorLevelBuffer circular buffer.

    Bug: webrtc:12774
    Change-Id: I2b26660e3fe051ab358dd5298ba5098f275943da
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219631


    Reviewed-by: default avatarMinyue Li <minyue@webrtc.org>
    Reviewed-by: default avatarAlessio Bazzica <alessiob@webrtc.org>
    Commit-Queue: Hanna Silen <silen@webrtc.org>
    Cr-Commit-Position: refs/heads/master@{#34167}
parent 506f6ca5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -6039,3 +6039,6 @@ cae1f1d47b
# MOZ_LIBWEBRTC_SRC=/home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src MOZ_LIBWEBRTC_COMMIT=mjfdev bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
4f26a3c7e8
# MOZ_LIBWEBRTC_SRC=/home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src MOZ_LIBWEBRTC_COMMIT=mjfdev bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
ea72ee6350
+2 −0
Original line number Diff line number Diff line
@@ -4028,3 +4028,5 @@ libwebrtc updated from /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwe
libwebrtc updated from /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src commit mjfdev on 2022-05-26T17:56:24.551075.
# python3 vendor-libwebrtc.py --from-local /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src --commit mjfdev libwebrtc
libwebrtc updated from /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src commit mjfdev on 2022-05-26T17:57:05.254837.
# python3 vendor-libwebrtc.py --from-local /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src --commit mjfdev libwebrtc
libwebrtc updated from /home/mfroman/git-checkouts/trial-webrtc-builds/moz-libwebrtc-checkout/src commit mjfdev on 2022-05-26T17:57:46.062493.
+14 −0
Original line number Diff line number Diff line
@@ -38,6 +38,18 @@ rtc_library("agc") {
  absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}

rtc_library("clipping_predictor_level_buffer") {
  sources = [
    "clipping_predictor_level_buffer.cc",
    "clipping_predictor_level_buffer.h",
  ]
  deps = [
    "../../../rtc_base:checks",
    "../../../rtc_base:logging",
  ]
  absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}

rtc_library("level_estimation") {
  sources = [
    "agc.cc",
@@ -96,6 +108,7 @@ if (rtc_include_tests) {
    testonly = true
    sources = [
      "agc_manager_direct_unittest.cc",
      "clipping_predictor_level_buffer_unittest.cc",
      "loudness_histogram_unittest.cc",
      "mock_agc.h",
    ]
@@ -103,6 +116,7 @@ if (rtc_include_tests) {

    deps = [
      ":agc",
      ":clipping_predictor_level_buffer",
      ":gain_control_interface",
      ":level_estimation",
      "..:mocks",
+77 −0
Original line number Diff line number Diff line
/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/agc/clipping_predictor_level_buffer.h"

#include <algorithm>
#include <cmath>

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

bool ClippingPredictorLevelBuffer::Level::operator==(const Level& level) const {
  constexpr float kEpsilon = 1e-6f;
  return std::fabs(average - level.average) < kEpsilon &&
         std::fabs(max - level.max) < kEpsilon;
}

ClippingPredictorLevelBuffer::ClippingPredictorLevelBuffer(int capacity)
    : tail_(-1), size_(0), data_(std::max(1, capacity)) {
  if (capacity > kMaxCapacity) {
    RTC_LOG(LS_WARNING) << "[agc]: ClippingPredictorLevelBuffer exceeds the "
                        << "maximum allowed capacity. Capacity: " << capacity;
  }
  RTC_DCHECK(!data_.empty());
}

void ClippingPredictorLevelBuffer::Reset() {
  tail_ = -1;
  size_ = 0;
}

void ClippingPredictorLevelBuffer::Push(Level level) {
  ++tail_;
  if (tail_ == Capacity()) {
    tail_ = 0;
  }
  if (size_ < Capacity()) {
    size_++;
  }
  data_[tail_] = level;
}

// TODO(bugs.webrtc.org/12774): Optimize partial computation for long buffers.
absl::optional<ClippingPredictorLevelBuffer::Level>
ClippingPredictorLevelBuffer::ComputePartialMetrics(int delay,
                                                    int num_items) const {
  RTC_DCHECK_GE(delay, 0);
  RTC_DCHECK_LT(delay, Capacity());
  RTC_DCHECK_GT(num_items, 0);
  RTC_DCHECK_LE(num_items, Capacity());
  RTC_DCHECK_LE(delay + num_items, Capacity());
  if (delay + num_items > Size()) {
    return absl::nullopt;
  }
  float sum = 0.0f;
  float max = 0.0f;
  for (int i = 0; i < num_items && i < Size(); ++i) {
    int idx = tail_ - delay - i;
    if (idx < 0) {
      idx += Capacity();
    }
    sum += data_[idx].average;
    max = std::fmax(data_[idx].max, max);
  }
  return absl::optional<Level>({sum / static_cast<float>(num_items), max});
}

}  // namespace webrtc
+71 −0
Original line number Diff line number Diff line
/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_LEVEL_BUFFER_H_
#define MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_LEVEL_BUFFER_H_

#include <memory>
#include <vector>

#include "absl/types/optional.h"

namespace webrtc {

// A circular buffer to store frame-wise `Level` items for clipping prediction.
// The current implementation is not optimized for large buffer lengths.
class ClippingPredictorLevelBuffer {
 public:
  struct Level {
    float average;
    float max;
    bool operator==(const Level& level) const;
  };

  // Recommended maximum capacity. It is possible to create a buffer with a
  // larger capacity, but the implementation is not optimized for large values.
  static constexpr int kMaxCapacity = 100;

  // Ctor. Sets the buffer capacity to max(1, `capacity`) and logs a warning
  // message if the capacity is greater than `kMaxCapacity`.
  explicit ClippingPredictorLevelBuffer(int capacity);
  ~ClippingPredictorLevelBuffer() {}
  ClippingPredictorLevelBuffer(const ClippingPredictorLevelBuffer&) = delete;
  ClippingPredictorLevelBuffer& operator=(const ClippingPredictorLevelBuffer&) =
      delete;

  void Reset();

  // Returns the current number of items stored in the buffer.
  int Size() const { return size_; }

  // Returns the capacity of the buffer.
  int Capacity() const { return data_.size(); }

  // Adds a `level` item into the circular buffer `data_`. Stores at most
  // `Capacity()` items. If more items are pushed, the new item replaces the
  // least recently pushed item.
  void Push(Level level);

  // If at least `num_items` + `delay` items have been pushed, returns the
  // average and maximum value for the `num_items` most recently pushed items
  // from `delay` to `delay` - `num_items` (a delay equal to zero corresponds
  // to the most recently pushed item). The value of `delay` is limited to
  // [0, N] and `num_items` to [1, M] where N + M is the capacity of the buffer.
  absl::optional<Level> ComputePartialMetrics(int delay, int num_items) const;

 private:
  int tail_;
  int size_;
  std::vector<Level> data_;
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_PROCESSING_AGC_CLIPPING_PREDICTOR_LEVEL_BUFFER_H_
Loading