Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc

Issue 1702943002: Pass ownership of external encoders to the ACM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 13 matching lines...) Expand all
24 #include "webrtc/system_wrappers/include/logging.h" 24 #include "webrtc/system_wrappers/include/logging.h"
25 #include "webrtc/system_wrappers/include/metrics.h" 25 #include "webrtc/system_wrappers/include/metrics.h"
26 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" 26 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
27 #include "webrtc/system_wrappers/include/trace.h" 27 #include "webrtc/system_wrappers/include/trace.h"
28 #include "webrtc/typedefs.h" 28 #include "webrtc/typedefs.h"
29 29
30 namespace webrtc { 30 namespace webrtc {
31 31
32 namespace acm2 { 32 namespace acm2 {
33 33
34 struct EncoderFactory {
35 AudioEncoder* external_speech_encoder = nullptr;
36 CodecManager codec_manager;
37 RentACodec rent_a_codec;
38 };
39
34 namespace { 40 namespace {
35 41
36 // TODO(turajs): the same functionality is used in NetEq. If both classes 42 // TODO(turajs): the same functionality is used in NetEq. If both classes
37 // need them, make it a static function in ACMCodecDB. 43 // need them, make it a static function in ACMCodecDB.
38 bool IsCodecRED(const CodecInst& codec) { 44 bool IsCodecRED(const CodecInst& codec) {
39 return (STR_CASE_CMP(codec.plname, "RED") == 0); 45 return (STR_CASE_CMP(codec.plname, "RED") == 0);
40 } 46 }
41 47
42 bool IsCodecCN(const CodecInst& codec) { 48 bool IsCodecCN(const CodecInst& codec) {
43 return (STR_CASE_CMP(codec.plname, "CN") == 0); 49 return (STR_CASE_CMP(codec.plname, "CN") == 0);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 size_t offset = 0; 89 size_t offset = 0;
84 for (size_t i = 0; i < info.redundant.size(); ++i) { 90 for (size_t i = 0; i < info.redundant.size(); ++i) {
85 frag->fragmentationOffset[i] = offset; 91 frag->fragmentationOffset[i] = offset;
86 offset += info.redundant[i].encoded_bytes; 92 offset += info.redundant[i].encoded_bytes;
87 frag->fragmentationLength[i] = info.redundant[i].encoded_bytes; 93 frag->fragmentationLength[i] = info.redundant[i].encoded_bytes;
88 frag->fragmentationTimeDiff[i] = rtc::checked_cast<uint16_t>( 94 frag->fragmentationTimeDiff[i] = rtc::checked_cast<uint16_t>(
89 info.encoded_timestamp - info.redundant[i].encoded_timestamp); 95 info.encoded_timestamp - info.redundant[i].encoded_timestamp);
90 frag->fragmentationPlType[i] = info.redundant[i].payload_type; 96 frag->fragmentationPlType[i] = info.redundant[i].payload_type;
91 } 97 }
92 } 98 }
99
100 // Wraps a raw AudioEncoder pointer. The idea is that you can put one of these
101 // in a unique_ptr, to protect the contained raw pointer from being deleted
102 // when the unique_ptr expires. (This is of course a bad idea in general, but
103 // backwards compatibility.)
104 class RawAudioEncoderWrapper final : public AudioEncoder {
105 public:
106 RawAudioEncoderWrapper(AudioEncoder* enc) : enc_(enc) {}
107 size_t MaxEncodedBytes() const override { return enc_->MaxEncodedBytes(); }
108 int SampleRateHz() const override { return enc_->SampleRateHz(); }
109 size_t NumChannels() const override { return enc_->NumChannels(); }
110 int RtpTimestampRateHz() const override { return enc_->RtpTimestampRateHz(); }
111 size_t Num10MsFramesInNextPacket() const override {
112 return enc_->Num10MsFramesInNextPacket();
113 }
114 size_t Max10MsFramesInAPacket() const override {
115 return enc_->Max10MsFramesInAPacket();
116 }
117 int GetTargetBitrate() const override { return enc_->GetTargetBitrate(); }
118 EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
119 rtc::ArrayView<const int16_t> audio,
120 rtc::Buffer* encoded) override {
121 return enc_->Encode(rtp_timestamp, audio, encoded);
122 }
123 EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
124 rtc::ArrayView<const int16_t> audio,
125 size_t max_encoded_bytes,
126 uint8_t* encoded) override {
127 return enc_->EncodeInternal(rtp_timestamp, audio, max_encoded_bytes,
128 encoded);
129 }
130 void Reset() override { return enc_->Reset(); }
131 bool SetFec(bool enable) override { return enc_->SetFec(enable); }
132 bool SetDtx(bool enable) override { return enc_->SetDtx(enable); }
133 bool SetApplication(Application application) override {
134 return enc_->SetApplication(application);
135 }
136 void SetMaxPlaybackRate(int frequency_hz) override {
137 return enc_->SetMaxPlaybackRate(frequency_hz);
138 }
139 void SetProjectedPacketLossRate(double fraction) override {
140 return enc_->SetProjectedPacketLossRate(fraction);
141 }
142 void SetTargetBitrate(int target_bps) override {
143 return enc_->SetTargetBitrate(target_bps);
144 }
145
146 private:
147 AudioEncoder* enc_;
148 };
149
150 // Return false on error.
151 bool CreateSpeechEncoderIfNecessary(EncoderFactory* ef) {
152 auto* sp = ef->codec_manager.GetStackParams();
153 if (sp->speech_encoder) {
154 // Do nothing; we already have a speech encoder.
155 } else if (ef->codec_manager.GetCodecInst()) {
156 RTC_DCHECK(!ef->external_speech_encoder);
157 // We have no speech encoder, but we have a specification for making one.
158 std::unique_ptr<AudioEncoder> enc =
159 ef->rent_a_codec.RentEncoder(*ef->codec_manager.GetCodecInst());
160 if (!enc)
161 return false; // Encoder spec was bad.
162 sp->speech_encoder = std::move(enc);
163 } else if (ef->external_speech_encoder) {
164 RTC_DCHECK(!ef->codec_manager.GetCodecInst());
165 // We have an external speech encoder.
166 sp->speech_encoder = std::unique_ptr<AudioEncoder>(
167 new RawAudioEncoderWrapper(ef->external_speech_encoder));
168 }
169 return true;
170 }
171
93 } // namespace 172 } // namespace
94 173
95 void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) { 174 void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) {
96 if (value != last_value_ || first_time_) { 175 if (value != last_value_ || first_time_) {
97 first_time_ = false; 176 first_time_ = false;
98 last_value_ = value; 177 last_value_ = value;
99 RTC_HISTOGRAM_COUNTS_SPARSE_100(histogram_name_, value); 178 RTC_HISTOGRAM_COUNTS_SPARSE_100(histogram_name_, value);
100 } 179 }
101 } 180 }
102 181
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 ///////////////////////////////////////// 272 /////////////////////////////////////////
194 // Sender 273 // Sender
195 // 274 //
196 275
197 // Can be called multiple times for Codec, CNG, RED. 276 // Can be called multiple times for Codec, CNG, RED.
198 int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) { 277 int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
199 rtc::CritScope lock(&acm_crit_sect_); 278 rtc::CritScope lock(&acm_crit_sect_);
200 if (!encoder_factory_->codec_manager.RegisterEncoder(send_codec)) { 279 if (!encoder_factory_->codec_manager.RegisterEncoder(send_codec)) {
201 return -1; 280 return -1;
202 } 281 }
282 if (encoder_factory_->codec_manager.GetCodecInst()) {
283 encoder_factory_->external_speech_encoder = nullptr;
284 }
285 if (!CreateSpeechEncoderIfNecessary(encoder_factory_.get())) {
286 return -1;
287 }
203 auto* sp = encoder_factory_->codec_manager.GetStackParams(); 288 auto* sp = encoder_factory_->codec_manager.GetStackParams();
204 if (!sp->speech_encoder && encoder_factory_->codec_manager.GetCodecInst()) {
205 // We have no speech encoder, but we have a specification for making one.
206 AudioEncoder* enc = encoder_factory_->rent_a_codec.RentEncoder(
207 *encoder_factory_->codec_manager.GetCodecInst());
208 if (!enc)
209 return -1;
210 sp->speech_encoder = enc;
211 }
212 if (sp->speech_encoder) 289 if (sp->speech_encoder)
213 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp); 290 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
214 return 0; 291 return 0;
215 } 292 }
216 293
217 void AudioCodingModuleImpl::RegisterExternalSendCodec( 294 void AudioCodingModuleImpl::RegisterExternalSendCodec(
218 AudioEncoder* external_speech_encoder) { 295 AudioEncoder* external_speech_encoder) {
219 rtc::CritScope lock(&acm_crit_sect_); 296 rtc::CritScope lock(&acm_crit_sect_);
297 encoder_factory_->codec_manager.UnsetCodecInst();
298 encoder_factory_->external_speech_encoder = external_speech_encoder;
299 RTC_CHECK(CreateSpeechEncoderIfNecessary(encoder_factory_.get()));
220 auto* sp = encoder_factory_->codec_manager.GetStackParams(); 300 auto* sp = encoder_factory_->codec_manager.GetStackParams();
221 sp->speech_encoder = external_speech_encoder; 301 RTC_CHECK(sp->speech_encoder);
222 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp); 302 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
223 } 303 }
224 304
225 // Get current send codec. 305 // Get current send codec.
226 rtc::Optional<CodecInst> AudioCodingModuleImpl::SendCodec() const { 306 rtc::Optional<CodecInst> AudioCodingModuleImpl::SendCodec() const {
227 rtc::CritScope lock(&acm_crit_sect_); 307 rtc::CritScope lock(&acm_crit_sect_);
228 auto* ci = encoder_factory_->codec_manager.GetCodecInst(); 308 auto* ci = encoder_factory_->codec_manager.GetCodecInst();
229 if (ci) { 309 if (ci) {
230 return rtc::Optional<CodecInst>(*ci); 310 return rtc::Optional<CodecInst>(*ci);
231 } 311 }
232 auto* enc = encoder_factory_->codec_manager.GetStackParams()->speech_encoder; 312 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
313 const std::unique_ptr<AudioEncoder>& enc =
314 encoder_factory_->codec_manager.GetStackParams()->speech_encoder;
233 if (enc) { 315 if (enc) {
234 return rtc::Optional<CodecInst>(CodecManager::ForgeCodecInst(enc)); 316 return rtc::Optional<CodecInst>(CodecManager::ForgeCodecInst(enc.get()));
235 } 317 }
236 return rtc::Optional<CodecInst>(); 318 return rtc::Optional<CodecInst>();
237 } 319 }
238 320
239 // Get current send frequency. 321 // Get current send frequency.
240 int AudioCodingModuleImpl::SendFrequency() const { 322 int AudioCodingModuleImpl::SendFrequency() const {
241 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, 323 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
242 "SendFrequency()"); 324 "SendFrequency()");
243 rtc::CritScope lock(&acm_crit_sect_); 325 rtc::CritScope lock(&acm_crit_sect_);
244 326
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 526
445 bool AudioCodingModuleImpl::REDStatus() const { 527 bool AudioCodingModuleImpl::REDStatus() const {
446 rtc::CritScope lock(&acm_crit_sect_); 528 rtc::CritScope lock(&acm_crit_sect_);
447 return encoder_factory_->codec_manager.GetStackParams()->use_red; 529 return encoder_factory_->codec_manager.GetStackParams()->use_red;
448 } 530 }
449 531
450 // Configure RED status i.e on/off. 532 // Configure RED status i.e on/off.
451 int AudioCodingModuleImpl::SetREDStatus(bool enable_red) { 533 int AudioCodingModuleImpl::SetREDStatus(bool enable_red) {
452 #ifdef WEBRTC_CODEC_RED 534 #ifdef WEBRTC_CODEC_RED
453 rtc::CritScope lock(&acm_crit_sect_); 535 rtc::CritScope lock(&acm_crit_sect_);
536 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
454 if (!encoder_factory_->codec_manager.SetCopyRed(enable_red)) { 537 if (!encoder_factory_->codec_manager.SetCopyRed(enable_red)) {
455 return -1; 538 return -1;
456 } 539 }
457 auto* sp = encoder_factory_->codec_manager.GetStackParams(); 540 auto* sp = encoder_factory_->codec_manager.GetStackParams();
458 if (sp->speech_encoder) 541 if (sp->speech_encoder)
459 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp); 542 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
460 return 0; 543 return 0;
461 #else 544 #else
462 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, 545 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
463 " WEBRTC_CODEC_RED is undefined"); 546 " WEBRTC_CODEC_RED is undefined");
464 return -1; 547 return -1;
465 #endif 548 #endif
466 } 549 }
467 550
468 ///////////////////////////////////////// 551 /////////////////////////////////////////
469 // (FEC) Forward Error Correction (codec internal) 552 // (FEC) Forward Error Correction (codec internal)
470 // 553 //
471 554
472 bool AudioCodingModuleImpl::CodecFEC() const { 555 bool AudioCodingModuleImpl::CodecFEC() const {
473 rtc::CritScope lock(&acm_crit_sect_); 556 rtc::CritScope lock(&acm_crit_sect_);
474 return encoder_factory_->codec_manager.GetStackParams()->use_codec_fec; 557 return encoder_factory_->codec_manager.GetStackParams()->use_codec_fec;
475 } 558 }
476 559
477 int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) { 560 int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) {
478 rtc::CritScope lock(&acm_crit_sect_); 561 rtc::CritScope lock(&acm_crit_sect_);
562 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
479 if (!encoder_factory_->codec_manager.SetCodecFEC(enable_codec_fec)) { 563 if (!encoder_factory_->codec_manager.SetCodecFEC(enable_codec_fec)) {
480 return -1; 564 return -1;
481 } 565 }
482 auto* sp = encoder_factory_->codec_manager.GetStackParams(); 566 auto* sp = encoder_factory_->codec_manager.GetStackParams();
483 if (sp->speech_encoder) 567 if (sp->speech_encoder)
484 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp); 568 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
485 if (enable_codec_fec) { 569 if (enable_codec_fec) {
486 return sp->use_codec_fec ? 0 : -1; 570 return sp->use_codec_fec ? 0 : -1;
487 } else { 571 } else {
488 RTC_DCHECK(!sp->use_codec_fec); 572 RTC_DCHECK(!sp->use_codec_fec);
(...skipping 11 matching lines...) Expand all
500 584
501 ///////////////////////////////////////// 585 /////////////////////////////////////////
502 // (VAD) Voice Activity Detection 586 // (VAD) Voice Activity Detection
503 // 587 //
504 int AudioCodingModuleImpl::SetVAD(bool enable_dtx, 588 int AudioCodingModuleImpl::SetVAD(bool enable_dtx,
505 bool enable_vad, 589 bool enable_vad,
506 ACMVADMode mode) { 590 ACMVADMode mode) {
507 // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting. 591 // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting.
508 RTC_DCHECK_EQ(enable_dtx, enable_vad); 592 RTC_DCHECK_EQ(enable_dtx, enable_vad);
509 rtc::CritScope lock(&acm_crit_sect_); 593 rtc::CritScope lock(&acm_crit_sect_);
594 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
510 if (!encoder_factory_->codec_manager.SetVAD(enable_dtx, mode)) { 595 if (!encoder_factory_->codec_manager.SetVAD(enable_dtx, mode)) {
511 return -1; 596 return -1;
512 } 597 }
513 auto* sp = encoder_factory_->codec_manager.GetStackParams(); 598 auto* sp = encoder_factory_->codec_manager.GetStackParams();
514 if (sp->speech_encoder) 599 if (sp->speech_encoder)
515 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp); 600 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
516 return 0; 601 return 0;
517 } 602 }
518 603
519 // Get VAD/DTX settings. 604 // Get VAD/DTX settings.
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 return receiver_.LeastRequiredDelayMs(); 901 return receiver_.LeastRequiredDelayMs();
817 } 902 }
818 903
819 void AudioCodingModuleImpl::GetDecodingCallStatistics( 904 void AudioCodingModuleImpl::GetDecodingCallStatistics(
820 AudioDecodingCallStats* call_stats) const { 905 AudioDecodingCallStats* call_stats) const {
821 receiver_.GetDecodingCallStatistics(call_stats); 906 receiver_.GetDecodingCallStatistics(call_stats);
822 } 907 }
823 908
824 } // namespace acm2 909 } // namespace acm2
825 } // namespace webrtc 910 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698