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