tor-browser

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

audio_decoder_opus.cc (5503B)


      1 /*
      2 *  Copyright (c) 2015 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/opus/audio_decoder_opus.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <utility>
     17 #include <vector>
     18 
     19 #include "api/array_view.h"
     20 #include "api/audio_codecs/audio_decoder.h"
     21 #include "api/field_trials_view.h"
     22 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
     23 #include "modules/audio_coding/codecs/opus/opus_interface.h"
     24 #include "rtc_base/buffer.h"
     25 #include "rtc_base/checks.h"
     26 
     27 namespace webrtc {
     28 
     29 AudioDecoderOpusImpl::AudioDecoderOpusImpl(const FieldTrialsView& field_trials,
     30                                           size_t num_channels,
     31                                           int sample_rate_hz)
     32    : channels_(num_channels),
     33      sample_rate_hz_(sample_rate_hz),
     34      generate_plc_(field_trials.IsEnabled("WebRTC-Audio-OpusGeneratePlc")) {
     35  RTC_DCHECK(num_channels == 1 || num_channels == 2);
     36  RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 48000);
     37  const int error =
     38      WebRtcOpus_DecoderCreate(&dec_state_, channels_, sample_rate_hz_);
     39  RTC_DCHECK(error == 0);
     40  WebRtcOpus_DecoderInit(dec_state_);
     41 }
     42 
     43 AudioDecoderOpusImpl::~AudioDecoderOpusImpl() {
     44  WebRtcOpus_DecoderFree(dec_state_);
     45 }
     46 
     47 std::vector<AudioDecoder::ParseResult> AudioDecoderOpusImpl::ParsePayload(
     48    Buffer&& payload,
     49    uint32_t timestamp) {
     50  std::vector<ParseResult> results;
     51 
     52  if (PacketHasFec(payload.data(), payload.size())) {
     53    const int duration =
     54        PacketDurationRedundant(payload.data(), payload.size());
     55    RTC_DCHECK_GE(duration, 0);
     56    Buffer payload_copy(payload.data(), payload.size());
     57    std::unique_ptr<EncodedAudioFrame> fec_frame(
     58        new OpusFrame(this, std::move(payload_copy), false));
     59    results.emplace_back(timestamp - duration, 1, std::move(fec_frame));
     60  }
     61  std::unique_ptr<EncodedAudioFrame> frame(
     62      new OpusFrame(this, std::move(payload), true));
     63  results.emplace_back(timestamp, 0, std::move(frame));
     64  return results;
     65 }
     66 
     67 int AudioDecoderOpusImpl::DecodeInternal(const uint8_t* encoded,
     68                                         size_t encoded_len,
     69                                         int sample_rate_hz,
     70                                         int16_t* decoded,
     71                                         SpeechType* speech_type) {
     72  RTC_DCHECK_EQ(sample_rate_hz, sample_rate_hz_);
     73  int16_t temp_type = 1;  // Default is speech.
     74  int ret =
     75      WebRtcOpus_Decode(dec_state_, encoded, encoded_len, decoded, &temp_type);
     76  if (ret > 0)
     77    ret *= static_cast<int>(channels_);  // Return total number of samples.
     78  *speech_type = ConvertSpeechType(temp_type);
     79  return ret;
     80 }
     81 
     82 int AudioDecoderOpusImpl::DecodeRedundantInternal(const uint8_t* encoded,
     83                                                  size_t encoded_len,
     84                                                  int sample_rate_hz,
     85                                                  int16_t* decoded,
     86                                                  SpeechType* speech_type) {
     87  if (!PacketHasFec(encoded, encoded_len)) {
     88    // This packet is a RED packet.
     89    return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
     90                          speech_type);
     91  }
     92 
     93  RTC_DCHECK_EQ(sample_rate_hz, sample_rate_hz_);
     94  int16_t temp_type = 1;  // Default is speech.
     95  int ret = WebRtcOpus_DecodeFec(dec_state_, encoded, encoded_len, decoded,
     96                                 &temp_type);
     97  if (ret > 0)
     98    ret *= static_cast<int>(channels_);  // Return total number of samples.
     99  *speech_type = ConvertSpeechType(temp_type);
    100  return ret;
    101 }
    102 
    103 void AudioDecoderOpusImpl::Reset() {
    104  WebRtcOpus_DecoderInit(dec_state_);
    105 }
    106 
    107 int AudioDecoderOpusImpl::PacketDuration(const uint8_t* encoded,
    108                                         size_t encoded_len) const {
    109  return WebRtcOpus_DurationEst(dec_state_, encoded, encoded_len);
    110 }
    111 
    112 int AudioDecoderOpusImpl::PacketDurationRedundant(const uint8_t* encoded,
    113                                                  size_t encoded_len) const {
    114  if (!PacketHasFec(encoded, encoded_len)) {
    115    // This packet is a RED packet.
    116    return PacketDuration(encoded, encoded_len);
    117  }
    118 
    119  return WebRtcOpus_FecDurationEst(encoded, encoded_len, sample_rate_hz_);
    120 }
    121 
    122 bool AudioDecoderOpusImpl::PacketHasFec(const uint8_t* encoded,
    123                                        size_t encoded_len) const {
    124  int fec;
    125  fec = WebRtcOpus_PacketHasFec(encoded, encoded_len);
    126  return (fec == 1);
    127 }
    128 
    129 int AudioDecoderOpusImpl::SampleRateHz() const {
    130  return sample_rate_hz_;
    131 }
    132 
    133 size_t AudioDecoderOpusImpl::Channels() const {
    134  return channels_;
    135 }
    136 
    137 void AudioDecoderOpusImpl::GeneratePlc(
    138    size_t /* requested_samples_per_channel */,
    139    BufferT<int16_t>* concealment_audio) {
    140  if (!generate_plc_) {
    141    return;
    142  }
    143  int plc_size = WebRtcOpus_PlcDuration(dec_state_) * channels_;
    144  concealment_audio->AppendData(plc_size, [&](ArrayView<int16_t> decoded) {
    145    int16_t temp_type = 1;
    146    int ret =
    147        WebRtcOpus_Decode(dec_state_, nullptr, 0, decoded.data(), &temp_type);
    148    if (ret < 0) {
    149      return 0;
    150    }
    151    return ret;
    152  });
    153 }
    154 
    155 }  // namespace webrtc