| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  *  Copyright (c) 2017 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_API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_ | 
|  | 12 #define WEBRTC_API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_ | 
|  | 13 | 
|  | 14 #include <memory> | 
|  | 15 #include <vector> | 
|  | 16 | 
|  | 17 #include "webrtc/api/audio_codecs/audio_encoder_factory.h" | 
|  | 18 #include "webrtc/base/scoped_ref_ptr.h" | 
|  | 19 | 
|  | 20 namespace webrtc { | 
|  | 21 | 
|  | 22 namespace audio_encoder_factory_template_impl { | 
|  | 23 | 
|  | 24 template <typename... Ts> | 
|  | 25 struct Helper; | 
|  | 26 | 
|  | 27 // Base case: 0 template parameters. | 
|  | 28 template <> | 
|  | 29 struct Helper<> { | 
|  | 30   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {} | 
|  | 31   static rtc::Optional<AudioCodecInfo> QueryAudioEncoder( | 
|  | 32       const SdpAudioFormat& format) { | 
|  | 33     return rtc::Optional<AudioCodecInfo>(); | 
|  | 34   } | 
|  | 35   static std::unique_ptr<AudioEncoder> MakeAudioEncoder( | 
|  | 36       int payload_type, | 
|  | 37       const SdpAudioFormat& format) { | 
|  | 38     return nullptr; | 
|  | 39   } | 
|  | 40 }; | 
|  | 41 | 
|  | 42 // Inductive case: Called with n + 1 template parameters; calls subroutines | 
|  | 43 // with n template parameters. | 
|  | 44 template <typename T, typename... Ts> | 
|  | 45 struct Helper<T, Ts...> { | 
|  | 46   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) { | 
|  | 47     T::AppendSupportedEncoders(specs); | 
|  | 48     Helper<Ts...>::AppendSupportedEncoders(specs); | 
|  | 49   } | 
|  | 50   static rtc::Optional<AudioCodecInfo> QueryAudioEncoder( | 
|  | 51       const SdpAudioFormat& format) { | 
|  | 52     auto opt_config = T::SdpToConfig(format); | 
|  | 53     return opt_config ? rtc::Optional<AudioCodecInfo>( | 
|  | 54                             T::QueryAudioEncoder(*opt_config)) | 
|  | 55                       : Helper<Ts...>::QueryAudioEncoder(format); | 
|  | 56   } | 
|  | 57   static std::unique_ptr<AudioEncoder> MakeAudioEncoder( | 
|  | 58       int payload_type, | 
|  | 59       const SdpAudioFormat& format) { | 
|  | 60     auto opt_config = T::SdpToConfig(format); | 
|  | 61     if (opt_config) { | 
|  | 62       return T::MakeAudioEncoder(*opt_config, payload_type); | 
|  | 63     } else { | 
|  | 64       return Helper<Ts...>::MakeAudioEncoder(payload_type, format); | 
|  | 65     } | 
|  | 66   } | 
|  | 67 }; | 
|  | 68 | 
|  | 69 template <typename... Ts> | 
|  | 70 class AudioEncoderFactoryT : public AudioEncoderFactory { | 
|  | 71  public: | 
|  | 72   std::vector<AudioCodecSpec> GetSupportedEncoders() override { | 
|  | 73     std::vector<AudioCodecSpec> specs; | 
|  | 74     Helper<Ts...>::AppendSupportedEncoders(&specs); | 
|  | 75     return specs; | 
|  | 76   } | 
|  | 77 | 
|  | 78   rtc::Optional<AudioCodecInfo> QueryAudioEncoder( | 
|  | 79       const SdpAudioFormat& format) override { | 
|  | 80     return Helper<Ts...>::QueryAudioEncoder(format); | 
|  | 81   } | 
|  | 82 | 
|  | 83   std::unique_ptr<AudioEncoder> MakeAudioEncoder( | 
|  | 84       int payload_type, | 
|  | 85       const SdpAudioFormat& format) override { | 
|  | 86     return Helper<Ts...>::MakeAudioEncoder(payload_type, format); | 
|  | 87   } | 
|  | 88 }; | 
|  | 89 | 
|  | 90 }  // namespace audio_encoder_factory_template_impl | 
|  | 91 | 
|  | 92 // Make an AudioEncoderFactory that can create instances of the given encoders. | 
|  | 93 // | 
|  | 94 // Each encoder type is given as a template argument to the function; it should | 
|  | 95 // be a struct with the following static member functions: | 
|  | 96 // | 
|  | 97 //   // Converts |audio_format| to a ConfigType instance. Returns an empty | 
|  | 98 //   // optional if |audio_format| doesn't correctly specify an encoder of our | 
|  | 99 //   // type. | 
|  | 100 //   rtc::Optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format); | 
|  | 101 // | 
|  | 102 //   // Appends zero or more AudioCodecSpecs to the list that will be returned | 
|  | 103 //   // by AudioEncoderFactory::GetSupportedEncoders(). | 
|  | 104 //   void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs); | 
|  | 105 // | 
|  | 106 //   // Returns information about how this format would be encoded. Used to | 
|  | 107 //   // implement AudioEncoderFactory::QueryAudioEncoder(). | 
|  | 108 //   AudioCodecInfo QueryAudioEncoder(const ConfigType& config); | 
|  | 109 // | 
|  | 110 //   // Creates an AudioEncoder for the specified format. Used to implement | 
|  | 111 //   // AudioEncoderFactory::MakeAudioEncoder(). | 
|  | 112 //   std::unique_ptr<AudioEncoder> MakeAudioEncoder(const ConfigType& config, | 
|  | 113 //                                                  int payload_type); | 
|  | 114 // | 
|  | 115 // ConfigType should be a type that encapsulates all the settings needed to | 
|  | 116 // create an AudioDecoder. | 
|  | 117 // | 
|  | 118 // Whenever it tries to do something, the new factory will try each of the | 
|  | 119 // encoders in the order they were specified in the template argument list, | 
|  | 120 // stopping at the first one that claims to be able to do the job. | 
|  | 121 // | 
|  | 122 // NOTE: This function is still under development and may change without notice. | 
|  | 123 // | 
|  | 124 // TODO(kwiberg): Point at CreateBuiltinAudioEncoderFactory() for an example of | 
|  | 125 // how it is used. | 
|  | 126 template <typename... Ts> | 
|  | 127 rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() { | 
|  | 128   // There's no technical reason we couldn't allow zero template parameters, | 
|  | 129   // but such a factory couldn't create any encoders, and callers can do this | 
|  | 130   // by mistake by simply forgetting the <> altogether. So we forbid it in | 
|  | 131   // order to prevent caller foot-shooting. | 
|  | 132   static_assert(sizeof...(Ts) >= 1, | 
|  | 133                 "Caller must give at least one template parameter"); | 
|  | 134 | 
|  | 135   return rtc::scoped_refptr<AudioEncoderFactory>( | 
|  | 136       new rtc::RefCountedObject< | 
|  | 137           audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>()); | 
|  | 138 } | 
|  | 139 | 
|  | 140 }  // namespace webrtc | 
|  | 141 | 
|  | 142 #endif  // WEBRTC_API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_ | 
| OLD | NEW | 
|---|