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