| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 /* |  | 
| 2  *  Copyright (c) 2016 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 #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" |  | 
| 12 |  | 
| 13 #include <vector> |  | 
| 14 |  | 
| 15 #include "webrtc/base/checks.h" |  | 
| 16 #include "webrtc/base/optional.h" |  | 
| 17 #include "webrtc/common_types.h" |  | 
| 18 #include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" |  | 
| 19 #include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" |  | 
| 20 #ifdef WEBRTC_CODEC_G722 |  | 
| 21 #include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" |  | 
| 22 #endif |  | 
| 23 #ifdef WEBRTC_CODEC_ILBC |  | 
| 24 #include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" |  | 
| 25 #endif |  | 
| 26 #ifdef WEBRTC_CODEC_ISACFX |  | 
| 27 #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isac
     fix.h"  // nogncheck |  | 
| 28 #endif |  | 
| 29 #ifdef WEBRTC_CODEC_ISAC |  | 
| 30 #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isa
     c.h"  // nogncheck |  | 
| 31 #endif |  | 
| 32 #ifdef WEBRTC_CODEC_OPUS |  | 
| 33 #include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" |  | 
| 34 #endif |  | 
| 35 #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" |  | 
| 36 |  | 
| 37 namespace webrtc { |  | 
| 38 |  | 
| 39 namespace { |  | 
| 40 |  | 
| 41 struct NamedDecoderConstructor { |  | 
| 42   const char* name; |  | 
| 43 |  | 
| 44   // If |format| is good, return true and (if |out| isn't null) reset |*out| to |  | 
| 45   // a new decoder object. If the |format| is not good, return false. |  | 
| 46   bool (*constructor)(const SdpAudioFormat& format, |  | 
| 47                       std::unique_ptr<AudioDecoder>* out); |  | 
| 48 }; |  | 
| 49 |  | 
| 50 // TODO(kwiberg): These factory functions should probably be moved to each |  | 
| 51 // decoder. |  | 
| 52 NamedDecoderConstructor decoder_constructors[] = { |  | 
| 53     {"pcmu", |  | 
| 54      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 55        if (format.clockrate_hz == 8000 && format.num_channels >= 1) { |  | 
| 56          if (out) { |  | 
| 57            out->reset(new AudioDecoderPcmU(format.num_channels)); |  | 
| 58          } |  | 
| 59          return true; |  | 
| 60        } else { |  | 
| 61          return false; |  | 
| 62        } |  | 
| 63      }}, |  | 
| 64     {"pcma", |  | 
| 65      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 66        if (format.clockrate_hz == 8000 && format.num_channels >= 1) { |  | 
| 67          if (out) { |  | 
| 68            out->reset(new AudioDecoderPcmA(format.num_channels)); |  | 
| 69          } |  | 
| 70          return true; |  | 
| 71        } else { |  | 
| 72          return false; |  | 
| 73        } |  | 
| 74      }}, |  | 
| 75 #ifdef WEBRTC_CODEC_ILBC |  | 
| 76     {"ilbc", |  | 
| 77      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 78        if (format.clockrate_hz == 8000 && format.num_channels == 1) { |  | 
| 79          if (out) { |  | 
| 80            out->reset(new AudioDecoderIlbc); |  | 
| 81          } |  | 
| 82          return true; |  | 
| 83        } else { |  | 
| 84          return false; |  | 
| 85        } |  | 
| 86      }}, |  | 
| 87 #endif |  | 
| 88 #if defined(WEBRTC_CODEC_ISACFX) |  | 
| 89     {"isac", |  | 
| 90      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 91        if (format.clockrate_hz == 16000 && format.num_channels == 1) { |  | 
| 92          if (out) { |  | 
| 93            out->reset(new AudioDecoderIsacFix(format.clockrate_hz)); |  | 
| 94          } |  | 
| 95          return true; |  | 
| 96        } else { |  | 
| 97          return false; |  | 
| 98        } |  | 
| 99      }}, |  | 
| 100 #elif defined(WEBRTC_CODEC_ISAC) |  | 
| 101     {"isac", |  | 
| 102      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 103        if ((format.clockrate_hz == 16000 || format.clockrate_hz == 32000) && |  | 
| 104            format.num_channels == 1) { |  | 
| 105          if (out) { |  | 
| 106            out->reset(new AudioDecoderIsac(format.clockrate_hz)); |  | 
| 107          } |  | 
| 108          return true; |  | 
| 109        } else { |  | 
| 110          return false; |  | 
| 111        } |  | 
| 112      }}, |  | 
| 113 #endif |  | 
| 114     {"l16", |  | 
| 115      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 116        if (format.num_channels >= 1) { |  | 
| 117          if (out) { |  | 
| 118            out->reset(new AudioDecoderPcm16B(format.clockrate_hz, |  | 
| 119                                              format.num_channels)); |  | 
| 120          } |  | 
| 121          return true; |  | 
| 122        } else { |  | 
| 123          return false; |  | 
| 124        } |  | 
| 125      }}, |  | 
| 126 #ifdef WEBRTC_CODEC_G722 |  | 
| 127     {"g722", |  | 
| 128      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 129        if (format.clockrate_hz == 8000) { |  | 
| 130          if (format.num_channels == 1) { |  | 
| 131            if (out) { |  | 
| 132              out->reset(new AudioDecoderG722); |  | 
| 133            } |  | 
| 134            return true; |  | 
| 135          } else if (format.num_channels == 2) { |  | 
| 136            if (out) { |  | 
| 137              out->reset(new AudioDecoderG722Stereo); |  | 
| 138            } |  | 
| 139            return true; |  | 
| 140          } |  | 
| 141        } |  | 
| 142        return false; |  | 
| 143      }}, |  | 
| 144 #endif |  | 
| 145 #ifdef WEBRTC_CODEC_OPUS |  | 
| 146     {"opus", |  | 
| 147      [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) { |  | 
| 148        const rtc::Optional<int> num_channels = [&] { |  | 
| 149          auto stereo = format.parameters.find("stereo"); |  | 
| 150          if (stereo != format.parameters.end()) { |  | 
| 151            if (stereo->second == "0") { |  | 
| 152              return rtc::Optional<int>(1); |  | 
| 153            } else if (stereo->second == "1") { |  | 
| 154              return rtc::Optional<int>(2); |  | 
| 155            } else { |  | 
| 156              return rtc::Optional<int>();  // Bad stereo parameter. |  | 
| 157            } |  | 
| 158          } |  | 
| 159          return rtc::Optional<int>(1);  // Default to mono. |  | 
| 160        }(); |  | 
| 161        if (format.clockrate_hz == 48000 && format.num_channels == 2 && |  | 
| 162            num_channels) { |  | 
| 163          if (out) { |  | 
| 164            out->reset(new AudioDecoderOpus(*num_channels)); |  | 
| 165          } |  | 
| 166          return true; |  | 
| 167        } else { |  | 
| 168          return false; |  | 
| 169        } |  | 
| 170      }}, |  | 
| 171 #endif |  | 
| 172 }; |  | 
| 173 |  | 
| 174 class BuiltinAudioDecoderFactory : public AudioDecoderFactory { |  | 
| 175  public: |  | 
| 176   std::vector<AudioCodecSpec> GetSupportedDecoders() override { |  | 
| 177     static std::vector<AudioCodecSpec> specs = { |  | 
| 178 #ifdef WEBRTC_CODEC_OPUS |  | 
| 179       { { "opus", 48000, 2, { |  | 
| 180             {"minptime", "10" }, |  | 
| 181             {"useinbandfec", "1" } |  | 
| 182           } |  | 
| 183         }, false |  | 
| 184       }, |  | 
| 185 #endif |  | 
| 186 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) |  | 
| 187       {{"isac", 16000, 1}, true}, |  | 
| 188 #endif |  | 
| 189 #if (defined(WEBRTC_CODEC_ISAC)) |  | 
| 190       {{"isac", 32000, 1}, true}, |  | 
| 191 #endif |  | 
| 192 #ifdef WEBRTC_CODEC_G722 |  | 
| 193       {{"G722", 8000, 1}, true}, |  | 
| 194 #endif |  | 
| 195 #ifdef WEBRTC_CODEC_ILBC |  | 
| 196       {{"iLBC", 8000, 1}, true}, |  | 
| 197 #endif |  | 
| 198       {{"PCMU", 8000, 1}, true}, |  | 
| 199       {{"PCMA", 8000, 1}, true} |  | 
| 200     }; |  | 
| 201 |  | 
| 202     return specs; |  | 
| 203   } |  | 
| 204 |  | 
| 205   bool IsSupportedDecoder(const SdpAudioFormat& format) override { |  | 
| 206     for (const auto& dc : decoder_constructors) { |  | 
| 207       if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { |  | 
| 208         return dc.constructor(format, nullptr); |  | 
| 209       } |  | 
| 210     } |  | 
| 211     return false; |  | 
| 212   } |  | 
| 213 |  | 
| 214   std::unique_ptr<AudioDecoder> MakeAudioDecoder( |  | 
| 215       const SdpAudioFormat& format) override { |  | 
| 216     for (const auto& dc : decoder_constructors) { |  | 
| 217       if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { |  | 
| 218         std::unique_ptr<AudioDecoder> decoder; |  | 
| 219         bool ok = dc.constructor(format, &decoder); |  | 
| 220         RTC_DCHECK_EQ(ok, decoder != nullptr); |  | 
| 221         if (decoder) { |  | 
| 222           const int expected_sample_rate_hz = |  | 
| 223               STR_CASE_CMP(format.name.c_str(), "g722") == 0 |  | 
| 224                   ? 2 * format.clockrate_hz |  | 
| 225                   : format.clockrate_hz; |  | 
| 226           RTC_CHECK_EQ(expected_sample_rate_hz, decoder->SampleRateHz()); |  | 
| 227         } |  | 
| 228         return decoder; |  | 
| 229       } |  | 
| 230     } |  | 
| 231     return nullptr; |  | 
| 232   } |  | 
| 233 }; |  | 
| 234 |  | 
| 235 }  // namespace |  | 
| 236 |  | 
| 237 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { |  | 
| 238   return rtc::scoped_refptr<AudioDecoderFactory>( |  | 
| 239       new rtc::RefCountedObject<BuiltinAudioDecoderFactory>); |  | 
| 240 } |  | 
| 241 |  | 
| 242 }  // namespace webrtc |  | 
| OLD | NEW | 
|---|