xref: /aosp_15_r20/external/webrtc/api/audio_codecs/audio_decoder.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_decoder.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <utility>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/sanitizer.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/trace_event.h"
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace {
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker class OldStyleEncodedFrame final : public AudioDecoder::EncodedAudioFrame {
27*d9f75844SAndroid Build Coastguard Worker  public:
OldStyleEncodedFrame(AudioDecoder * decoder,rtc::Buffer && payload)28*d9f75844SAndroid Build Coastguard Worker   OldStyleEncodedFrame(AudioDecoder* decoder, rtc::Buffer&& payload)
29*d9f75844SAndroid Build Coastguard Worker       : decoder_(decoder), payload_(std::move(payload)) {}
30*d9f75844SAndroid Build Coastguard Worker 
Duration() const31*d9f75844SAndroid Build Coastguard Worker   size_t Duration() const override {
32*d9f75844SAndroid Build Coastguard Worker     const int ret = decoder_->PacketDuration(payload_.data(), payload_.size());
33*d9f75844SAndroid Build Coastguard Worker     return ret < 0 ? 0 : static_cast<size_t>(ret);
34*d9f75844SAndroid Build Coastguard Worker   }
35*d9f75844SAndroid Build Coastguard Worker 
Decode(rtc::ArrayView<int16_t> decoded) const36*d9f75844SAndroid Build Coastguard Worker   absl::optional<DecodeResult> Decode(
37*d9f75844SAndroid Build Coastguard Worker       rtc::ArrayView<int16_t> decoded) const override {
38*d9f75844SAndroid Build Coastguard Worker     auto speech_type = AudioDecoder::kSpeech;
39*d9f75844SAndroid Build Coastguard Worker     const int ret = decoder_->Decode(
40*d9f75844SAndroid Build Coastguard Worker         payload_.data(), payload_.size(), decoder_->SampleRateHz(),
41*d9f75844SAndroid Build Coastguard Worker         decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
42*d9f75844SAndroid Build Coastguard Worker     return ret < 0 ? absl::nullopt
43*d9f75844SAndroid Build Coastguard Worker                    : absl::optional<DecodeResult>(
44*d9f75844SAndroid Build Coastguard Worker                          {static_cast<size_t>(ret), speech_type});
45*d9f75844SAndroid Build Coastguard Worker   }
46*d9f75844SAndroid Build Coastguard Worker 
47*d9f75844SAndroid Build Coastguard Worker  private:
48*d9f75844SAndroid Build Coastguard Worker   AudioDecoder* const decoder_;
49*d9f75844SAndroid Build Coastguard Worker   const rtc::Buffer payload_;
50*d9f75844SAndroid Build Coastguard Worker };
51*d9f75844SAndroid Build Coastguard Worker 
52*d9f75844SAndroid Build Coastguard Worker }  // namespace
53*d9f75844SAndroid Build Coastguard Worker 
IsDtxPacket() const54*d9f75844SAndroid Build Coastguard Worker bool AudioDecoder::EncodedAudioFrame::IsDtxPacket() const {
55*d9f75844SAndroid Build Coastguard Worker   return false;
56*d9f75844SAndroid Build Coastguard Worker }
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker AudioDecoder::ParseResult::ParseResult() = default;
59*d9f75844SAndroid Build Coastguard Worker AudioDecoder::ParseResult::ParseResult(ParseResult&& b) = default;
ParseResult(uint32_t timestamp,int priority,std::unique_ptr<EncodedAudioFrame> frame)60*d9f75844SAndroid Build Coastguard Worker AudioDecoder::ParseResult::ParseResult(uint32_t timestamp,
61*d9f75844SAndroid Build Coastguard Worker                                        int priority,
62*d9f75844SAndroid Build Coastguard Worker                                        std::unique_ptr<EncodedAudioFrame> frame)
63*d9f75844SAndroid Build Coastguard Worker     : timestamp(timestamp), priority(priority), frame(std::move(frame)) {
64*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_GE(priority, 0);
65*d9f75844SAndroid Build Coastguard Worker }
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker AudioDecoder::ParseResult::~ParseResult() = default;
68*d9f75844SAndroid Build Coastguard Worker 
69*d9f75844SAndroid Build Coastguard Worker AudioDecoder::ParseResult& AudioDecoder::ParseResult::operator=(
70*d9f75844SAndroid Build Coastguard Worker     ParseResult&& b) = default;
71*d9f75844SAndroid Build Coastguard Worker 
ParsePayload(rtc::Buffer && payload,uint32_t timestamp)72*d9f75844SAndroid Build Coastguard Worker std::vector<AudioDecoder::ParseResult> AudioDecoder::ParsePayload(
73*d9f75844SAndroid Build Coastguard Worker     rtc::Buffer&& payload,
74*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp) {
75*d9f75844SAndroid Build Coastguard Worker   std::vector<ParseResult> results;
76*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<EncodedAudioFrame> frame(
77*d9f75844SAndroid Build Coastguard Worker       new OldStyleEncodedFrame(this, std::move(payload)));
78*d9f75844SAndroid Build Coastguard Worker   results.emplace_back(timestamp, 0, std::move(frame));
79*d9f75844SAndroid Build Coastguard Worker   return results;
80*d9f75844SAndroid Build Coastguard Worker }
81*d9f75844SAndroid Build Coastguard Worker 
Decode(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,size_t max_decoded_bytes,int16_t * decoded,SpeechType * speech_type)82*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::Decode(const uint8_t* encoded,
83*d9f75844SAndroid Build Coastguard Worker                          size_t encoded_len,
84*d9f75844SAndroid Build Coastguard Worker                          int sample_rate_hz,
85*d9f75844SAndroid Build Coastguard Worker                          size_t max_decoded_bytes,
86*d9f75844SAndroid Build Coastguard Worker                          int16_t* decoded,
87*d9f75844SAndroid Build Coastguard Worker                          SpeechType* speech_type) {
88*d9f75844SAndroid Build Coastguard Worker   TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
89*d9f75844SAndroid Build Coastguard Worker   rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
90*d9f75844SAndroid Build Coastguard Worker   int duration = PacketDuration(encoded, encoded_len);
91*d9f75844SAndroid Build Coastguard Worker   if (duration >= 0 &&
92*d9f75844SAndroid Build Coastguard Worker       duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
93*d9f75844SAndroid Build Coastguard Worker     return -1;
94*d9f75844SAndroid Build Coastguard Worker   }
95*d9f75844SAndroid Build Coastguard Worker   return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
96*d9f75844SAndroid Build Coastguard Worker                         speech_type);
97*d9f75844SAndroid Build Coastguard Worker }
98*d9f75844SAndroid Build Coastguard Worker 
DecodeRedundant(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,size_t max_decoded_bytes,int16_t * decoded,SpeechType * speech_type)99*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
100*d9f75844SAndroid Build Coastguard Worker                                   size_t encoded_len,
101*d9f75844SAndroid Build Coastguard Worker                                   int sample_rate_hz,
102*d9f75844SAndroid Build Coastguard Worker                                   size_t max_decoded_bytes,
103*d9f75844SAndroid Build Coastguard Worker                                   int16_t* decoded,
104*d9f75844SAndroid Build Coastguard Worker                                   SpeechType* speech_type) {
105*d9f75844SAndroid Build Coastguard Worker   TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
106*d9f75844SAndroid Build Coastguard Worker   rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
107*d9f75844SAndroid Build Coastguard Worker   int duration = PacketDurationRedundant(encoded, encoded_len);
108*d9f75844SAndroid Build Coastguard Worker   if (duration >= 0 &&
109*d9f75844SAndroid Build Coastguard Worker       duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
110*d9f75844SAndroid Build Coastguard Worker     return -1;
111*d9f75844SAndroid Build Coastguard Worker   }
112*d9f75844SAndroid Build Coastguard Worker   return DecodeRedundantInternal(encoded, encoded_len, sample_rate_hz, decoded,
113*d9f75844SAndroid Build Coastguard Worker                                  speech_type);
114*d9f75844SAndroid Build Coastguard Worker }
115*d9f75844SAndroid Build Coastguard Worker 
DecodeRedundantInternal(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,SpeechType * speech_type)116*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
117*d9f75844SAndroid Build Coastguard Worker                                           size_t encoded_len,
118*d9f75844SAndroid Build Coastguard Worker                                           int sample_rate_hz,
119*d9f75844SAndroid Build Coastguard Worker                                           int16_t* decoded,
120*d9f75844SAndroid Build Coastguard Worker                                           SpeechType* speech_type) {
121*d9f75844SAndroid Build Coastguard Worker   return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
122*d9f75844SAndroid Build Coastguard Worker                         speech_type);
123*d9f75844SAndroid Build Coastguard Worker }
124*d9f75844SAndroid Build Coastguard Worker 
HasDecodePlc() const125*d9f75844SAndroid Build Coastguard Worker bool AudioDecoder::HasDecodePlc() const {
126*d9f75844SAndroid Build Coastguard Worker   return false;
127*d9f75844SAndroid Build Coastguard Worker }
128*d9f75844SAndroid Build Coastguard Worker 
DecodePlc(size_t num_frames,int16_t * decoded)129*d9f75844SAndroid Build Coastguard Worker size_t AudioDecoder::DecodePlc(size_t num_frames, int16_t* decoded) {
130*d9f75844SAndroid Build Coastguard Worker   return 0;
131*d9f75844SAndroid Build Coastguard Worker }
132*d9f75844SAndroid Build Coastguard Worker 
133*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/9676): Remove default implementation.
GeneratePlc(size_t,rtc::BufferT<int16_t> *)134*d9f75844SAndroid Build Coastguard Worker void AudioDecoder::GeneratePlc(size_t /*requested_samples_per_channel*/,
135*d9f75844SAndroid Build Coastguard Worker                                rtc::BufferT<int16_t>* /*concealment_audio*/) {}
136*d9f75844SAndroid Build Coastguard Worker 
ErrorCode()137*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::ErrorCode() {
138*d9f75844SAndroid Build Coastguard Worker   return 0;
139*d9f75844SAndroid Build Coastguard Worker }
140*d9f75844SAndroid Build Coastguard Worker 
PacketDuration(const uint8_t * encoded,size_t encoded_len) const141*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::PacketDuration(const uint8_t* encoded,
142*d9f75844SAndroid Build Coastguard Worker                                  size_t encoded_len) const {
143*d9f75844SAndroid Build Coastguard Worker   return kNotImplemented;
144*d9f75844SAndroid Build Coastguard Worker }
145*d9f75844SAndroid Build Coastguard Worker 
PacketDurationRedundant(const uint8_t * encoded,size_t encoded_len) const146*d9f75844SAndroid Build Coastguard Worker int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
147*d9f75844SAndroid Build Coastguard Worker                                           size_t encoded_len) const {
148*d9f75844SAndroid Build Coastguard Worker   return kNotImplemented;
149*d9f75844SAndroid Build Coastguard Worker }
150*d9f75844SAndroid Build Coastguard Worker 
PacketHasFec(const uint8_t * encoded,size_t encoded_len) const151*d9f75844SAndroid Build Coastguard Worker bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
152*d9f75844SAndroid Build Coastguard Worker                                 size_t encoded_len) const {
153*d9f75844SAndroid Build Coastguard Worker   return false;
154*d9f75844SAndroid Build Coastguard Worker }
155*d9f75844SAndroid Build Coastguard Worker 
ConvertSpeechType(int16_t type)156*d9f75844SAndroid Build Coastguard Worker AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
157*d9f75844SAndroid Build Coastguard Worker   switch (type) {
158*d9f75844SAndroid Build Coastguard Worker     case 0:  // TODO(hlundin): Both iSAC and Opus return 0 for speech.
159*d9f75844SAndroid Build Coastguard Worker     case 1:
160*d9f75844SAndroid Build Coastguard Worker       return kSpeech;
161*d9f75844SAndroid Build Coastguard Worker     case 2:
162*d9f75844SAndroid Build Coastguard Worker       return kComfortNoise;
163*d9f75844SAndroid Build Coastguard Worker     default:
164*d9f75844SAndroid Build Coastguard Worker       RTC_DCHECK_NOTREACHED();
165*d9f75844SAndroid Build Coastguard Worker       return kSpeech;
166*d9f75844SAndroid Build Coastguard Worker   }
167*d9f75844SAndroid Build Coastguard Worker }
168*d9f75844SAndroid Build Coastguard Worker 
169*d9f75844SAndroid Build Coastguard Worker constexpr int AudioDecoder::kMaxNumberOfChannels;
170*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
171