tor-browser

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

audio_encoder_g722.cc (5622B)


      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/codecs/g722/audio_encoder_g722.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <optional>
     16 #include <utility>
     17 
     18 #include "api/array_view.h"
     19 #include "api/audio_codecs/audio_encoder.h"
     20 #include "api/audio_codecs/g722/audio_encoder_g722_config.h"
     21 #include "api/units/time_delta.h"
     22 #include "modules/audio_coding/codecs/g722/g722_interface.h"
     23 #include "rtc_base/buffer.h"
     24 #include "rtc_base/checks.h"
     25 
     26 namespace webrtc {
     27 
     28 namespace {
     29 
     30 const size_t kSampleRateHz = 16000;
     31 
     32 }  // namespace
     33 
     34 AudioEncoderG722Impl::AudioEncoderG722Impl(const AudioEncoderG722Config& config,
     35                                           int payload_type)
     36    : num_channels_(config.num_channels),
     37      payload_type_(payload_type),
     38      num_10ms_frames_per_packet_(
     39          static_cast<size_t>(config.frame_size_ms / 10)),
     40      num_10ms_frames_buffered_(0),
     41      first_timestamp_in_buffer_(0),
     42      encoders_(new EncoderState[num_channels_]),
     43      interleave_buffer_(2 * num_channels_) {
     44  RTC_CHECK(config.IsOk());
     45  const size_t samples_per_channel =
     46      kSampleRateHz / 100 * num_10ms_frames_per_packet_;
     47  for (size_t i = 0; i < num_channels_; ++i) {
     48    encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]);
     49    encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2);
     50  }
     51  Reset();
     52 }
     53 
     54 AudioEncoderG722Impl::~AudioEncoderG722Impl() = default;
     55 
     56 int AudioEncoderG722Impl::SampleRateHz() const {
     57  return kSampleRateHz;
     58 }
     59 
     60 size_t AudioEncoderG722Impl::NumChannels() const {
     61  return num_channels_;
     62 }
     63 
     64 int AudioEncoderG722Impl::RtpTimestampRateHz() const {
     65  // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz
     66  // codec.
     67  return kSampleRateHz / 2;
     68 }
     69 
     70 size_t AudioEncoderG722Impl::Num10MsFramesInNextPacket() const {
     71  return num_10ms_frames_per_packet_;
     72 }
     73 
     74 size_t AudioEncoderG722Impl::Max10MsFramesInAPacket() const {
     75  return num_10ms_frames_per_packet_;
     76 }
     77 
     78 int AudioEncoderG722Impl::GetTargetBitrate() const {
     79  // 4 bits/sample, 16000 samples/s/channel.
     80  return static_cast<int>(64000 * NumChannels());
     81 }
     82 
     83 void AudioEncoderG722Impl::Reset() {
     84  num_10ms_frames_buffered_ = 0;
     85  for (size_t i = 0; i < num_channels_; ++i)
     86    RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder));
     87 }
     88 
     89 std::optional<std::pair<TimeDelta, TimeDelta>>
     90 AudioEncoderG722Impl::GetFrameLengthRange() const {
     91  return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
     92           TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
     93 }
     94 
     95 AudioEncoder::EncodedInfo AudioEncoderG722Impl::EncodeImpl(
     96    uint32_t rtp_timestamp,
     97    ArrayView<const int16_t> audio,
     98    Buffer* encoded) {
     99  if (num_10ms_frames_buffered_ == 0)
    100    first_timestamp_in_buffer_ = rtp_timestamp;
    101 
    102  // Deinterleave samples and save them in each channel's buffer.
    103  const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_;
    104  for (size_t i = 0; i < kSampleRateHz / 100; ++i)
    105    for (size_t j = 0; j < num_channels_; ++j)
    106      encoders_[j].speech_buffer[start + i] = audio[i * num_channels_ + j];
    107 
    108  // If we don't yet have enough samples for a packet, we're done for now.
    109  if (++num_10ms_frames_buffered_ < num_10ms_frames_per_packet_) {
    110    return EncodedInfo();
    111  }
    112 
    113  // Encode each channel separately.
    114  RTC_CHECK_EQ(num_10ms_frames_buffered_, num_10ms_frames_per_packet_);
    115  num_10ms_frames_buffered_ = 0;
    116  const size_t samples_per_channel = SamplesPerChannel();
    117  for (size_t i = 0; i < num_channels_; ++i) {
    118    const size_t bytes_encoded = WebRtcG722_Encode(
    119        encoders_[i].encoder, encoders_[i].speech_buffer.get(),
    120        samples_per_channel, encoders_[i].encoded_buffer.data());
    121    RTC_CHECK_EQ(bytes_encoded, samples_per_channel / 2);
    122  }
    123 
    124  const size_t bytes_to_encode = samples_per_channel / 2 * num_channels_;
    125  EncodedInfo info;
    126  info.encoded_bytes =
    127      encoded->AppendData(bytes_to_encode, [&](ArrayView<uint8_t> encoded) {
    128        // Interleave the encoded bytes of the different channels. Each separate
    129        // channel and the interleaved stream encodes two samples per byte, most
    130        // significant half first.
    131        for (size_t i = 0; i < samples_per_channel / 2; ++i) {
    132          for (size_t j = 0; j < num_channels_; ++j) {
    133            uint8_t two_samples = encoders_[j].encoded_buffer.data()[i];
    134            interleave_buffer_.data()[j] = two_samples >> 4;
    135            interleave_buffer_.data()[num_channels_ + j] = two_samples & 0xf;
    136          }
    137          for (size_t j = 0; j < num_channels_; ++j)
    138            encoded[i * num_channels_ + j] =
    139                interleave_buffer_.data()[2 * j] << 4 |
    140                interleave_buffer_.data()[2 * j + 1];
    141        }
    142 
    143        return bytes_to_encode;
    144      });
    145  info.encoded_timestamp = first_timestamp_in_buffer_;
    146  info.payload_type = payload_type_;
    147  info.encoder_type = CodecType::kG722;
    148  return info;
    149 }
    150 
    151 AudioEncoderG722Impl::EncoderState::EncoderState() {
    152  RTC_CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder));
    153 }
    154 
    155 AudioEncoderG722Impl::EncoderState::~EncoderState() {
    156  RTC_CHECK_EQ(0, WebRtcG722_FreeEncoder(encoder));
    157 }
    158 
    159 size_t AudioEncoderG722Impl::SamplesPerChannel() const {
    160  return kSampleRateHz / 100 * num_10ms_frames_per_packet_;
    161 }
    162 
    163 }  // namespace webrtc