• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
14 #include <utility>
15 
16 #include "absl/types/optional.h"
17 #include "api/array_view.h"
18 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
19 #include "rtc_base/checks.h"
20 
21 namespace webrtc {
22 
AudioDecoderOpusImpl(size_t num_channels,int sample_rate_hz)23 AudioDecoderOpusImpl::AudioDecoderOpusImpl(size_t num_channels,
24                                            int sample_rate_hz)
25     : channels_{num_channels}, sample_rate_hz_{sample_rate_hz} {
26   RTC_DCHECK(num_channels == 1 || num_channels == 2);
27   RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 48000);
28   const int error =
29       WebRtcOpus_DecoderCreate(&dec_state_, channels_, sample_rate_hz_);
30   RTC_DCHECK(error == 0);
31   WebRtcOpus_DecoderInit(dec_state_);
32 }
33 
~AudioDecoderOpusImpl()34 AudioDecoderOpusImpl::~AudioDecoderOpusImpl() {
35   WebRtcOpus_DecoderFree(dec_state_);
36 }
37 
ParsePayload(rtc::Buffer && payload,uint32_t timestamp)38 std::vector<AudioDecoder::ParseResult> AudioDecoderOpusImpl::ParsePayload(
39     rtc::Buffer&& payload,
40     uint32_t timestamp) {
41   std::vector<ParseResult> results;
42 
43   if (PacketHasFec(payload.data(), payload.size())) {
44     const int duration =
45         PacketDurationRedundant(payload.data(), payload.size());
46     RTC_DCHECK_GE(duration, 0);
47     rtc::Buffer payload_copy(payload.data(), payload.size());
48     std::unique_ptr<EncodedAudioFrame> fec_frame(
49         new OpusFrame(this, std::move(payload_copy), false));
50     results.emplace_back(timestamp - duration, 1, std::move(fec_frame));
51   }
52   std::unique_ptr<EncodedAudioFrame> frame(
53       new OpusFrame(this, std::move(payload), true));
54   results.emplace_back(timestamp, 0, std::move(frame));
55   return results;
56 }
57 
DecodeInternal(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,SpeechType * speech_type)58 int AudioDecoderOpusImpl::DecodeInternal(const uint8_t* encoded,
59                                          size_t encoded_len,
60                                          int sample_rate_hz,
61                                          int16_t* decoded,
62                                          SpeechType* speech_type) {
63   RTC_DCHECK_EQ(sample_rate_hz, sample_rate_hz_);
64   int16_t temp_type = 1;  // Default is speech.
65   int ret =
66       WebRtcOpus_Decode(dec_state_, encoded, encoded_len, decoded, &temp_type);
67   if (ret > 0)
68     ret *= static_cast<int>(channels_);  // Return total number of samples.
69   *speech_type = ConvertSpeechType(temp_type);
70   return ret;
71 }
72 
DecodeRedundantInternal(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,SpeechType * speech_type)73 int AudioDecoderOpusImpl::DecodeRedundantInternal(const uint8_t* encoded,
74                                                   size_t encoded_len,
75                                                   int sample_rate_hz,
76                                                   int16_t* decoded,
77                                                   SpeechType* speech_type) {
78   if (!PacketHasFec(encoded, encoded_len)) {
79     // This packet is a RED packet.
80     return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
81                           speech_type);
82   }
83 
84   RTC_DCHECK_EQ(sample_rate_hz, sample_rate_hz_);
85   int16_t temp_type = 1;  // Default is speech.
86   int ret = WebRtcOpus_DecodeFec(dec_state_, encoded, encoded_len, decoded,
87                                  &temp_type);
88   if (ret > 0)
89     ret *= static_cast<int>(channels_);  // Return total number of samples.
90   *speech_type = ConvertSpeechType(temp_type);
91   return ret;
92 }
93 
Reset()94 void AudioDecoderOpusImpl::Reset() {
95   WebRtcOpus_DecoderInit(dec_state_);
96 }
97 
PacketDuration(const uint8_t * encoded,size_t encoded_len) const98 int AudioDecoderOpusImpl::PacketDuration(const uint8_t* encoded,
99                                          size_t encoded_len) const {
100   return WebRtcOpus_DurationEst(dec_state_, encoded, encoded_len);
101 }
102 
PacketDurationRedundant(const uint8_t * encoded,size_t encoded_len) const103 int AudioDecoderOpusImpl::PacketDurationRedundant(const uint8_t* encoded,
104                                                   size_t encoded_len) const {
105   if (!PacketHasFec(encoded, encoded_len)) {
106     // This packet is a RED packet.
107     return PacketDuration(encoded, encoded_len);
108   }
109 
110   return WebRtcOpus_FecDurationEst(encoded, encoded_len, sample_rate_hz_);
111 }
112 
PacketHasFec(const uint8_t * encoded,size_t encoded_len) const113 bool AudioDecoderOpusImpl::PacketHasFec(const uint8_t* encoded,
114                                         size_t encoded_len) const {
115   int fec;
116   fec = WebRtcOpus_PacketHasFec(encoded, encoded_len);
117   return (fec == 1);
118 }
119 
SampleRateHz() const120 int AudioDecoderOpusImpl::SampleRateHz() const {
121   return sample_rate_hz_;
122 }
123 
Channels() const124 size_t AudioDecoderOpusImpl::Channels() const {
125   return channels_;
126 }
127 
128 }  // namespace webrtc
129