• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   *  Copyright (c) 2015 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_ACM2_RENT_A_CODEC_H_
12  #define WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_
13  
14  #include <stddef.h>
15  #include <map>
16  
17  #include "webrtc/base/array_view.h"
18  #include "webrtc/base/constructormagic.h"
19  #include "webrtc/base/optional.h"
20  #include "webrtc/base/scoped_ptr.h"
21  #include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
22  #include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
23  #include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
24  #include "webrtc/typedefs.h"
25  
26  #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
27  #include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h"
28  #else
29  // Dummy implementation, for when we don't have iSAC.
30  namespace webrtc {
31  class LockedIsacBandwidthInfo {};
32  }
33  #endif
34  
35  namespace webrtc {
36  
37  struct CodecInst;
38  
39  namespace acm2 {
40  
41  class RentACodec {
42   public:
43    enum class CodecId {
44  #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
45      kISAC,
46  #endif
47  #ifdef WEBRTC_CODEC_ISAC
48      kISACSWB,
49  #endif
50      // Mono
51      kPCM16B,
52      kPCM16Bwb,
53      kPCM16Bswb32kHz,
54      // Stereo
55      kPCM16B_2ch,
56      kPCM16Bwb_2ch,
57      kPCM16Bswb32kHz_2ch,
58      // Mono
59      kPCMU,
60      kPCMA,
61      // Stereo
62      kPCMU_2ch,
63      kPCMA_2ch,
64  #ifdef WEBRTC_CODEC_ILBC
65      kILBC,
66  #endif
67  #ifdef WEBRTC_CODEC_G722
68      kG722,      // Mono
69      kG722_2ch,  // Stereo
70  #endif
71  #ifdef WEBRTC_CODEC_OPUS
72      kOpus,  // Mono and stereo
73  #endif
74      kCNNB,
75      kCNWB,
76      kCNSWB,
77  #ifdef ENABLE_48000_HZ
78      kCNFB,
79  #endif
80      kAVT,
81  #ifdef WEBRTC_CODEC_RED
82      kRED,
83  #endif
84      kNumCodecs,  // Implementation detail. Don't use.
85  
86  // Set unsupported codecs to -1.
87  #if !defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX)
88      kISAC = -1,
89  #endif
90  #ifndef WEBRTC_CODEC_ISAC
91      kISACSWB = -1,
92  #endif
93      // 48 kHz not supported, always set to -1.
94      kPCM16Bswb48kHz = -1,
95  #ifndef WEBRTC_CODEC_ILBC
96      kILBC = -1,
97  #endif
98  #ifndef WEBRTC_CODEC_G722
99      kG722 = -1,      // Mono
100      kG722_2ch = -1,  // Stereo
101  #endif
102  #ifndef WEBRTC_CODEC_OPUS
103      kOpus = -1,  // Mono and stereo
104  #endif
105  #ifndef WEBRTC_CODEC_RED
106      kRED = -1,
107  #endif
108  #ifndef ENABLE_48000_HZ
109      kCNFB = -1,
110  #endif
111  
112      kNone = -1
113    };
114  
115    enum class NetEqDecoder {
116      kDecoderPCMu,
117      kDecoderPCMa,
118      kDecoderPCMu_2ch,
119      kDecoderPCMa_2ch,
120      kDecoderILBC,
121      kDecoderISAC,
122      kDecoderISACswb,
123      kDecoderPCM16B,
124      kDecoderPCM16Bwb,
125      kDecoderPCM16Bswb32kHz,
126      kDecoderPCM16Bswb48kHz,
127      kDecoderPCM16B_2ch,
128      kDecoderPCM16Bwb_2ch,
129      kDecoderPCM16Bswb32kHz_2ch,
130      kDecoderPCM16Bswb48kHz_2ch,
131      kDecoderPCM16B_5ch,
132      kDecoderG722,
133      kDecoderG722_2ch,
134      kDecoderRED,
135      kDecoderAVT,
136      kDecoderCNGnb,
137      kDecoderCNGwb,
138      kDecoderCNGswb32kHz,
139      kDecoderCNGswb48kHz,
140      kDecoderArbitrary,
141      kDecoderOpus,
142      kDecoderOpus_2ch,
143    };
144  
NumberOfCodecs()145    static inline size_t NumberOfCodecs() {
146      return static_cast<size_t>(CodecId::kNumCodecs);
147    }
148  
CodecIndexFromId(CodecId codec_id)149    static inline rtc::Optional<int> CodecIndexFromId(CodecId codec_id) {
150      const int i = static_cast<int>(codec_id);
151      return i >= 0 && i < static_cast<int>(NumberOfCodecs())
152                 ? rtc::Optional<int>(i)
153                 : rtc::Optional<int>();
154    }
155  
CodecIdFromIndex(int codec_index)156    static inline rtc::Optional<CodecId> CodecIdFromIndex(int codec_index) {
157      return static_cast<size_t>(codec_index) < NumberOfCodecs()
158                 ? rtc::Optional<RentACodec::CodecId>(
159                       static_cast<RentACodec::CodecId>(codec_index))
160                 : rtc::Optional<RentACodec::CodecId>();
161    }
162  
163    static rtc::Optional<CodecId> CodecIdByParams(const char* payload_name,
164                                                  int sampling_freq_hz,
165                                                  size_t channels);
166    static rtc::Optional<CodecInst> CodecInstById(CodecId codec_id);
167    static rtc::Optional<CodecId> CodecIdByInst(const CodecInst& codec_inst);
168    static rtc::Optional<CodecInst> CodecInstByParams(const char* payload_name,
169                                                      int sampling_freq_hz,
170                                                      size_t channels);
171    static bool IsCodecValid(const CodecInst& codec_inst);
172  
IsPayloadTypeValid(int payload_type)173    static inline bool IsPayloadTypeValid(int payload_type) {
174      return payload_type >= 0 && payload_type <= 127;
175    }
176  
177    static rtc::ArrayView<const CodecInst> Database();
178  
179    static rtc::Optional<bool> IsSupportedNumChannels(CodecId codec_id,
180                                                      size_t num_channels);
181  
182    static rtc::Optional<NetEqDecoder> NetEqDecoderFromCodecId(
183        CodecId codec_id,
184        size_t num_channels);
185  
186    // Parse codec_inst and extract payload types. If the given CodecInst was for
187    // the wrong sort of codec, return kSkip; otherwise, if the rate was illegal,
188    // return kBadFreq; otherwise, update the given RTP timestamp rate (Hz) ->
189    // payload type map and return kOk.
190    enum class RegistrationResult { kOk, kSkip, kBadFreq };
191    static RegistrationResult RegisterCngPayloadType(std::map<int, int>* pt_map,
192                                                     const CodecInst& codec_inst);
193    static RegistrationResult RegisterRedPayloadType(std::map<int, int>* pt_map,
194                                                     const CodecInst& codec_inst);
195  
196    RentACodec();
197    ~RentACodec();
198  
199    // Creates and returns an audio encoder built to the given specification.
200    // Returns null in case of error. The returned encoder is live until the next
201    // successful call to this function, or until the Rent-A-Codec is destroyed.
202    AudioEncoder* RentEncoder(const CodecInst& codec_inst);
203  
204    struct StackParameters {
205      StackParameters();
206      ~StackParameters();
207  
208      AudioEncoder* speech_encoder = nullptr;
209      bool use_codec_fec = false;
210      bool use_red = false;
211      bool use_cng = false;
212      ACMVADMode vad_mode = VADNormal;
213  
214      // Maps from RTP timestamp rate (in Hz) to payload type.
215      std::map<int, int> cng_payload_types;
216      std::map<int, int> red_payload_types;
217    };
218  
219    // Creates and returns an audio encoder stack constructed to the given
220    // specification. If the specification isn't compatible with the encoder, it
221    // will be changed to match (things will be switched off). The returned
222    // encoder is live until the next successful call to this function, or until
223    // the Rent-A-Codec is destroyed.
224    AudioEncoder* RentEncoderStack(StackParameters* param);
225  
226    // The last return value of RentEncoderStack, or null if it hasn't been
227    // called.
GetEncoderStack()228    AudioEncoder* GetEncoderStack() const { return encoder_stack_; }
229  
230    // Creates and returns an iSAC decoder, which will remain live until the
231    // Rent-A-Codec is destroyed. Subsequent calls will simply return the same
232    // object.
233    AudioDecoder* RentIsacDecoder();
234  
235   private:
236    rtc::scoped_ptr<AudioEncoder> speech_encoder_;
237    rtc::scoped_ptr<AudioEncoder> cng_encoder_;
238    rtc::scoped_ptr<AudioEncoder> red_encoder_;
239    rtc::scoped_ptr<AudioDecoder> isac_decoder_;
240    AudioEncoder* encoder_stack_ = nullptr;
241    LockedIsacBandwidthInfo isac_bandwidth_info_;
242  
243    RTC_DISALLOW_COPY_AND_ASSIGN(RentACodec);
244  };
245  
246  }  // namespace acm2
247  }  // namespace webrtc
248  
249  #endif  // WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_
250