tor-browser

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

acm_send_test.cc (5956B)


      1 /*
      2 *  Copyright (c) 2014 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_coding/acm2/acm_send_test.h"
     12 
     13 #include <cstdint>
     14 #include <cstdio>
     15 #include <cstring>
     16 #include <memory>
     17 #include <utility>
     18 
     19 #include "absl/strings/match.h"
     20 #include "absl/strings/str_cat.h"
     21 #include "absl/strings/string_view.h"
     22 #include "api/audio_codecs/audio_encoder.h"
     23 #include "api/audio_codecs/audio_format.h"
     24 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
     25 #include "api/environment/environment_factory.h"
     26 #include "modules/audio_coding/include/audio_coding_module.h"
     27 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
     28 #include "modules/audio_coding/neteq/tools/input_audio_file.h"
     29 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     30 #include "rtc_base/checks.h"
     31 
     32 namespace webrtc {
     33 namespace test {
     34 
     35 AcmSendTestOldApi::AcmSendTestOldApi(InputAudioFile* audio_source,
     36                                     int source_rate_hz,
     37                                     int test_duration_ms)
     38    : clock_(0),
     39      env_(CreateEnvironment(&clock_)),
     40      acm_(AudioCodingModule::Create()),
     41      audio_source_(audio_source),
     42      source_rate_hz_(source_rate_hz),
     43      input_block_size_samples_(
     44          static_cast<size_t>(source_rate_hz_ * kBlockSizeMs / 1000)),
     45      codec_registered_(false),
     46      test_duration_ms_(test_duration_ms),
     47      frame_type_(AudioFrameType::kAudioFrameSpeech),
     48      payload_type_(0),
     49      timestamp_(0),
     50      sequence_number_(0) {
     51  input_frame_.sample_rate_hz_ = source_rate_hz_;
     52  input_frame_.num_channels_ = 1;
     53  input_frame_.samples_per_channel_ = input_block_size_samples_;
     54  RTC_DCHECK_LE(input_block_size_samples_ * input_frame_.num_channels_,
     55                AudioFrame::kMaxDataSizeSamples);
     56  acm_->RegisterTransportCallback(this);
     57 }
     58 
     59 AcmSendTestOldApi::~AcmSendTestOldApi() = default;
     60 
     61 bool AcmSendTestOldApi::RegisterCodec(absl::string_view payload_name,
     62                                      int clockrate_hz,
     63                                      int num_channels,
     64                                      int payload_type,
     65                                      int frame_size_samples) {
     66  SdpAudioFormat format(payload_name, clockrate_hz, num_channels);
     67  if (absl::EqualsIgnoreCase(payload_name, "g722")) {
     68    RTC_CHECK_EQ(16000, clockrate_hz);
     69    format.clockrate_hz = 8000;
     70  } else if (absl::EqualsIgnoreCase(payload_name, "opus")) {
     71    RTC_CHECK(num_channels == 1 || num_channels == 2);
     72    if (num_channels == 2) {
     73      format.parameters["stereo"] = "1";
     74    }
     75    format.num_channels = 2;
     76  }
     77  format.parameters["ptime"] = absl::StrCat(
     78      CheckedDivExact(frame_size_samples, CheckedDivExact(clockrate_hz, 1000)));
     79  auto factory = CreateBuiltinAudioEncoderFactory();
     80  acm_->SetEncoder(
     81      factory->Create(env_, format, {.payload_type = payload_type}));
     82  codec_registered_ = true;
     83  input_frame_.num_channels_ = num_channels;
     84  RTC_DCHECK_LE(input_block_size_samples_ * input_frame_.num_channels_,
     85                AudioFrame::kMaxDataSizeSamples);
     86  return codec_registered_;
     87 }
     88 
     89 void AcmSendTestOldApi::RegisterExternalCodec(
     90    std::unique_ptr<AudioEncoder> external_speech_encoder) {
     91  input_frame_.num_channels_ = external_speech_encoder->NumChannels();
     92  acm_->SetEncoder(std::move(external_speech_encoder));
     93  RTC_DCHECK_LE(input_block_size_samples_ * input_frame_.num_channels_,
     94                AudioFrame::kMaxDataSizeSamples);
     95  codec_registered_ = true;
     96 }
     97 
     98 std::unique_ptr<RtpPacketReceived> AcmSendTestOldApi::NextPacket() {
     99  RTC_DCHECK(codec_registered_);
    100  if (filter_.test(static_cast<size_t>(payload_type_))) {
    101    // This payload type should be filtered out. Since the payload type is the
    102    // same throughout the whole test run, no packet at all will be delivered.
    103    // We can just as well signal that the test is over by returning NULL.
    104    return nullptr;
    105  }
    106  // Insert audio and process until one packet is produced.
    107  while (clock_.TimeInMilliseconds() < test_duration_ms_) {
    108    clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
    109    RTC_CHECK(audio_source_->Read(
    110        input_block_size_samples_ * input_frame_.num_channels_,
    111        input_frame_.mutable_data()));
    112    data_to_send_ = false;
    113    RTC_CHECK_GE(acm_->Add10MsData(input_frame_), 0);
    114    input_frame_.timestamp_ += static_cast<uint32_t>(input_block_size_samples_);
    115    if (data_to_send_) {
    116      // Encoded packet received.
    117      return CreatePacket();
    118    }
    119  }
    120  // Test ended.
    121  return nullptr;
    122 }
    123 
    124 // This method receives the callback from ACM when a new packet is produced.
    125 int32_t AcmSendTestOldApi::SendData(
    126    AudioFrameType frame_type,
    127    uint8_t payload_type,
    128    uint32_t timestamp,
    129    const uint8_t* payload_data,
    130    size_t payload_len_bytes,
    131    int64_t /* absolute_capture_timestamp_ms */) {
    132  // Store the packet locally.
    133  frame_type_ = frame_type;
    134  payload_type_ = payload_type;
    135  timestamp_ = timestamp;
    136  last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
    137  RTC_DCHECK_EQ(last_payload_vec_.size(), payload_len_bytes);
    138  data_to_send_ = true;
    139  return 0;
    140 }
    141 
    142 std::unique_ptr<RtpPacketReceived> AcmSendTestOldApi::CreatePacket() {
    143  auto rtp_packet = std::make_unique<RtpPacketReceived>();
    144 
    145  // Populate the header.
    146  rtp_packet->SetPayloadType(payload_type_);
    147  rtp_packet->SetSequenceNumber(sequence_number_);
    148  rtp_packet->SetTimestamp(timestamp_);
    149  rtp_packet->SetSsrc(0x12345678);
    150  ++sequence_number_;
    151 
    152  rtp_packet->SetPayload(last_payload_vec_);
    153  rtp_packet->set_arrival_time(clock_.CurrentTime());
    154  return rtp_packet;
    155 }
    156 
    157 }  // namespace test
    158 }  // namespace webrtc