OLD | NEW |
| (Empty) |
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 #include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" | |
12 | |
13 #include "webrtc/base/checks.h" | |
14 #include "webrtc/base/logging.h" | |
15 #include "webrtc/engine_configurations.h" | |
16 #include "webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h" | |
17 #ifdef WEBRTC_CODEC_RED | |
18 #include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h" | |
19 #endif | |
20 | |
21 namespace webrtc { | |
22 namespace acm2 { | |
23 | |
24 CodecOwner::CodecOwner() : speech_encoder_(nullptr) { | |
25 } | |
26 | |
27 CodecOwner::~CodecOwner() = default; | |
28 | |
29 namespace { | |
30 | |
31 AudioEncoder* CreateRedEncoder(int red_payload_type, | |
32 AudioEncoder* encoder, | |
33 rtc::scoped_ptr<AudioEncoder>* red_encoder) { | |
34 #ifdef WEBRTC_CODEC_RED | |
35 if (red_payload_type != -1) { | |
36 AudioEncoderCopyRed::Config config; | |
37 config.payload_type = red_payload_type; | |
38 config.speech_encoder = encoder; | |
39 red_encoder->reset(new AudioEncoderCopyRed(config)); | |
40 return red_encoder->get(); | |
41 } | |
42 #endif | |
43 | |
44 red_encoder->reset(); | |
45 return encoder; | |
46 } | |
47 | |
48 void CreateCngEncoder(int cng_payload_type, | |
49 ACMVADMode vad_mode, | |
50 AudioEncoder* encoder, | |
51 rtc::scoped_ptr<AudioEncoder>* cng_encoder) { | |
52 if (cng_payload_type == -1) { | |
53 cng_encoder->reset(); | |
54 return; | |
55 } | |
56 AudioEncoderCng::Config config; | |
57 config.num_channels = encoder->NumChannels(); | |
58 config.payload_type = cng_payload_type; | |
59 config.speech_encoder = encoder; | |
60 switch (vad_mode) { | |
61 case VADNormal: | |
62 config.vad_mode = Vad::kVadNormal; | |
63 break; | |
64 case VADLowBitrate: | |
65 config.vad_mode = Vad::kVadLowBitrate; | |
66 break; | |
67 case VADAggr: | |
68 config.vad_mode = Vad::kVadAggressive; | |
69 break; | |
70 case VADVeryAggr: | |
71 config.vad_mode = Vad::kVadVeryAggressive; | |
72 break; | |
73 default: | |
74 FATAL(); | |
75 } | |
76 cng_encoder->reset(new AudioEncoderCng(config)); | |
77 } | |
78 } // namespace | |
79 | |
80 void CodecOwner::SetEncoders(AudioEncoder* external_speech_encoder, | |
81 int cng_payload_type, | |
82 ACMVADMode vad_mode, | |
83 int red_payload_type) { | |
84 speech_encoder_ = external_speech_encoder; | |
85 ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); | |
86 } | |
87 | |
88 void CodecOwner::ChangeCngAndRed(int cng_payload_type, | |
89 ACMVADMode vad_mode, | |
90 int red_payload_type) { | |
91 RTC_DCHECK(speech_encoder_); | |
92 if (cng_payload_type != -1 || red_payload_type != -1) { | |
93 // The RED and CNG encoders need to be in sync with the speech encoder, so | |
94 // reset the latter to ensure its buffer is empty. | |
95 speech_encoder_->Reset(); | |
96 } | |
97 AudioEncoder* encoder = CreateRedEncoder( | |
98 red_payload_type, speech_encoder_, &red_encoder_); | |
99 CreateCngEncoder(cng_payload_type, vad_mode, encoder, &cng_encoder_); | |
100 } | |
101 | |
102 AudioEncoder* CodecOwner::Encoder() { | |
103 const auto& const_this = *this; | |
104 return const_cast<AudioEncoder*>(const_this.Encoder()); | |
105 } | |
106 | |
107 const AudioEncoder* CodecOwner::Encoder() const { | |
108 if (cng_encoder_) | |
109 return cng_encoder_.get(); | |
110 if (red_encoder_) | |
111 return red_encoder_.get(); | |
112 return speech_encoder_; | |
113 } | |
114 | |
115 } // namespace acm2 | |
116 } // namespace webrtc | |
OLD | NEW |