tor-browser

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

frame_blocker_unittest.cc (17001B)


      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/audio_processing/aec3/frame_blocker.h"
     12 
     13 #include <cstddef>
     14 #include <string>
     15 #include <vector>
     16 
     17 #include "api/array_view.h"
     18 #include "modules/audio_processing/aec3/aec3_common.h"
     19 #include "modules/audio_processing/aec3/block.h"
     20 #include "modules/audio_processing/aec3/block_framer.h"
     21 #include "rtc_base/checks.h"
     22 #include "rtc_base/strings/string_builder.h"
     23 #include "test/gtest.h"
     24 
     25 namespace webrtc {
     26 namespace {
     27 
     28 float ComputeSampleValue(size_t chunk_counter,
     29                         size_t chunk_size,
     30                         size_t band,
     31                         size_t channel,
     32                         size_t sample_index,
     33                         int offset) {
     34  float value =
     35      static_cast<int>(chunk_counter * chunk_size + sample_index + channel) +
     36      offset;
     37  return value > 0 ? 5000 * band + value : 0;
     38 }
     39 
     40 void FillSubFrame(size_t sub_frame_counter,
     41                  int offset,
     42                  std::vector<std::vector<std::vector<float>>>* sub_frame) {
     43  for (size_t band = 0; band < sub_frame->size(); ++band) {
     44    for (size_t channel = 0; channel < (*sub_frame)[band].size(); ++channel) {
     45      for (size_t sample = 0; sample < (*sub_frame)[band][channel].size();
     46           ++sample) {
     47        (*sub_frame)[band][channel][sample] = ComputeSampleValue(
     48            sub_frame_counter, kSubFrameLength, band, channel, sample, offset);
     49      }
     50    }
     51  }
     52 }
     53 
     54 void FillSubFrameView(
     55    size_t sub_frame_counter,
     56    int offset,
     57    std::vector<std::vector<std::vector<float>>>* sub_frame,
     58    std::vector<std::vector<ArrayView<float>>>* sub_frame_view) {
     59  FillSubFrame(sub_frame_counter, offset, sub_frame);
     60  for (size_t band = 0; band < sub_frame_view->size(); ++band) {
     61    for (size_t channel = 0; channel < (*sub_frame_view)[band].size();
     62         ++channel) {
     63      (*sub_frame_view)[band][channel] = ArrayView<float>(
     64          &(*sub_frame)[band][channel][0], (*sub_frame)[band][channel].size());
     65    }
     66  }
     67 }
     68 
     69 bool VerifySubFrame(
     70    size_t sub_frame_counter,
     71    int offset,
     72    const std::vector<std::vector<ArrayView<float>>>& sub_frame_view) {
     73  std::vector<std::vector<std::vector<float>>> reference_sub_frame(
     74      sub_frame_view.size(),
     75      std::vector<std::vector<float>>(
     76          sub_frame_view[0].size(),
     77          std::vector<float>(sub_frame_view[0][0].size(), 0.f)));
     78  FillSubFrame(sub_frame_counter, offset, &reference_sub_frame);
     79  for (size_t band = 0; band < sub_frame_view.size(); ++band) {
     80    for (size_t channel = 0; channel < sub_frame_view[band].size(); ++channel) {
     81      for (size_t sample = 0; sample < sub_frame_view[band][channel].size();
     82           ++sample) {
     83        if (reference_sub_frame[band][channel][sample] !=
     84            sub_frame_view[band][channel][sample]) {
     85          return false;
     86        }
     87      }
     88    }
     89  }
     90  return true;
     91 }
     92 
     93 bool VerifyBlock(size_t block_counter, int offset, const Block& block) {
     94  for (int band = 0; band < block.NumBands(); ++band) {
     95    for (int channel = 0; channel < block.NumChannels(); ++channel) {
     96      for (size_t sample = 0; sample < kBlockSize; ++sample) {
     97        auto it = block.begin(band, channel) + sample;
     98        const float reference_value = ComputeSampleValue(
     99            block_counter, kBlockSize, band, channel, sample, offset);
    100        if (reference_value != *it) {
    101          return false;
    102        }
    103      }
    104    }
    105  }
    106  return true;
    107 }
    108 
    109 // Verifies that the FrameBlocker properly forms blocks out of the frames.
    110 void RunBlockerTest(int sample_rate_hz, size_t num_channels) {
    111  constexpr size_t kNumSubFramesToProcess = 20;
    112  const size_t num_bands = NumBandsForRate(sample_rate_hz);
    113 
    114  Block block(num_bands, num_channels);
    115  std::vector<std::vector<std::vector<float>>> input_sub_frame(
    116      num_bands, std::vector<std::vector<float>>(
    117                     num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    118  std::vector<std::vector<ArrayView<float>>> input_sub_frame_view(
    119      num_bands, std::vector<ArrayView<float>>(num_channels));
    120  FrameBlocker blocker(num_bands, num_channels);
    121 
    122  size_t block_counter = 0;
    123  for (size_t sub_frame_index = 0; sub_frame_index < kNumSubFramesToProcess;
    124       ++sub_frame_index) {
    125    FillSubFrameView(sub_frame_index, 0, &input_sub_frame,
    126                     &input_sub_frame_view);
    127 
    128    blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &block);
    129    VerifyBlock(block_counter++, 0, block);
    130 
    131    if ((sub_frame_index + 1) % 4 == 0) {
    132      EXPECT_TRUE(blocker.IsBlockAvailable());
    133    } else {
    134      EXPECT_FALSE(blocker.IsBlockAvailable());
    135    }
    136    if (blocker.IsBlockAvailable()) {
    137      blocker.ExtractBlock(&block);
    138      VerifyBlock(block_counter++, 0, block);
    139    }
    140  }
    141 }
    142 
    143 // Verifies that the FrameBlocker and BlockFramer work well together and produce
    144 // the expected output.
    145 void RunBlockerAndFramerTest(int sample_rate_hz, size_t num_channels) {
    146  const size_t kNumSubFramesToProcess = 20;
    147  const size_t num_bands = NumBandsForRate(sample_rate_hz);
    148 
    149  Block block(num_bands, num_channels);
    150  std::vector<std::vector<std::vector<float>>> input_sub_frame(
    151      num_bands, std::vector<std::vector<float>>(
    152                     num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    153  std::vector<std::vector<std::vector<float>>> output_sub_frame(
    154      num_bands, std::vector<std::vector<float>>(
    155                     num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    156  std::vector<std::vector<ArrayView<float>>> output_sub_frame_view(
    157      num_bands, std::vector<ArrayView<float>>(num_channels));
    158  std::vector<std::vector<ArrayView<float>>> input_sub_frame_view(
    159      num_bands, std::vector<ArrayView<float>>(num_channels));
    160  FrameBlocker blocker(num_bands, num_channels);
    161  BlockFramer framer(num_bands, num_channels);
    162 
    163  for (size_t sub_frame_index = 0; sub_frame_index < kNumSubFramesToProcess;
    164       ++sub_frame_index) {
    165    FillSubFrameView(sub_frame_index, 0, &input_sub_frame,
    166                     &input_sub_frame_view);
    167    FillSubFrameView(sub_frame_index, 0, &output_sub_frame,
    168                     &output_sub_frame_view);
    169 
    170    blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &block);
    171    framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view);
    172 
    173    if ((sub_frame_index + 1) % 4 == 0) {
    174      EXPECT_TRUE(blocker.IsBlockAvailable());
    175    } else {
    176      EXPECT_FALSE(blocker.IsBlockAvailable());
    177    }
    178    if (blocker.IsBlockAvailable()) {
    179      blocker.ExtractBlock(&block);
    180      framer.InsertBlock(block);
    181    }
    182    if (sub_frame_index > 1) {
    183      EXPECT_TRUE(VerifySubFrame(sub_frame_index, -64, output_sub_frame_view));
    184    }
    185  }
    186 }
    187 
    188 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    189 // Verifies that the FrameBlocker crashes if the InsertSubFrameAndExtractBlock
    190 // method is called for inputs with the wrong number of bands or band lengths.
    191 void RunWronglySizedInsertAndExtractParametersTest(
    192    int sample_rate_hz,
    193    size_t correct_num_channels,
    194    size_t num_block_bands,
    195    size_t num_block_channels,
    196    size_t num_sub_frame_bands,
    197    size_t num_sub_frame_channels,
    198    size_t sub_frame_length) {
    199  const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
    200 
    201  Block block(num_block_bands, num_block_channels);
    202  std::vector<std::vector<std::vector<float>>> input_sub_frame(
    203      num_sub_frame_bands,
    204      std::vector<std::vector<float>>(
    205          num_sub_frame_channels, std::vector<float>(sub_frame_length, 0.f)));
    206  std::vector<std::vector<ArrayView<float>>> input_sub_frame_view(
    207      input_sub_frame.size(),
    208      std::vector<ArrayView<float>>(num_sub_frame_channels));
    209  FillSubFrameView(0, 0, &input_sub_frame, &input_sub_frame_view);
    210  FrameBlocker blocker(correct_num_bands, correct_num_channels);
    211  EXPECT_DEATH(
    212      blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &block), "");
    213 }
    214 
    215 // Verifies that the FrameBlocker crashes if the ExtractBlock method is called
    216 // for inputs with the wrong number of bands or band lengths.
    217 void RunWronglySizedExtractParameterTest(int sample_rate_hz,
    218                                         size_t correct_num_channels,
    219                                         size_t num_block_bands,
    220                                         size_t num_block_channels) {
    221  const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
    222 
    223  Block correct_block(correct_num_bands, correct_num_channels);
    224  Block wrong_block(num_block_bands, num_block_channels);
    225  std::vector<std::vector<std::vector<float>>> input_sub_frame(
    226      correct_num_bands,
    227      std::vector<std::vector<float>>(
    228          correct_num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    229  std::vector<std::vector<ArrayView<float>>> input_sub_frame_view(
    230      input_sub_frame.size(),
    231      std::vector<ArrayView<float>>(correct_num_channels));
    232  FillSubFrameView(0, 0, &input_sub_frame, &input_sub_frame_view);
    233  FrameBlocker blocker(correct_num_bands, correct_num_channels);
    234  blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &correct_block);
    235  blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &correct_block);
    236  blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &correct_block);
    237  blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &correct_block);
    238 
    239  EXPECT_DEATH(blocker.ExtractBlock(&wrong_block), "");
    240 }
    241 
    242 // Verifies that the FrameBlocker crashes if the ExtractBlock method is called
    243 // after a wrong number of previous InsertSubFrameAndExtractBlock method calls
    244 // have been made.
    245 void RunWrongExtractOrderTest(int sample_rate_hz,
    246                              size_t num_channels,
    247                              size_t num_preceeding_api_calls) {
    248  const size_t num_bands = NumBandsForRate(sample_rate_hz);
    249 
    250  Block block(num_bands, num_channels);
    251  std::vector<std::vector<std::vector<float>>> input_sub_frame(
    252      num_bands, std::vector<std::vector<float>>(
    253                     num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    254  std::vector<std::vector<ArrayView<float>>> input_sub_frame_view(
    255      input_sub_frame.size(), std::vector<ArrayView<float>>(num_channels));
    256  FillSubFrameView(0, 0, &input_sub_frame, &input_sub_frame_view);
    257  FrameBlocker blocker(num_bands, num_channels);
    258  for (size_t k = 0; k < num_preceeding_api_calls; ++k) {
    259    blocker.InsertSubFrameAndExtractBlock(input_sub_frame_view, &block);
    260  }
    261 
    262  EXPECT_DEATH(blocker.ExtractBlock(&block), "");
    263 }
    264 #endif
    265 
    266 std::string ProduceDebugText(int sample_rate_hz, size_t num_channels) {
    267  StringBuilder ss;
    268  ss << "Sample rate: " << sample_rate_hz;
    269  ss << ", number of channels: " << num_channels;
    270  return ss.Release();
    271 }
    272 
    273 }  // namespace
    274 
    275 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    276 TEST(FrameBlockerDeathTest,
    277     WrongNumberOfBandsInBlockForInsertSubFrameAndExtractBlock) {
    278  for (auto rate : {16000, 32000, 48000}) {
    279    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    280      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    281      const size_t correct_num_bands = NumBandsForRate(rate);
    282      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    283      RunWronglySizedInsertAndExtractParametersTest(
    284          rate, correct_num_channels, wrong_num_bands, correct_num_channels,
    285          correct_num_bands, correct_num_channels, kSubFrameLength);
    286    }
    287  }
    288 }
    289 
    290 TEST(FrameBlockerDeathTest,
    291     WrongNumberOfChannelsInBlockForInsertSubFrameAndExtractBlock) {
    292  for (auto rate : {16000, 32000, 48000}) {
    293    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    294      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    295      const size_t correct_num_bands = NumBandsForRate(rate);
    296      const size_t wrong_num_channels = correct_num_channels + 1;
    297      RunWronglySizedInsertAndExtractParametersTest(
    298          rate, correct_num_channels, correct_num_bands, wrong_num_channels,
    299          correct_num_bands, correct_num_channels, kSubFrameLength);
    300    }
    301  }
    302 }
    303 
    304 TEST(FrameBlockerDeathTest,
    305     WrongNumberOfBandsInSubFrameForInsertSubFrameAndExtractBlock) {
    306  for (auto rate : {16000, 32000, 48000}) {
    307    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    308      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    309      const size_t correct_num_bands = NumBandsForRate(rate);
    310      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    311      RunWronglySizedInsertAndExtractParametersTest(
    312          rate, correct_num_channels, correct_num_bands, correct_num_channels,
    313          wrong_num_bands, correct_num_channels, kSubFrameLength);
    314    }
    315  }
    316 }
    317 
    318 TEST(FrameBlockerDeathTest,
    319     WrongNumberOfChannelsInSubFrameForInsertSubFrameAndExtractBlock) {
    320  for (auto rate : {16000, 32000, 48000}) {
    321    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    322      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    323      const size_t correct_num_bands = NumBandsForRate(rate);
    324      const size_t wrong_num_channels = correct_num_channels + 1;
    325      RunWronglySizedInsertAndExtractParametersTest(
    326          rate, correct_num_channels, correct_num_bands, wrong_num_channels,
    327          correct_num_bands, wrong_num_channels, kSubFrameLength);
    328    }
    329  }
    330 }
    331 
    332 TEST(FrameBlockerDeathTest,
    333     WrongNumberOfSamplesInSubFrameForInsertSubFrameAndExtractBlock) {
    334  for (auto rate : {16000, 32000, 48000}) {
    335    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    336      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    337      const size_t correct_num_bands = NumBandsForRate(rate);
    338      RunWronglySizedInsertAndExtractParametersTest(
    339          rate, correct_num_channels, correct_num_bands, correct_num_channels,
    340          correct_num_bands, correct_num_channels, kSubFrameLength - 1);
    341    }
    342  }
    343 }
    344 
    345 TEST(FrameBlockerDeathTest, WrongNumberOfBandsInBlockForExtractBlock) {
    346  for (auto rate : {16000, 32000, 48000}) {
    347    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    348      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    349      const size_t correct_num_bands = NumBandsForRate(rate);
    350      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    351      RunWronglySizedExtractParameterTest(
    352          rate, correct_num_channels, wrong_num_bands, correct_num_channels);
    353    }
    354  }
    355 }
    356 
    357 TEST(FrameBlockerDeathTest, WrongNumberOfChannelsInBlockForExtractBlock) {
    358  for (auto rate : {16000, 32000, 48000}) {
    359    for (size_t correct_num_channels : {1, 2, 4, 8}) {
    360      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    361      const size_t correct_num_bands = NumBandsForRate(rate);
    362      const size_t wrong_num_channels = correct_num_channels + 1;
    363      RunWronglySizedExtractParameterTest(
    364          rate, correct_num_channels, correct_num_bands, wrong_num_channels);
    365    }
    366  }
    367 }
    368 
    369 TEST(FrameBlockerDeathTest, WrongNumberOfPreceedingApiCallsForExtractBlock) {
    370  for (auto rate : {16000, 32000, 48000}) {
    371    for (size_t num_channels : {1, 2, 4, 8}) {
    372      for (size_t num_calls = 0; num_calls < 4; ++num_calls) {
    373        StringBuilder ss;
    374        ss << "Sample rate: " << rate;
    375        ss << "Num channels: " << num_channels;
    376        ss << ", Num preceeding InsertSubFrameAndExtractBlock calls: "
    377           << num_calls;
    378 
    379        SCOPED_TRACE(ss.str());
    380        RunWrongExtractOrderTest(rate, num_channels, num_calls);
    381      }
    382    }
    383  }
    384 }
    385 
    386 // Verifies that the verification for 0 number of channels works.
    387 TEST(FrameBlockerDeathTest, ZeroNumberOfChannelsParameter) {
    388  EXPECT_DEATH(FrameBlocker(16000, 0), "");
    389 }
    390 
    391 // Verifies that the verification for 0 number of bands works.
    392 TEST(FrameBlockerDeathTest, ZeroNumberOfBandsParameter) {
    393  EXPECT_DEATH(FrameBlocker(0, 1), "");
    394 }
    395 
    396 // Verifiers that the verification for null sub_frame pointer works.
    397 TEST(FrameBlockerDeathTest, NullBlockParameter) {
    398  std::vector<std::vector<std::vector<float>>> sub_frame(
    399      1, std::vector<std::vector<float>>(
    400             1, std::vector<float>(kSubFrameLength, 0.f)));
    401  std::vector<std::vector<ArrayView<float>>> sub_frame_view(sub_frame.size());
    402  FillSubFrameView(0, 0, &sub_frame, &sub_frame_view);
    403  EXPECT_DEATH(
    404      FrameBlocker(1, 1).InsertSubFrameAndExtractBlock(sub_frame_view, nullptr),
    405      "");
    406 }
    407 
    408 #endif
    409 
    410 TEST(FrameBlocker, BlockBitexactness) {
    411  for (auto rate : {16000, 32000, 48000}) {
    412    for (size_t num_channels : {1, 2, 4, 8}) {
    413      SCOPED_TRACE(ProduceDebugText(rate, num_channels));
    414      RunBlockerTest(rate, num_channels);
    415    }
    416  }
    417 }
    418 
    419 TEST(FrameBlocker, BlockerAndFramer) {
    420  for (auto rate : {16000, 32000, 48000}) {
    421    for (size_t num_channels : {1, 2, 4, 8}) {
    422      SCOPED_TRACE(ProduceDebugText(rate, num_channels));
    423      RunBlockerAndFramerTest(rate, num_channels);
    424    }
    425  }
    426 }
    427 
    428 }  // namespace webrtc