xref: /aosp_15_r20/external/webrtc/api/audio_codecs/audio_decoder.h (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 #ifndef API_AUDIO_CODECS_AUDIO_DECODER_H_
12*d9f75844SAndroid Build Coastguard Worker #define API_AUDIO_CODECS_AUDIO_DECODER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <memory>
18*d9f75844SAndroid Build Coastguard Worker #include <vector>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/buffer.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker class AudioDecoder {
27*d9f75844SAndroid Build Coastguard Worker  public:
28*d9f75844SAndroid Build Coastguard Worker   enum SpeechType {
29*d9f75844SAndroid Build Coastguard Worker     kSpeech = 1,
30*d9f75844SAndroid Build Coastguard Worker     kComfortNoise = 2,
31*d9f75844SAndroid Build Coastguard Worker   };
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker   // Used by PacketDuration below. Save the value -1 for errors.
34*d9f75844SAndroid Build Coastguard Worker   enum { kNotImplemented = -2 };
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker   AudioDecoder() = default;
37*d9f75844SAndroid Build Coastguard Worker   virtual ~AudioDecoder() = default;
38*d9f75844SAndroid Build Coastguard Worker 
39*d9f75844SAndroid Build Coastguard Worker   AudioDecoder(const AudioDecoder&) = delete;
40*d9f75844SAndroid Build Coastguard Worker   AudioDecoder& operator=(const AudioDecoder&) = delete;
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker   class EncodedAudioFrame {
43*d9f75844SAndroid Build Coastguard Worker    public:
44*d9f75844SAndroid Build Coastguard Worker     struct DecodeResult {
45*d9f75844SAndroid Build Coastguard Worker       size_t num_decoded_samples;
46*d9f75844SAndroid Build Coastguard Worker       SpeechType speech_type;
47*d9f75844SAndroid Build Coastguard Worker     };
48*d9f75844SAndroid Build Coastguard Worker 
49*d9f75844SAndroid Build Coastguard Worker     virtual ~EncodedAudioFrame() = default;
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker     // Returns the duration in samples-per-channel of this audio frame.
52*d9f75844SAndroid Build Coastguard Worker     // If no duration can be ascertained, returns zero.
53*d9f75844SAndroid Build Coastguard Worker     virtual size_t Duration() const = 0;
54*d9f75844SAndroid Build Coastguard Worker 
55*d9f75844SAndroid Build Coastguard Worker     // Returns true if this packet contains DTX.
56*d9f75844SAndroid Build Coastguard Worker     virtual bool IsDtxPacket() const;
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker     // Decodes this frame of audio and writes the result in `decoded`.
59*d9f75844SAndroid Build Coastguard Worker     // `decoded` must be large enough to store as many samples as indicated by a
60*d9f75844SAndroid Build Coastguard Worker     // call to Duration() . On success, returns an absl::optional containing the
61*d9f75844SAndroid Build Coastguard Worker     // total number of samples across all channels, as well as whether the
62*d9f75844SAndroid Build Coastguard Worker     // decoder produced comfort noise or speech. On failure, returns an empty
63*d9f75844SAndroid Build Coastguard Worker     // absl::optional. Decode may be called at most once per frame object.
64*d9f75844SAndroid Build Coastguard Worker     virtual absl::optional<DecodeResult> Decode(
65*d9f75844SAndroid Build Coastguard Worker         rtc::ArrayView<int16_t> decoded) const = 0;
66*d9f75844SAndroid Build Coastguard Worker   };
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker   struct ParseResult {
69*d9f75844SAndroid Build Coastguard Worker     ParseResult();
70*d9f75844SAndroid Build Coastguard Worker     ParseResult(uint32_t timestamp,
71*d9f75844SAndroid Build Coastguard Worker                 int priority,
72*d9f75844SAndroid Build Coastguard Worker                 std::unique_ptr<EncodedAudioFrame> frame);
73*d9f75844SAndroid Build Coastguard Worker     ParseResult(ParseResult&& b);
74*d9f75844SAndroid Build Coastguard Worker     ~ParseResult();
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker     ParseResult& operator=(ParseResult&& b);
77*d9f75844SAndroid Build Coastguard Worker 
78*d9f75844SAndroid Build Coastguard Worker     // The timestamp of the frame is in samples per channel.
79*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp;
80*d9f75844SAndroid Build Coastguard Worker     // The relative priority of the frame compared to other frames of the same
81*d9f75844SAndroid Build Coastguard Worker     // payload and the same timeframe. A higher value means a lower priority.
82*d9f75844SAndroid Build Coastguard Worker     // The highest priority is zero - negative values are not allowed.
83*d9f75844SAndroid Build Coastguard Worker     int priority;
84*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<EncodedAudioFrame> frame;
85*d9f75844SAndroid Build Coastguard Worker   };
86*d9f75844SAndroid Build Coastguard Worker 
87*d9f75844SAndroid Build Coastguard Worker   // Let the decoder parse this payload and prepare zero or more decodable
88*d9f75844SAndroid Build Coastguard Worker   // frames. Each frame must be between 10 ms and 120 ms long. The caller must
89*d9f75844SAndroid Build Coastguard Worker   // ensure that the AudioDecoder object outlives any frame objects returned by
90*d9f75844SAndroid Build Coastguard Worker   // this call. The decoder is free to swap or move the data from the `payload`
91*d9f75844SAndroid Build Coastguard Worker   // buffer. `timestamp` is the input timestamp, in samples, corresponding to
92*d9f75844SAndroid Build Coastguard Worker   // the start of the payload.
93*d9f75844SAndroid Build Coastguard Worker   virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
94*d9f75844SAndroid Build Coastguard Worker                                                 uint32_t timestamp);
95*d9f75844SAndroid Build Coastguard Worker 
96*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/10098): The Decode and DecodeRedundant methods are
97*d9f75844SAndroid Build Coastguard Worker   // obsolete; callers should call ParsePayload instead. For now, subclasses
98*d9f75844SAndroid Build Coastguard Worker   // must still implement DecodeInternal.
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker   // Decodes `encode_len` bytes from `encoded` and writes the result in
101*d9f75844SAndroid Build Coastguard Worker   // `decoded`. The maximum bytes allowed to be written into `decoded` is
102*d9f75844SAndroid Build Coastguard Worker   // `max_decoded_bytes`. Returns the total number of samples across all
103*d9f75844SAndroid Build Coastguard Worker   // channels. If the decoder produced comfort noise, `speech_type`
104*d9f75844SAndroid Build Coastguard Worker   // is set to kComfortNoise, otherwise it is kSpeech. The desired output
105*d9f75844SAndroid Build Coastguard Worker   // sample rate is provided in `sample_rate_hz`, which must be valid for the
106*d9f75844SAndroid Build Coastguard Worker   // codec at hand.
107*d9f75844SAndroid Build Coastguard Worker   int Decode(const uint8_t* encoded,
108*d9f75844SAndroid Build Coastguard Worker              size_t encoded_len,
109*d9f75844SAndroid Build Coastguard Worker              int sample_rate_hz,
110*d9f75844SAndroid Build Coastguard Worker              size_t max_decoded_bytes,
111*d9f75844SAndroid Build Coastguard Worker              int16_t* decoded,
112*d9f75844SAndroid Build Coastguard Worker              SpeechType* speech_type);
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   // Same as Decode(), but interfaces to the decoders redundant decode function.
115*d9f75844SAndroid Build Coastguard Worker   // The default implementation simply calls the regular Decode() method.
116*d9f75844SAndroid Build Coastguard Worker   int DecodeRedundant(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                       size_t max_decoded_bytes,
120*d9f75844SAndroid Build Coastguard Worker                       int16_t* decoded,
121*d9f75844SAndroid Build Coastguard Worker                       SpeechType* speech_type);
122*d9f75844SAndroid Build Coastguard Worker 
123*d9f75844SAndroid Build Coastguard Worker   // Indicates if the decoder implements the DecodePlc method.
124*d9f75844SAndroid Build Coastguard Worker   virtual bool HasDecodePlc() const;
125*d9f75844SAndroid Build Coastguard Worker 
126*d9f75844SAndroid Build Coastguard Worker   // Calls the packet-loss concealment of the decoder to update the state after
127*d9f75844SAndroid Build Coastguard Worker   // one or several lost packets. The caller has to make sure that the
128*d9f75844SAndroid Build Coastguard Worker   // memory allocated in `decoded` should accommodate `num_frames` frames.
129*d9f75844SAndroid Build Coastguard Worker   virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker   // Asks the decoder to generate packet-loss concealment and append it to the
132*d9f75844SAndroid Build Coastguard Worker   // end of `concealment_audio`. The concealment audio should be in
133*d9f75844SAndroid Build Coastguard Worker   // channel-interleaved format, with as many channels as the last decoded
134*d9f75844SAndroid Build Coastguard Worker   // packet produced. The implementation must produce at least
135*d9f75844SAndroid Build Coastguard Worker   // requested_samples_per_channel, or nothing at all. This is a signal to the
136*d9f75844SAndroid Build Coastguard Worker   // caller to conceal the loss with other means. If the implementation provides
137*d9f75844SAndroid Build Coastguard Worker   // concealment samples, it is also responsible for "stitching" it together
138*d9f75844SAndroid Build Coastguard Worker   // with the decoded audio on either side of the concealment.
139*d9f75844SAndroid Build Coastguard Worker   // Note: The default implementation of GeneratePlc will be deleted soon. All
140*d9f75844SAndroid Build Coastguard Worker   // implementations must provide their own, which can be a simple as a no-op.
141*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/9676): Remove default implementation.
142*d9f75844SAndroid Build Coastguard Worker   virtual void GeneratePlc(size_t requested_samples_per_channel,
143*d9f75844SAndroid Build Coastguard Worker                            rtc::BufferT<int16_t>* concealment_audio);
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker   // Resets the decoder state (empty buffers etc.).
146*d9f75844SAndroid Build Coastguard Worker   virtual void Reset() = 0;
147*d9f75844SAndroid Build Coastguard Worker 
148*d9f75844SAndroid Build Coastguard Worker   // Returns the last error code from the decoder.
149*d9f75844SAndroid Build Coastguard Worker   virtual int ErrorCode();
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   // Returns the duration in samples-per-channel of the payload in `encoded`
152*d9f75844SAndroid Build Coastguard Worker   // which is `encoded_len` bytes long. Returns kNotImplemented if no duration
153*d9f75844SAndroid Build Coastguard Worker   // estimate is available, or -1 in case of an error.
154*d9f75844SAndroid Build Coastguard Worker   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
155*d9f75844SAndroid Build Coastguard Worker 
156*d9f75844SAndroid Build Coastguard Worker   // Returns the duration in samples-per-channel of the redandant payload in
157*d9f75844SAndroid Build Coastguard Worker   // `encoded` which is `encoded_len` bytes long. Returns kNotImplemented if no
158*d9f75844SAndroid Build Coastguard Worker   // duration estimate is available, or -1 in case of an error.
159*d9f75844SAndroid Build Coastguard Worker   virtual int PacketDurationRedundant(const uint8_t* encoded,
160*d9f75844SAndroid Build Coastguard Worker                                       size_t encoded_len) const;
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker   // Detects whether a packet has forward error correction. The packet is
163*d9f75844SAndroid Build Coastguard Worker   // comprised of the samples in `encoded` which is `encoded_len` bytes long.
164*d9f75844SAndroid Build Coastguard Worker   // Returns true if the packet has FEC and false otherwise.
165*d9f75844SAndroid Build Coastguard Worker   virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker   // Returns the actual sample rate of the decoder's output. This value may not
168*d9f75844SAndroid Build Coastguard Worker   // change during the lifetime of the decoder.
169*d9f75844SAndroid Build Coastguard Worker   virtual int SampleRateHz() const = 0;
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker   // The number of channels in the decoder's output. This value may not change
172*d9f75844SAndroid Build Coastguard Worker   // during the lifetime of the decoder.
173*d9f75844SAndroid Build Coastguard Worker   virtual size_t Channels() const = 0;
174*d9f75844SAndroid Build Coastguard Worker 
175*d9f75844SAndroid Build Coastguard Worker   // The maximum number of audio channels supported by WebRTC decoders.
176*d9f75844SAndroid Build Coastguard Worker   static constexpr int kMaxNumberOfChannels = 24;
177*d9f75844SAndroid Build Coastguard Worker 
178*d9f75844SAndroid Build Coastguard Worker  protected:
179*d9f75844SAndroid Build Coastguard Worker   static SpeechType ConvertSpeechType(int16_t type);
180*d9f75844SAndroid Build Coastguard Worker 
181*d9f75844SAndroid Build Coastguard Worker   virtual int DecodeInternal(const uint8_t* encoded,
182*d9f75844SAndroid Build Coastguard Worker                              size_t encoded_len,
183*d9f75844SAndroid Build Coastguard Worker                              int sample_rate_hz,
184*d9f75844SAndroid Build Coastguard Worker                              int16_t* decoded,
185*d9f75844SAndroid Build Coastguard Worker                              SpeechType* speech_type) = 0;
186*d9f75844SAndroid Build Coastguard Worker 
187*d9f75844SAndroid Build Coastguard Worker   virtual int DecodeRedundantInternal(const uint8_t* encoded,
188*d9f75844SAndroid Build Coastguard Worker                                       size_t encoded_len,
189*d9f75844SAndroid Build Coastguard Worker                                       int sample_rate_hz,
190*d9f75844SAndroid Build Coastguard Worker                                       int16_t* decoded,
191*d9f75844SAndroid Build Coastguard Worker                                       SpeechType* speech_type);
192*d9f75844SAndroid Build Coastguard Worker };
193*d9f75844SAndroid Build Coastguard Worker 
194*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
195*d9f75844SAndroid Build Coastguard Worker #endif  // API_AUDIO_CODECS_AUDIO_DECODER_H_
196