Line data Source code
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 "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h"
12 :
13 : #include <utility>
14 :
15 : #include "webrtc/base/checks.h"
16 :
17 : namespace webrtc {
18 :
19 : namespace {
20 0 : class OpusFrame : public AudioDecoder::EncodedAudioFrame {
21 : public:
22 0 : OpusFrame(AudioDecoderOpus* decoder,
23 : rtc::Buffer&& payload,
24 : bool is_primary_payload)
25 0 : : decoder_(decoder),
26 0 : payload_(std::move(payload)),
27 0 : is_primary_payload_(is_primary_payload) {}
28 :
29 0 : size_t Duration() const override {
30 : int ret;
31 0 : if (is_primary_payload_) {
32 0 : ret = decoder_->PacketDuration(payload_.data(), payload_.size());
33 : } else {
34 0 : ret = decoder_->PacketDurationRedundant(payload_.data(), payload_.size());
35 : }
36 0 : return (ret < 0) ? 0 : static_cast<size_t>(ret);
37 : }
38 :
39 0 : rtc::Optional<DecodeResult> Decode(
40 : rtc::ArrayView<int16_t> decoded) const override {
41 0 : AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
42 : int ret;
43 0 : if (is_primary_payload_) {
44 0 : ret = decoder_->Decode(
45 0 : payload_.data(), payload_.size(), decoder_->SampleRateHz(),
46 0 : decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
47 : } else {
48 0 : ret = decoder_->DecodeRedundant(
49 0 : payload_.data(), payload_.size(), decoder_->SampleRateHz(),
50 0 : decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
51 : }
52 :
53 0 : if (ret < 0)
54 0 : return rtc::Optional<DecodeResult>();
55 :
56 0 : return rtc::Optional<DecodeResult>({static_cast<size_t>(ret), speech_type});
57 : }
58 :
59 : private:
60 : AudioDecoderOpus* const decoder_;
61 : const rtc::Buffer payload_;
62 : const bool is_primary_payload_;
63 : };
64 :
65 : } // namespace
66 :
67 0 : AudioDecoderOpus::AudioDecoderOpus(size_t num_channels)
68 0 : : channels_(num_channels) {
69 0 : RTC_DCHECK(num_channels == 1 || num_channels == 2);
70 0 : WebRtcOpus_DecoderCreate(&dec_state_, channels_);
71 0 : WebRtcOpus_DecoderInit(dec_state_);
72 0 : }
73 :
74 0 : AudioDecoderOpus::~AudioDecoderOpus() {
75 0 : WebRtcOpus_DecoderFree(dec_state_);
76 0 : }
77 :
78 0 : std::vector<AudioDecoder::ParseResult> AudioDecoderOpus::ParsePayload(
79 : rtc::Buffer&& payload,
80 : uint32_t timestamp) {
81 0 : std::vector<ParseResult> results;
82 :
83 0 : if (PacketHasFec(payload.data(), payload.size())) {
84 : const int duration =
85 0 : PacketDurationRedundant(payload.data(), payload.size());
86 0 : RTC_DCHECK_GE(duration, 0);
87 0 : rtc::Buffer payload_copy(payload.data(), payload.size());
88 : std::unique_ptr<EncodedAudioFrame> fec_frame(
89 0 : new OpusFrame(this, std::move(payload_copy), false));
90 0 : results.emplace_back(timestamp - duration, 1, std::move(fec_frame));
91 : }
92 : std::unique_ptr<EncodedAudioFrame> frame(
93 0 : new OpusFrame(this, std::move(payload), true));
94 0 : results.emplace_back(timestamp, 0, std::move(frame));
95 0 : return results;
96 : }
97 :
98 0 : int AudioDecoderOpus::DecodeInternal(const uint8_t* encoded,
99 : size_t encoded_len,
100 : int sample_rate_hz,
101 : int16_t* decoded,
102 : SpeechType* speech_type) {
103 0 : RTC_DCHECK_EQ(sample_rate_hz, 48000);
104 0 : int16_t temp_type = 1; // Default is speech.
105 : int ret =
106 0 : WebRtcOpus_Decode(dec_state_, encoded, encoded_len, decoded, &temp_type);
107 0 : if (ret > 0)
108 0 : ret *= static_cast<int>(channels_); // Return total number of samples.
109 0 : *speech_type = ConvertSpeechType(temp_type);
110 0 : return ret;
111 : }
112 :
113 0 : int AudioDecoderOpus::DecodeRedundantInternal(const uint8_t* encoded,
114 : size_t encoded_len,
115 : int sample_rate_hz,
116 : int16_t* decoded,
117 : SpeechType* speech_type) {
118 0 : if (!PacketHasFec(encoded, encoded_len)) {
119 : // This packet is a RED packet.
120 : return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
121 0 : speech_type);
122 : }
123 :
124 0 : RTC_DCHECK_EQ(sample_rate_hz, 48000);
125 0 : int16_t temp_type = 1; // Default is speech.
126 0 : int ret = WebRtcOpus_DecodeFec(dec_state_, encoded, encoded_len, decoded,
127 0 : &temp_type);
128 0 : if (ret > 0)
129 0 : ret *= static_cast<int>(channels_); // Return total number of samples.
130 0 : *speech_type = ConvertSpeechType(temp_type);
131 0 : return ret;
132 : }
133 :
134 0 : void AudioDecoderOpus::Reset() {
135 0 : WebRtcOpus_DecoderInit(dec_state_);
136 0 : }
137 :
138 0 : int AudioDecoderOpus::PacketDuration(const uint8_t* encoded,
139 : size_t encoded_len) const {
140 0 : return WebRtcOpus_DurationEst(dec_state_, encoded, encoded_len);
141 : }
142 :
143 0 : int AudioDecoderOpus::PacketDurationRedundant(const uint8_t* encoded,
144 : size_t encoded_len) const {
145 0 : if (!PacketHasFec(encoded, encoded_len)) {
146 : // This packet is a RED packet.
147 0 : return PacketDuration(encoded, encoded_len);
148 : }
149 :
150 0 : return WebRtcOpus_FecDurationEst(encoded, encoded_len);
151 : }
152 :
153 0 : bool AudioDecoderOpus::PacketHasFec(const uint8_t* encoded,
154 : size_t encoded_len) const {
155 : int fec;
156 0 : fec = WebRtcOpus_PacketHasFec(encoded, encoded_len);
157 0 : return (fec == 1);
158 : }
159 :
160 0 : int AudioDecoderOpus::SampleRateHz() const {
161 0 : return 48000;
162 : }
163 :
164 0 : size_t AudioDecoderOpus::Channels() const {
165 0 : return channels_;
166 : }
167 :
168 : } // namespace webrtc
|