Line data Source code
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 : #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECODER_DATABASE_H_
12 : #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECODER_DATABASE_H_
13 :
14 : #include <map>
15 : #include <memory>
16 : #include <string>
17 :
18 : #include "webrtc/base/constructormagic.h"
19 : #include "webrtc/common_types.h" // NULL
20 : #include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h"
21 : #include "webrtc/modules/audio_coding/codecs/audio_format.h"
22 : #include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
23 : #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
24 : #include "webrtc/modules/audio_coding/neteq/packet.h"
25 : #include "webrtc/typedefs.h"
26 :
27 : namespace webrtc {
28 :
29 0 : class DecoderDatabase {
30 : public:
31 : enum DatabaseReturnCodes {
32 : kOK = 0,
33 : kInvalidRtpPayloadType = -1,
34 : kCodecNotSupported = -2,
35 : kInvalidSampleRate = -3,
36 : kDecoderExists = -4,
37 : kDecoderNotFound = -5,
38 : kInvalidPointer = -6
39 : };
40 :
41 : // Class that stores decoder info in the database.
42 0 : class DecoderInfo {
43 : public:
44 : DecoderInfo(const SdpAudioFormat& audio_format,
45 : AudioDecoderFactory* factory,
46 : const std::string& codec_name);
47 : explicit DecoderInfo(const SdpAudioFormat& audio_format,
48 : AudioDecoderFactory* factory = nullptr);
49 : explicit DecoderInfo(NetEqDecoder ct,
50 : AudioDecoderFactory* factory = nullptr);
51 : DecoderInfo(const SdpAudioFormat& audio_format,
52 : AudioDecoder* ext_dec,
53 : const std::string& codec_name);
54 : DecoderInfo(DecoderInfo&&);
55 : ~DecoderInfo();
56 :
57 : // Get the AudioDecoder object, creating it first if necessary.
58 : AudioDecoder* GetDecoder() const;
59 :
60 : // Delete the AudioDecoder object, unless it's external. (This means we can
61 : // always recreate it later if we need it.)
62 0 : void DropDecoder() const { decoder_.reset(); }
63 :
64 0 : int SampleRateHz() const {
65 0 : if (IsDtmf()) {
66 : // DTMF has a 1:1 mapping between clock rate and sample rate.
67 0 : return audio_format_.clockrate_hz;
68 : }
69 0 : const AudioDecoder* decoder = GetDecoder();
70 0 : RTC_DCHECK_EQ(1, !!decoder + !!cng_decoder_);
71 0 : return decoder ? decoder->SampleRateHz() : cng_decoder_->sample_rate_hz;
72 : }
73 :
74 0 : const SdpAudioFormat& GetFormat() const { return audio_format_; }
75 :
76 : // Returns true if the decoder's format is comfort noise.
77 0 : bool IsComfortNoise() const {
78 0 : RTC_DCHECK_EQ(!!cng_decoder_, subtype_ == Subtype::kComfortNoise);
79 0 : return subtype_ == Subtype::kComfortNoise;
80 : }
81 :
82 : // Returns true if the decoder's format is DTMF.
83 0 : bool IsDtmf() const {
84 0 : return subtype_ == Subtype::kDtmf;
85 : }
86 :
87 : // Returns true if the decoder's format is RED.
88 0 : bool IsRed() const {
89 0 : return subtype_ == Subtype::kRed;
90 : }
91 :
92 : // Returns true if the decoder's format is named |name|.
93 : bool IsType(const char* name) const;
94 : // Returns true if the decoder's format is named |name|.
95 : bool IsType(const std::string& name) const;
96 :
97 0 : const std::string& get_name() const { return name_; }
98 :
99 : private:
100 : // TODO(ossu): |name_| is kept here while we retain the old external
101 : // decoder interface. Remove this once using an
102 : // AudioDecoderFactory has supplanted the old functionality.
103 : const std::string name_;
104 :
105 : const SdpAudioFormat audio_format_;
106 : AudioDecoderFactory* const factory_;
107 : mutable std::unique_ptr<AudioDecoder> decoder_;
108 :
109 : // Set iff this is an external decoder.
110 : AudioDecoder* const external_decoder_;
111 :
112 : // Set iff this is a comfort noise decoder.
113 : struct CngDecoder {
114 : static rtc::Optional<CngDecoder> Create(const SdpAudioFormat& format);
115 : int sample_rate_hz;
116 : };
117 : const rtc::Optional<CngDecoder> cng_decoder_;
118 :
119 : enum class Subtype : int8_t {
120 : kNormal,
121 : kComfortNoise,
122 : kDtmf,
123 : kRed
124 : };
125 :
126 : static Subtype SubtypeFromFormat(const SdpAudioFormat& format);
127 :
128 : const Subtype subtype_;
129 : };
130 :
131 : // Maximum value for 8 bits, and an invalid RTP payload type (since it is
132 : // only 7 bits).
133 : static const uint8_t kRtpPayloadTypeError = 0xFF;
134 :
135 : DecoderDatabase(
136 : const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory);
137 :
138 : virtual ~DecoderDatabase();
139 :
140 : // Returns true if the database is empty.
141 : virtual bool Empty() const;
142 :
143 : // Returns the number of decoders registered in the database.
144 : virtual int Size() const;
145 :
146 : // Resets the database, erasing all registered payload types, and deleting
147 : // any AudioDecoder objects that were not externally created and inserted
148 : // using InsertExternal().
149 : virtual void Reset();
150 :
151 : // Registers |rtp_payload_type| as a decoder of type |codec_type|. The |name|
152 : // is only used to populate the name field in the DecoderInfo struct in the
153 : // database, and can be arbitrary (including empty). Returns kOK on success;
154 : // otherwise an error code.
155 : virtual int RegisterPayload(uint8_t rtp_payload_type,
156 : NetEqDecoder codec_type,
157 : const std::string& name);
158 :
159 : // Registers a decoder for the given payload type. Returns kOK on success;
160 : // otherwise an error code.
161 : virtual int RegisterPayload(int rtp_payload_type,
162 : const SdpAudioFormat& audio_format);
163 :
164 : // Registers an externally created AudioDecoder object, and associates it
165 : // as a decoder of type |codec_type| with |rtp_payload_type|.
166 : virtual int InsertExternal(uint8_t rtp_payload_type,
167 : NetEqDecoder codec_type,
168 : const std::string& codec_name,
169 : AudioDecoder* decoder);
170 :
171 : // Removes the entry for |rtp_payload_type| from the database.
172 : // Returns kDecoderNotFound or kOK depending on the outcome of the operation.
173 : virtual int Remove(uint8_t rtp_payload_type);
174 :
175 : // Remove all entries.
176 : virtual void RemoveAll();
177 :
178 : // Returns a pointer to the DecoderInfo struct for |rtp_payload_type|. If
179 : // no decoder is registered with that |rtp_payload_type|, NULL is returned.
180 : virtual const DecoderInfo* GetDecoderInfo(uint8_t rtp_payload_type) const;
181 :
182 : // Sets the active decoder to be |rtp_payload_type|. If this call results in a
183 : // change of active decoder, |new_decoder| is set to true. The previous active
184 : // decoder's AudioDecoder object is deleted.
185 : virtual int SetActiveDecoder(uint8_t rtp_payload_type, bool* new_decoder);
186 :
187 : // Returns the current active decoder, or NULL if no active decoder exists.
188 : virtual AudioDecoder* GetActiveDecoder() const;
189 :
190 : // Sets the active comfort noise decoder to be |rtp_payload_type|. If this
191 : // call results in a change of active comfort noise decoder, the previous
192 : // active decoder's AudioDecoder object is deleted.
193 : virtual int SetActiveCngDecoder(uint8_t rtp_payload_type);
194 :
195 : // Returns the current active comfort noise decoder, or NULL if no active
196 : // comfort noise decoder exists.
197 : virtual ComfortNoiseDecoder* GetActiveCngDecoder() const;
198 :
199 : // The following are utility methods: they will look up DecoderInfo through
200 : // GetDecoderInfo and call the respective method on that info object, if it
201 : // exists.
202 :
203 : // Returns a pointer to the AudioDecoder object associated with
204 : // |rtp_payload_type|, or NULL if none is registered. If the AudioDecoder
205 : // object does not exist for that decoder, the object is created.
206 : AudioDecoder* GetDecoder(uint8_t rtp_payload_type) const;
207 :
208 : // Returns if |rtp_payload_type| is registered with a format named |name|.
209 : bool IsType(uint8_t rtp_payload_type, const char* name) const;
210 :
211 : // Returns if |rtp_payload_type| is registered with a format named |name|.
212 : bool IsType(uint8_t rtp_payload_type, const std::string& name) const;
213 :
214 : // Returns true if |rtp_payload_type| is registered as comfort noise.
215 : bool IsComfortNoise(uint8_t rtp_payload_type) const;
216 :
217 : // Returns true if |rtp_payload_type| is registered as DTMF.
218 : bool IsDtmf(uint8_t rtp_payload_type) const;
219 :
220 : // Returns true if |rtp_payload_type| is registered as RED.
221 : bool IsRed(uint8_t rtp_payload_type) const;
222 :
223 : // Returns kOK if all packets in |packet_list| carry payload types that are
224 : // registered in the database. Otherwise, returns kDecoderNotFound.
225 : int CheckPayloadTypes(const PacketList& packet_list) const;
226 :
227 : private:
228 : typedef std::map<uint8_t, DecoderInfo> DecoderMap;
229 :
230 : DecoderMap decoders_;
231 : int active_decoder_type_;
232 : int active_cng_decoder_type_;
233 : mutable std::unique_ptr<ComfortNoiseDecoder> active_cng_decoder_;
234 : rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
235 :
236 : RTC_DISALLOW_COPY_AND_ASSIGN(DecoderDatabase);
237 : };
238 :
239 : } // namespace webrtc
240 : #endif // WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECODER_DATABASE_H_
|