OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 68 |
69 bool IsG722(const CodecInst& codec) { | 69 bool IsG722(const CodecInst& codec) { |
70 return | 70 return |
71 #ifdef WEBRTC_CODEC_G722 | 71 #ifdef WEBRTC_CODEC_G722 |
72 !STR_CASE_CMP(codec.plname, "g722") || | 72 !STR_CASE_CMP(codec.plname, "g722") || |
73 #endif | 73 #endif |
74 false; | 74 false; |
75 } | 75 } |
76 } // namespace | 76 } // namespace |
77 | 77 |
78 CodecOwner::CodecOwner() | 78 CodecOwner::CodecOwner() : external_speech_encoder_(nullptr) { |
79 : isac_is_encoder_(false), external_speech_encoder_(nullptr) { | |
80 } | 79 } |
81 | 80 |
82 CodecOwner::~CodecOwner() = default; | 81 CodecOwner::~CodecOwner() = default; |
83 | 82 |
84 namespace { | 83 namespace { |
85 AudioEncoderDecoderMutableIsac* CreateIsacCodec(const CodecInst& speech_inst) { | 84 |
| 85 rtc::scoped_ptr<AudioDecoder> CreateIsacDecoder( |
| 86 LockedIsacBandwidthInfo* bwinfo) { |
86 #if defined(WEBRTC_CODEC_ISACFX) | 87 #if defined(WEBRTC_CODEC_ISACFX) |
87 return new AudioEncoderDecoderMutableIsacFix(speech_inst); | 88 return rtc_make_scoped_ptr(new AudioDecoderIsacFix(bwinfo)); |
88 #elif defined(WEBRTC_CODEC_ISAC) | 89 #elif defined(WEBRTC_CODEC_ISAC) |
89 return new AudioEncoderDecoderMutableIsacFloat(speech_inst); | 90 return rtc_make_scoped_ptr(new AudioDecoderIsac(bwinfo)); |
90 #else | 91 #else |
91 FATAL() << "iSAC is not supported."; | 92 FATAL() << "iSAC is not supported."; |
92 return nullptr; | 93 return rtc::scoped_ptr<AudioDecoder>(); |
93 #endif | 94 #endif |
94 } | 95 } |
95 | 96 |
96 void CreateSpeechEncoder( | 97 rtc::scoped_ptr<AudioEncoderMutable> CreateIsacEncoder( |
97 const CodecInst& speech_inst, | 98 const CodecInst& speech_inst, |
98 rtc::scoped_ptr<AudioEncoderMutable>* speech_encoder, | 99 LockedIsacBandwidthInfo* bwinfo) { |
99 rtc::scoped_ptr<AudioEncoderDecoderMutableIsac>* isac_codec, | 100 #if defined(WEBRTC_CODEC_ISACFX) |
100 bool* isac_is_encoder) { | 101 return rtc_make_scoped_ptr( |
| 102 new AudioEncoderMutableIsacFix(speech_inst, bwinfo)); |
| 103 #elif defined(WEBRTC_CODEC_ISAC) |
| 104 return rtc_make_scoped_ptr( |
| 105 new AudioEncoderMutableIsacFloat(speech_inst, bwinfo)); |
| 106 #else |
| 107 FATAL() << "iSAC is not supported."; |
| 108 return rtc::scoped_ptr<AudioEncoderMutable>(); |
| 109 #endif |
| 110 } |
| 111 |
| 112 rtc::scoped_ptr<AudioEncoderMutable> CreateSpeechEncoder( |
| 113 const CodecInst& speech_inst, |
| 114 LockedIsacBandwidthInfo* bwinfo) { |
101 if (IsIsac(speech_inst)) { | 115 if (IsIsac(speech_inst)) { |
102 if (*isac_codec) { | 116 return CreateIsacEncoder(speech_inst, bwinfo); |
103 (*isac_codec)->UpdateSettings(speech_inst); | 117 } else if (IsOpus(speech_inst)) { |
104 } else { | 118 return rtc_make_scoped_ptr(new AudioEncoderMutableOpus(speech_inst)); |
105 isac_codec->reset(CreateIsacCodec(speech_inst)); | |
106 } | |
107 *isac_is_encoder = true; | |
108 speech_encoder->reset(); | |
109 return; | |
110 } | |
111 if (IsOpus(speech_inst)) { | |
112 speech_encoder->reset(new AudioEncoderMutableOpus(speech_inst)); | |
113 } else if (IsPcmU(speech_inst)) { | 119 } else if (IsPcmU(speech_inst)) { |
114 speech_encoder->reset(new AudioEncoderMutablePcmU(speech_inst)); | 120 return rtc_make_scoped_ptr(new AudioEncoderMutablePcmU(speech_inst)); |
115 } else if (IsPcmA(speech_inst)) { | 121 } else if (IsPcmA(speech_inst)) { |
116 speech_encoder->reset(new AudioEncoderMutablePcmA(speech_inst)); | 122 return rtc_make_scoped_ptr(new AudioEncoderMutablePcmA(speech_inst)); |
117 } else if (IsPcm16B(speech_inst)) { | 123 } else if (IsPcm16B(speech_inst)) { |
118 speech_encoder->reset(new AudioEncoderMutablePcm16B(speech_inst)); | 124 return rtc_make_scoped_ptr(new AudioEncoderMutablePcm16B(speech_inst)); |
119 } else if (IsIlbc(speech_inst)) { | 125 } else if (IsIlbc(speech_inst)) { |
120 speech_encoder->reset(new AudioEncoderMutableIlbc(speech_inst)); | 126 return rtc_make_scoped_ptr(new AudioEncoderMutableIlbc(speech_inst)); |
121 } else if (IsG722(speech_inst)) { | 127 } else if (IsG722(speech_inst)) { |
122 speech_encoder->reset(new AudioEncoderMutableG722(speech_inst)); | 128 return rtc_make_scoped_ptr(new AudioEncoderMutableG722(speech_inst)); |
123 } else { | 129 } else { |
124 FATAL(); | 130 FATAL(); |
| 131 return rtc::scoped_ptr<AudioEncoderMutable>(); |
125 } | 132 } |
126 *isac_is_encoder = false; | |
127 } | 133 } |
128 | 134 |
129 AudioEncoder* CreateRedEncoder(int red_payload_type, | 135 AudioEncoder* CreateRedEncoder(int red_payload_type, |
130 AudioEncoder* encoder, | 136 AudioEncoder* encoder, |
131 rtc::scoped_ptr<AudioEncoder>* red_encoder) { | 137 rtc::scoped_ptr<AudioEncoder>* red_encoder) { |
132 if (red_payload_type == -1) { | 138 if (red_payload_type == -1) { |
133 red_encoder->reset(); | 139 red_encoder->reset(); |
134 return encoder; | 140 return encoder; |
135 } | 141 } |
136 AudioEncoderCopyRed::Config config; | 142 AudioEncoderCopyRed::Config config; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 FATAL(); | 175 FATAL(); |
170 } | 176 } |
171 cng_encoder->reset(new AudioEncoderCng(config)); | 177 cng_encoder->reset(new AudioEncoderCng(config)); |
172 } | 178 } |
173 } // namespace | 179 } // namespace |
174 | 180 |
175 void CodecOwner::SetEncoders(const CodecInst& speech_inst, | 181 void CodecOwner::SetEncoders(const CodecInst& speech_inst, |
176 int cng_payload_type, | 182 int cng_payload_type, |
177 ACMVADMode vad_mode, | 183 ACMVADMode vad_mode, |
178 int red_payload_type) { | 184 int red_payload_type) { |
179 CreateSpeechEncoder(speech_inst, &speech_encoder_, &isac_codec_, | 185 speech_encoder_ = CreateSpeechEncoder(speech_inst, &isac_bandwidth_info_); |
180 &isac_is_encoder_); | |
181 external_speech_encoder_ = nullptr; | 186 external_speech_encoder_ = nullptr; |
182 ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); | 187 ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); |
183 } | 188 } |
184 | 189 |
185 void CodecOwner::SetEncoders(AudioEncoderMutable* external_speech_encoder, | 190 void CodecOwner::SetEncoders(AudioEncoderMutable* external_speech_encoder, |
186 int cng_payload_type, | 191 int cng_payload_type, |
187 ACMVADMode vad_mode, | 192 ACMVADMode vad_mode, |
188 int red_payload_type) { | 193 int red_payload_type) { |
189 external_speech_encoder_ = external_speech_encoder; | 194 external_speech_encoder_ = external_speech_encoder; |
190 speech_encoder_.reset(); | 195 speech_encoder_.reset(); |
191 isac_is_encoder_ = false; | |
192 ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); | 196 ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); |
193 } | 197 } |
194 | 198 |
195 void CodecOwner::ChangeCngAndRed(int cng_payload_type, | 199 void CodecOwner::ChangeCngAndRed(int cng_payload_type, |
196 ACMVADMode vad_mode, | 200 ACMVADMode vad_mode, |
197 int red_payload_type) { | 201 int red_payload_type) { |
198 AudioEncoderMutable* speech_encoder = SpeechEncoder(); | 202 AudioEncoderMutable* speech_encoder = SpeechEncoder(); |
199 if (cng_payload_type != -1 || red_payload_type != -1) { | 203 if (cng_payload_type != -1 || red_payload_type != -1) { |
200 // The RED and CNG encoders need to be in sync with the speech encoder, so | 204 // The RED and CNG encoders need to be in sync with the speech encoder, so |
201 // reset the latter to ensure its buffer is empty. | 205 // reset the latter to ensure its buffer is empty. |
202 speech_encoder->Reset(); | 206 speech_encoder->Reset(); |
203 } | 207 } |
204 AudioEncoder* encoder = | 208 AudioEncoder* encoder = |
205 CreateRedEncoder(red_payload_type, speech_encoder, &red_encoder_); | 209 CreateRedEncoder(red_payload_type, speech_encoder, &red_encoder_); |
206 CreateCngEncoder(cng_payload_type, vad_mode, encoder, &cng_encoder_); | 210 CreateCngEncoder(cng_payload_type, vad_mode, encoder, &cng_encoder_); |
207 int num_true = | 211 DCHECK_EQ(!!speech_encoder_ + !!external_speech_encoder_, 1); |
208 !!speech_encoder_ + !!external_speech_encoder_ + isac_is_encoder_; | |
209 DCHECK_EQ(num_true, 1); | |
210 DCHECK(!isac_is_encoder_ || isac_codec_); | |
211 } | 212 } |
212 | 213 |
213 AudioDecoder* CodecOwner::GetIsacDecoder() { | 214 AudioDecoder* CodecOwner::GetIsacDecoder() { |
214 if (!isac_codec_) { | 215 if (!isac_decoder_) |
215 DCHECK(!isac_is_encoder_); | 216 isac_decoder_ = CreateIsacDecoder(&isac_bandwidth_info_); |
216 // None of the parameter values in |speech_inst| matter when the codec is | 217 return isac_decoder_.get(); |
217 // used only as a decoder. | |
218 CodecInst speech_inst; | |
219 speech_inst.plfreq = 16000; | |
220 speech_inst.rate = -1; | |
221 speech_inst.pacsize = 480; | |
222 isac_codec_.reset(CreateIsacCodec(speech_inst)); | |
223 } | |
224 return isac_codec_.get(); | |
225 } | 218 } |
226 | 219 |
227 AudioEncoder* CodecOwner::Encoder() { | 220 AudioEncoder* CodecOwner::Encoder() { |
228 const auto& const_this = *this; | 221 const auto& const_this = *this; |
229 return const_cast<AudioEncoder*>(const_this.Encoder()); | 222 return const_cast<AudioEncoder*>(const_this.Encoder()); |
230 } | 223 } |
231 | 224 |
232 const AudioEncoder* CodecOwner::Encoder() const { | 225 const AudioEncoder* CodecOwner::Encoder() const { |
233 if (cng_encoder_) | 226 if (cng_encoder_) |
234 return cng_encoder_.get(); | 227 return cng_encoder_.get(); |
235 if (red_encoder_) | 228 if (red_encoder_) |
236 return red_encoder_.get(); | 229 return red_encoder_.get(); |
237 return SpeechEncoder(); | 230 return SpeechEncoder(); |
238 } | 231 } |
239 | 232 |
240 AudioEncoderMutable* CodecOwner::SpeechEncoder() { | 233 AudioEncoderMutable* CodecOwner::SpeechEncoder() { |
241 const auto& const_this = *this; | 234 const auto& const_this = *this; |
242 return const_cast<AudioEncoderMutable*>(const_this.SpeechEncoder()); | 235 return const_cast<AudioEncoderMutable*>(const_this.SpeechEncoder()); |
243 } | 236 } |
244 | 237 |
245 const AudioEncoderMutable* CodecOwner::SpeechEncoder() const { | 238 const AudioEncoderMutable* CodecOwner::SpeechEncoder() const { |
246 int num_true = | 239 DCHECK(!speech_encoder_ || !external_speech_encoder_); |
247 !!speech_encoder_ + !!external_speech_encoder_ + isac_is_encoder_; | 240 return external_speech_encoder_ ? external_speech_encoder_ |
248 DCHECK_GE(num_true, 0); | 241 : speech_encoder_.get(); |
249 DCHECK_LE(num_true, 1); | |
250 if (external_speech_encoder_) | |
251 return external_speech_encoder_; | |
252 if (speech_encoder_) | |
253 return speech_encoder_.get(); | |
254 return isac_is_encoder_ ? isac_codec_.get() : nullptr; | |
255 } | 242 } |
256 | 243 |
257 } // namespace acm2 | 244 } // namespace acm2 |
258 } // namespace webrtc | 245 } // namespace webrtc |
OLD | NEW |