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