tor-browser

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

block_framer_unittest.cc (13458B)


      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/block_framer.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 "rtc_base/checks.h"
     21 #include "rtc_base/strings/string_builder.h"
     22 #include "test/gtest.h"
     23 
     24 namespace webrtc {
     25 namespace {
     26 
     27 void SetupSubFrameView(
     28    std::vector<std::vector<std::vector<float>>>* sub_frame,
     29    std::vector<std::vector<ArrayView<float>>>* sub_frame_view) {
     30  for (size_t band = 0; band < sub_frame_view->size(); ++band) {
     31    for (size_t channel = 0; channel < (*sub_frame_view)[band].size();
     32         ++channel) {
     33      (*sub_frame_view)[band][channel] =
     34          ArrayView<float>((*sub_frame)[band][channel].data(),
     35                           (*sub_frame)[band][channel].size());
     36    }
     37  }
     38 }
     39 
     40 float ComputeSampleValue(size_t chunk_counter,
     41                         size_t chunk_size,
     42                         size_t band,
     43                         size_t channel,
     44                         size_t sample_index,
     45                         int offset) {
     46  float value = static_cast<int>(100 + chunk_counter * chunk_size +
     47                                 sample_index + channel) +
     48                offset;
     49  return 5000 * band + value;
     50 }
     51 
     52 bool VerifySubFrame(
     53    size_t sub_frame_counter,
     54    int offset,
     55    const std::vector<std::vector<ArrayView<float>>>& sub_frame_view) {
     56  for (size_t band = 0; band < sub_frame_view.size(); ++band) {
     57    for (size_t channel = 0; channel < sub_frame_view[band].size(); ++channel) {
     58      for (size_t sample = 0; sample < sub_frame_view[band][channel].size();
     59           ++sample) {
     60        const float reference_value = ComputeSampleValue(
     61            sub_frame_counter, kSubFrameLength, band, channel, sample, offset);
     62        if (reference_value != sub_frame_view[band][channel][sample]) {
     63          return false;
     64        }
     65      }
     66    }
     67  }
     68  return true;
     69 }
     70 
     71 void FillBlock(size_t block_counter, Block* block) {
     72  for (int band = 0; band < block->NumBands(); ++band) {
     73    for (int channel = 0; channel < block->NumChannels(); ++channel) {
     74      auto b = block->View(band, channel);
     75      for (size_t sample = 0; sample < kBlockSize; ++sample) {
     76        b[sample] = ComputeSampleValue(block_counter, kBlockSize, band, channel,
     77                                       sample, 0);
     78      }
     79    }
     80  }
     81 }
     82 
     83 // Verifies that the BlockFramer is able to produce the expected frame content.
     84 void RunFramerTest(int sample_rate_hz, size_t num_channels) {
     85  constexpr size_t kNumSubFramesToProcess = 10;
     86  const size_t num_bands = NumBandsForRate(sample_rate_hz);
     87 
     88  Block block(num_bands, num_channels);
     89  std::vector<std::vector<std::vector<float>>> output_sub_frame(
     90      num_bands, std::vector<std::vector<float>>(
     91                     num_channels, std::vector<float>(kSubFrameLength, 0.f)));
     92  std::vector<std::vector<ArrayView<float>>> output_sub_frame_view(
     93      num_bands, std::vector<ArrayView<float>>(num_channels));
     94  SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
     95  BlockFramer framer(num_bands, num_channels);
     96 
     97  size_t block_index = 0;
     98  for (size_t sub_frame_index = 0; sub_frame_index < kNumSubFramesToProcess;
     99       ++sub_frame_index) {
    100    FillBlock(block_index++, &block);
    101    framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view);
    102    if (sub_frame_index > 1) {
    103      EXPECT_TRUE(VerifySubFrame(sub_frame_index, -64, output_sub_frame_view));
    104    }
    105 
    106    if ((sub_frame_index + 1) % 4 == 0) {
    107      FillBlock(block_index++, &block);
    108      framer.InsertBlock(block);
    109    }
    110  }
    111 }
    112 
    113 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    114 // Verifies that the BlockFramer crashes if the InsertBlockAndExtractSubFrame
    115 // method is called for inputs with the wrong number of bands or band lengths.
    116 void RunWronglySizedInsertAndExtractParametersTest(
    117    int sample_rate_hz,
    118    size_t correct_num_channels,
    119    size_t num_block_bands,
    120    size_t num_block_channels,
    121    size_t num_sub_frame_bands,
    122    size_t num_sub_frame_channels,
    123    size_t sub_frame_length) {
    124  const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
    125 
    126  Block block(num_block_bands, num_block_channels);
    127  std::vector<std::vector<std::vector<float>>> output_sub_frame(
    128      num_sub_frame_bands,
    129      std::vector<std::vector<float>>(
    130          num_sub_frame_channels, std::vector<float>(sub_frame_length, 0.f)));
    131  std::vector<std::vector<ArrayView<float>>> output_sub_frame_view(
    132      output_sub_frame.size(),
    133      std::vector<ArrayView<float>>(num_sub_frame_channels));
    134  SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
    135  BlockFramer framer(correct_num_bands, correct_num_channels);
    136  EXPECT_DEATH(
    137      framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view), "");
    138 }
    139 
    140 // Verifies that the BlockFramer crashes if the InsertBlock method is called for
    141 // inputs with the wrong number of bands or band lengths.
    142 void RunWronglySizedInsertParameterTest(int sample_rate_hz,
    143                                        size_t correct_num_channels,
    144                                        size_t num_block_bands,
    145                                        size_t num_block_channels) {
    146  const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
    147 
    148  Block correct_block(correct_num_bands, correct_num_channels);
    149  Block wrong_block(num_block_bands, num_block_channels);
    150  std::vector<std::vector<std::vector<float>>> output_sub_frame(
    151      correct_num_bands,
    152      std::vector<std::vector<float>>(
    153          correct_num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    154  std::vector<std::vector<ArrayView<float>>> output_sub_frame_view(
    155      output_sub_frame.size(),
    156      std::vector<ArrayView<float>>(correct_num_channels));
    157  SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
    158  BlockFramer framer(correct_num_bands, correct_num_channels);
    159  framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
    160  framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
    161  framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
    162  framer.InsertBlockAndExtractSubFrame(correct_block, &output_sub_frame_view);
    163 
    164  EXPECT_DEATH(framer.InsertBlock(wrong_block), "");
    165 }
    166 
    167 // Verifies that the BlockFramer crashes if the InsertBlock method is called
    168 // after a wrong number of previous InsertBlockAndExtractSubFrame method calls
    169 // have been made.
    170 
    171 void RunWronglyInsertOrderTest(int sample_rate_hz,
    172                               size_t num_channels,
    173                               size_t num_preceeding_api_calls) {
    174  const size_t correct_num_bands = NumBandsForRate(sample_rate_hz);
    175 
    176  Block block(correct_num_bands, num_channels);
    177  std::vector<std::vector<std::vector<float>>> output_sub_frame(
    178      correct_num_bands,
    179      std::vector<std::vector<float>>(
    180          num_channels, std::vector<float>(kSubFrameLength, 0.f)));
    181  std::vector<std::vector<ArrayView<float>>> output_sub_frame_view(
    182      output_sub_frame.size(), std::vector<ArrayView<float>>(num_channels));
    183  SetupSubFrameView(&output_sub_frame, &output_sub_frame_view);
    184  BlockFramer framer(correct_num_bands, num_channels);
    185  for (size_t k = 0; k < num_preceeding_api_calls; ++k) {
    186    framer.InsertBlockAndExtractSubFrame(block, &output_sub_frame_view);
    187  }
    188 
    189  EXPECT_DEATH(framer.InsertBlock(block), "");
    190 }
    191 #endif
    192 
    193 std::string ProduceDebugText(int sample_rate_hz, size_t num_channels) {
    194  StringBuilder ss;
    195  ss << "Sample rate: " << sample_rate_hz;
    196  ss << ", number of channels: " << num_channels;
    197  return ss.Release();
    198 }
    199 
    200 }  // namespace
    201 
    202 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
    203 TEST(BlockFramerDeathTest,
    204     WrongNumberOfBandsInBlockForInsertBlockAndExtractSubFrame) {
    205  for (auto rate : {16000, 32000, 48000}) {
    206    for (auto correct_num_channels : {1, 2, 8}) {
    207      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    208      const size_t correct_num_bands = NumBandsForRate(rate);
    209      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    210      RunWronglySizedInsertAndExtractParametersTest(
    211          rate, correct_num_channels, wrong_num_bands, correct_num_channels,
    212          correct_num_bands, correct_num_channels, kSubFrameLength);
    213    }
    214  }
    215 }
    216 
    217 TEST(BlockFramerDeathTest,
    218     WrongNumberOfChannelsInBlockForInsertBlockAndExtractSubFrame) {
    219  for (auto rate : {16000, 32000, 48000}) {
    220    for (auto correct_num_channels : {1, 2, 8}) {
    221      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    222      const size_t correct_num_bands = NumBandsForRate(rate);
    223      const size_t wrong_num_channels = correct_num_channels + 1;
    224      RunWronglySizedInsertAndExtractParametersTest(
    225          rate, correct_num_channels, correct_num_bands, wrong_num_channels,
    226          correct_num_bands, correct_num_channels, kSubFrameLength);
    227    }
    228  }
    229 }
    230 
    231 TEST(BlockFramerDeathTest,
    232     WrongNumberOfBandsInSubFrameForInsertBlockAndExtractSubFrame) {
    233  for (auto rate : {16000, 32000, 48000}) {
    234    for (auto correct_num_channels : {1, 2, 8}) {
    235      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    236      const size_t correct_num_bands = NumBandsForRate(rate);
    237      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    238      RunWronglySizedInsertAndExtractParametersTest(
    239          rate, correct_num_channels, correct_num_bands, correct_num_channels,
    240          wrong_num_bands, correct_num_channels, kSubFrameLength);
    241    }
    242  }
    243 }
    244 
    245 TEST(BlockFramerDeathTest,
    246     WrongNumberOfChannelsInSubFrameForInsertBlockAndExtractSubFrame) {
    247  for (auto rate : {16000, 32000, 48000}) {
    248    for (auto correct_num_channels : {1, 2, 8}) {
    249      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    250      const size_t correct_num_bands = NumBandsForRate(rate);
    251      const size_t wrong_num_channels = correct_num_channels + 1;
    252      RunWronglySizedInsertAndExtractParametersTest(
    253          rate, correct_num_channels, correct_num_bands, correct_num_channels,
    254          correct_num_bands, wrong_num_channels, kSubFrameLength);
    255    }
    256  }
    257 }
    258 
    259 TEST(BlockFramerDeathTest,
    260     WrongNumberOfSamplesInSubFrameForInsertBlockAndExtractSubFrame) {
    261  const size_t correct_num_channels = 1;
    262  for (auto rate : {16000, 32000, 48000}) {
    263    SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    264    const size_t correct_num_bands = NumBandsForRate(rate);
    265    RunWronglySizedInsertAndExtractParametersTest(
    266        rate, correct_num_channels, correct_num_bands, correct_num_channels,
    267        correct_num_bands, correct_num_channels, kSubFrameLength - 1);
    268  }
    269 }
    270 
    271 TEST(BlockFramerDeathTest, WrongNumberOfBandsInBlockForInsertBlock) {
    272  for (auto rate : {16000, 32000, 48000}) {
    273    for (auto correct_num_channels : {1, 2, 8}) {
    274      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    275      const size_t correct_num_bands = NumBandsForRate(rate);
    276      const size_t wrong_num_bands = (correct_num_bands % 3) + 1;
    277      RunWronglySizedInsertParameterTest(rate, correct_num_channels,
    278                                         wrong_num_bands, correct_num_channels);
    279    }
    280  }
    281 }
    282 
    283 TEST(BlockFramerDeathTest, WrongNumberOfChannelsInBlockForInsertBlock) {
    284  for (auto rate : {16000, 32000, 48000}) {
    285    for (auto correct_num_channels : {1, 2, 8}) {
    286      SCOPED_TRACE(ProduceDebugText(rate, correct_num_channels));
    287      const size_t correct_num_bands = NumBandsForRate(rate);
    288      const size_t wrong_num_channels = correct_num_channels + 1;
    289      RunWronglySizedInsertParameterTest(rate, correct_num_channels,
    290                                         correct_num_bands, wrong_num_channels);
    291    }
    292  }
    293 }
    294 
    295 TEST(BlockFramerDeathTest, WrongNumberOfPreceedingApiCallsForInsertBlock) {
    296  for (size_t num_channels : {1, 2, 8}) {
    297    for (auto rate : {16000, 32000, 48000}) {
    298      for (size_t num_calls = 0; num_calls < 4; ++num_calls) {
    299        StringBuilder ss;
    300        ss << "Sample rate: " << rate;
    301        ss << ", Num channels: " << num_channels;
    302        ss << ", Num preceeding InsertBlockAndExtractSubFrame calls: "
    303           << num_calls;
    304 
    305        SCOPED_TRACE(ss.str());
    306        RunWronglyInsertOrderTest(rate, num_channels, num_calls);
    307      }
    308    }
    309  }
    310 }
    311 
    312 // Verifies that the verification for 0 number of channels works.
    313 TEST(BlockFramerDeathTest, ZeroNumberOfChannelsParameter) {
    314  EXPECT_DEATH(BlockFramer(16000, 0), "");
    315 }
    316 
    317 // Verifies that the verification for 0 number of bands works.
    318 TEST(BlockFramerDeathTest, ZeroNumberOfBandsParameter) {
    319  EXPECT_DEATH(BlockFramer(0, 1), "");
    320 }
    321 
    322 // Verifies that the verification for null sub_frame pointer works.
    323 TEST(BlockFramerDeathTest, NullSubFrameParameter) {
    324  EXPECT_DEATH(
    325      BlockFramer(1, 1).InsertBlockAndExtractSubFrame(Block(1, 1), nullptr),
    326      "");
    327 }
    328 
    329 #endif
    330 
    331 TEST(BlockFramer, FrameBitexactness) {
    332  for (auto rate : {16000, 32000, 48000}) {
    333    for (auto num_channels : {1, 2, 4, 8}) {
    334      SCOPED_TRACE(ProduceDebugText(rate, num_channels));
    335      RunFramerTest(rate, num_channels);
    336    }
    337  }
    338 }
    339 
    340 }  // namespace webrtc