1 /*
2 * Copyright (c) 2012 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 "api/audio_codecs/audio_decoder.h"
12
13 #include <assert.h>
14
15 #include <memory>
16 #include <utility>
17
18 #include "api/array_view.h"
19 #include "rtc_base/checks.h"
20 #include "rtc_base/sanitizer.h"
21 #include "rtc_base/trace_event.h"
22
23 namespace webrtc {
24
25 namespace {
26
27 class OldStyleEncodedFrame final : public AudioDecoder::EncodedAudioFrame {
28 public:
OldStyleEncodedFrame(AudioDecoder * decoder,rtc::Buffer && payload)29 OldStyleEncodedFrame(AudioDecoder* decoder, rtc::Buffer&& payload)
30 : decoder_(decoder), payload_(std::move(payload)) {}
31
Duration() const32 size_t Duration() const override {
33 const int ret = decoder_->PacketDuration(payload_.data(), payload_.size());
34 return ret < 0 ? 0 : static_cast<size_t>(ret);
35 }
36
Decode(rtc::ArrayView<int16_t> decoded) const37 absl::optional<DecodeResult> Decode(
38 rtc::ArrayView<int16_t> decoded) const override {
39 auto speech_type = AudioDecoder::kSpeech;
40 const int ret = decoder_->Decode(
41 payload_.data(), payload_.size(), decoder_->SampleRateHz(),
42 decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
43 return ret < 0 ? absl::nullopt
44 : absl::optional<DecodeResult>(
45 {static_cast<size_t>(ret), speech_type});
46 }
47
48 private:
49 AudioDecoder* const decoder_;
50 const rtc::Buffer payload_;
51 };
52
53 } // namespace
54
IsDtxPacket() const55 bool AudioDecoder::EncodedAudioFrame::IsDtxPacket() const {
56 return false;
57 }
58
59 AudioDecoder::ParseResult::ParseResult() = default;
60 AudioDecoder::ParseResult::ParseResult(ParseResult&& b) = default;
ParseResult(uint32_t timestamp,int priority,std::unique_ptr<EncodedAudioFrame> frame)61 AudioDecoder::ParseResult::ParseResult(uint32_t timestamp,
62 int priority,
63 std::unique_ptr<EncodedAudioFrame> frame)
64 : timestamp(timestamp), priority(priority), frame(std::move(frame)) {
65 RTC_DCHECK_GE(priority, 0);
66 }
67
68 AudioDecoder::ParseResult::~ParseResult() = default;
69
70 AudioDecoder::ParseResult& AudioDecoder::ParseResult::operator=(
71 ParseResult&& b) = default;
72
ParsePayload(rtc::Buffer && payload,uint32_t timestamp)73 std::vector<AudioDecoder::ParseResult> AudioDecoder::ParsePayload(
74 rtc::Buffer&& payload,
75 uint32_t timestamp) {
76 std::vector<ParseResult> results;
77 std::unique_ptr<EncodedAudioFrame> frame(
78 new OldStyleEncodedFrame(this, std::move(payload)));
79 results.emplace_back(timestamp, 0, std::move(frame));
80 return results;
81 }
82
Decode(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,size_t max_decoded_bytes,int16_t * decoded,SpeechType * speech_type)83 int AudioDecoder::Decode(const uint8_t* encoded,
84 size_t encoded_len,
85 int sample_rate_hz,
86 size_t max_decoded_bytes,
87 int16_t* decoded,
88 SpeechType* speech_type) {
89 TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
90 rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
91 int duration = PacketDuration(encoded, encoded_len);
92 if (duration >= 0 &&
93 duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
94 return -1;
95 }
96 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
97 speech_type);
98 }
99
DecodeRedundant(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,size_t max_decoded_bytes,int16_t * decoded,SpeechType * speech_type)100 int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
101 size_t encoded_len,
102 int sample_rate_hz,
103 size_t max_decoded_bytes,
104 int16_t* decoded,
105 SpeechType* speech_type) {
106 TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
107 rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
108 int duration = PacketDurationRedundant(encoded, encoded_len);
109 if (duration >= 0 &&
110 duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
111 return -1;
112 }
113 return DecodeRedundantInternal(encoded, encoded_len, sample_rate_hz, decoded,
114 speech_type);
115 }
116
DecodeRedundantInternal(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,SpeechType * speech_type)117 int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
118 size_t encoded_len,
119 int sample_rate_hz,
120 int16_t* decoded,
121 SpeechType* speech_type) {
122 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
123 speech_type);
124 }
125
HasDecodePlc() const126 bool AudioDecoder::HasDecodePlc() const {
127 return false;
128 }
129
DecodePlc(size_t num_frames,int16_t * decoded)130 size_t AudioDecoder::DecodePlc(size_t num_frames, int16_t* decoded) {
131 return 0;
132 }
133
134 // TODO(bugs.webrtc.org/9676): Remove default implementation.
GeneratePlc(size_t,rtc::BufferT<int16_t> *)135 void AudioDecoder::GeneratePlc(size_t /*requested_samples_per_channel*/,
136 rtc::BufferT<int16_t>* /*concealment_audio*/) {}
137
ErrorCode()138 int AudioDecoder::ErrorCode() {
139 return 0;
140 }
141
PacketDuration(const uint8_t * encoded,size_t encoded_len) const142 int AudioDecoder::PacketDuration(const uint8_t* encoded,
143 size_t encoded_len) const {
144 return kNotImplemented;
145 }
146
PacketDurationRedundant(const uint8_t * encoded,size_t encoded_len) const147 int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
148 size_t encoded_len) const {
149 return kNotImplemented;
150 }
151
PacketHasFec(const uint8_t * encoded,size_t encoded_len) const152 bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
153 size_t encoded_len) const {
154 return false;
155 }
156
ConvertSpeechType(int16_t type)157 AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
158 switch (type) {
159 case 0: // TODO(hlundin): Both iSAC and Opus return 0 for speech.
160 case 1:
161 return kSpeech;
162 case 2:
163 return kComfortNoise;
164 default:
165 assert(false);
166 return kSpeech;
167 }
168 }
169
170 } // namespace webrtc
171