1 //
2 // libtgvoip is free and unencumbered public domain software.
3 // For more information, see http://unlicense.org or the UNLICENSE file
4 // you should have received with this source code distribution.
5 //
6
7 #include "OpusEncoder.h"
8 #include <assert.h>
9 #include <algorithm>
10 #include "logging.h"
11 #include "VoIPServerConfig.h"
12 #if TGVOIP_INCLUDE_OPUS_PACKAGE
13 #include <opus/opus.h>
14 #else
15 #include <opus.h>
16 #endif
17
18 namespace{
serverConfigValueToBandwidth(int config)19 int serverConfigValueToBandwidth(int config){
20 switch(config){
21 case 0:
22 return OPUS_BANDWIDTH_NARROWBAND;
23 case 1:
24 return OPUS_BANDWIDTH_MEDIUMBAND;
25 case 2:
26 return OPUS_BANDWIDTH_WIDEBAND;
27 case 3:
28 return OPUS_BANDWIDTH_SUPERWIDEBAND;
29 case 4:
30 default:
31 return OPUS_BANDWIDTH_FULLBAND;
32 }
33 }
34 }
35
OpusEncoder(MediaStreamItf * source,bool needSecondary)36 tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):queue(11), bufferPool(960*2, 10){
37 this->source=source;
38 source->SetCallback(tgvoip::OpusEncoder::Callback, this);
39 enc=opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
40 opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
41 opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(1));
42 opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
43 opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
44 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
45 requestedBitrate=20000;
46 currentBitrate=0;
47 running=false;
48 echoCanceller=NULL;
49 complexity=10;
50 frameDuration=20;
51 levelMeter=NULL;
52 vadNoVoiceBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_vad_no_voice_bitrate", 6000));
53 vadModeVoiceBandwidth=serverConfigValueToBandwidth(ServerConfig::GetSharedInstance()->GetInt("audio_vad_bandwidth", 3));
54 vadModeNoVoiceBandwidth=serverConfigValueToBandwidth(ServerConfig::GetSharedInstance()->GetInt("audio_vad_no_voice_bandwidth", 0));
55 secondaryEnabledBandwidth=serverConfigValueToBandwidth(ServerConfig::GetSharedInstance()->GetInt("audio_extra_ec_bandwidth", 2));
56 secondaryEncoderEnabled=false;
57
58 if(needSecondary){
59 secondaryEncoder=opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
60 opus_encoder_ctl(secondaryEncoder, OPUS_SET_COMPLEXITY(10));
61 opus_encoder_ctl(secondaryEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
62 //opus_encoder_ctl(secondaryEncoder, OPUS_SET_VBR(0));
63 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(8000));
64 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(secondaryEnabledBandwidth));
65 }else{
66 secondaryEncoder=NULL;
67 }
68 }
69
~OpusEncoder()70 tgvoip::OpusEncoder::~OpusEncoder(){
71 opus_encoder_destroy(enc);
72 if(secondaryEncoder)
73 opus_encoder_destroy(secondaryEncoder);
74 }
75
Start()76 void tgvoip::OpusEncoder::Start(){
77 if(running)
78 return;
79 running=true;
80 thread=new Thread(std::bind(&tgvoip::OpusEncoder::RunThread, this));
81 thread->SetName("OpusEncoder");
82 thread->Start();
83 thread->SetMaxPriority();
84 }
85
Stop()86 void tgvoip::OpusEncoder::Stop(){
87 if(!running)
88 return;
89 running=false;
90 queue.Put(NULL);
91 thread->Join();
92 delete thread;
93 }
94
95
SetBitrate(uint32_t bitrate)96 void tgvoip::OpusEncoder::SetBitrate(uint32_t bitrate){
97 requestedBitrate=bitrate;
98 }
99
Encode(int16_t * data,size_t len)100 void tgvoip::OpusEncoder::Encode(int16_t* data, size_t len){
101 if(requestedBitrate!=currentBitrate){
102 opus_encoder_ctl(enc, OPUS_SET_BITRATE(requestedBitrate));
103 currentBitrate=requestedBitrate;
104 LOGV("opus_encoder: setting bitrate to %u", currentBitrate);
105 }
106 if(levelMeter)
107 levelMeter->Update(data, len);
108 if(secondaryEncoderEnabled!=wasSecondaryEncoderEnabled){
109 wasSecondaryEncoderEnabled=secondaryEncoderEnabled;
110 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(secondaryEncoderEnabled ? secondaryEnabledBandwidth : OPUS_BANDWIDTH_FULLBAND));
111 }
112 int32_t r=opus_encode(enc, data, static_cast<int>(len), buffer, 4096);
113 if(r<=0){
114 LOGE("Error encoding: %d", r);
115 }else if(r==1){
116 LOGW("DTX");
117 }else if(running){
118 //LOGV("Packet size = %d", r);
119 int32_t secondaryLen=0;
120 unsigned char secondaryBuffer[128];
121 if(secondaryEncoderEnabled && secondaryEncoder){
122 secondaryLen=opus_encode(secondaryEncoder, data, static_cast<int>(len), secondaryBuffer, sizeof(secondaryBuffer));
123 //LOGV("secondaryLen %d", secondaryLen);
124 }
125 InvokeCallback(buffer, (size_t)r, secondaryBuffer, (size_t)secondaryLen);
126 }
127 }
128
Callback(unsigned char * data,size_t len,void * param)129 size_t tgvoip::OpusEncoder::Callback(unsigned char *data, size_t len, void* param){
130 OpusEncoder* e=(OpusEncoder*)param;
131 unsigned char* buf=e->bufferPool.Get();
132 if(buf){
133 assert(len==960*2);
134 memcpy(buf, data, 960*2);
135 e->queue.Put(buf);
136 }else{
137 LOGW("opus_encoder: no buffer slots left");
138 if(e->complexity>1){
139 e->complexity--;
140 opus_encoder_ctl(e->enc, OPUS_SET_COMPLEXITY(e->complexity));
141 }
142 }
143 return 0;
144 }
145
146
GetBitrate()147 uint32_t tgvoip::OpusEncoder::GetBitrate(){
148 return requestedBitrate;
149 }
150
SetEchoCanceller(EchoCanceller * aec)151 void tgvoip::OpusEncoder::SetEchoCanceller(EchoCanceller* aec){
152 echoCanceller=aec;
153 }
154
RunThread()155 void tgvoip::OpusEncoder::RunThread(){
156 uint32_t bufferedCount=0;
157 uint32_t packetsPerFrame=frameDuration/20;
158 LOGV("starting encoder, packets per frame=%d", packetsPerFrame);
159 int16_t* frame;
160 if(packetsPerFrame>1)
161 frame=(int16_t*) malloc(960*2*packetsPerFrame);
162 else
163 frame=NULL;
164 bool frameHasVoice=false;
165 bool wasVadMode=false;
166 while(running){
167 int16_t* packet=(int16_t*)queue.GetBlocking();
168 if(packet){
169 bool hasVoice=true;
170 if(echoCanceller)
171 echoCanceller->ProcessInput(packet, 960, hasVoice);
172 if(!postProcEffects.empty()){
173 for(effects::AudioEffect* effect:postProcEffects){
174 effect->Process(packet, 960);
175 }
176 }
177 if(packetsPerFrame==1){
178 Encode(packet, 960);
179 }else{
180 memcpy(frame+(960*bufferedCount), packet, 960*2);
181 frameHasVoice=frameHasVoice || hasVoice;
182 bufferedCount++;
183 if(bufferedCount==packetsPerFrame){
184 if(vadMode){
185 if(frameHasVoice){
186 opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
187 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(vadModeVoiceBandwidth));
188 if(secondaryEncoder){
189 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
190 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(vadModeVoiceBandwidth));
191 }
192 }else{
193 opus_encoder_ctl(enc, OPUS_SET_BITRATE(vadNoVoiceBitrate));
194 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(vadModeNoVoiceBandwidth));
195 if(secondaryEncoder){
196 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(vadNoVoiceBitrate));
197 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(vadModeNoVoiceBandwidth));
198 }
199 }
200 wasVadMode=true;
201 }else if(wasVadMode){
202 wasVadMode=false;
203 opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
204 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(secondaryEncoderEnabled ? secondaryEnabledBandwidth : OPUS_AUTO));
205 if(secondaryEncoder){
206 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
207 opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(secondaryEnabledBandwidth));
208 }
209 }
210 Encode(frame, 960*packetsPerFrame);
211 bufferedCount=0;
212 frameHasVoice=false;
213 }
214 }
215 bufferPool.Reuse(reinterpret_cast<unsigned char *>(packet));
216 }
217 }
218 if(frame)
219 free(frame);
220 }
221
222
SetOutputFrameDuration(uint32_t duration)223 void tgvoip::OpusEncoder::SetOutputFrameDuration(uint32_t duration){
224 frameDuration=duration;
225 }
226
227
SetPacketLoss(int percent)228 void tgvoip::OpusEncoder::SetPacketLoss(int percent){
229 packetLossPercent=std::min(20, percent);
230 opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packetLossPercent));
231 opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(percent>0 && !secondaryEncoderEnabled ? 1 : 0));
232 }
233
GetPacketLoss()234 int tgvoip::OpusEncoder::GetPacketLoss(){
235 return packetLossPercent;
236 }
237
SetDTX(bool enable)238 void tgvoip::OpusEncoder::SetDTX(bool enable){
239 opus_encoder_ctl(enc, OPUS_SET_DTX(enable ? 1 : 0));
240 }
241
SetLevelMeter(tgvoip::AudioLevelMeter * levelMeter)242 void tgvoip::OpusEncoder::SetLevelMeter(tgvoip::AudioLevelMeter *levelMeter){
243 this->levelMeter=levelMeter;
244 }
245
SetCallback(void (* f)(unsigned char *,size_t,unsigned char *,size_t,void *),void * param)246 void tgvoip::OpusEncoder::SetCallback(void (*f)(unsigned char *, size_t, unsigned char *, size_t, void *), void *param){
247 callback=f;
248 callbackParam=param;
249 }
250
InvokeCallback(unsigned char * data,size_t length,unsigned char * secondaryData,size_t secondaryLength)251 void tgvoip::OpusEncoder::InvokeCallback(unsigned char *data, size_t length, unsigned char *secondaryData, size_t secondaryLength){
252 callback(data, length, secondaryData, secondaryLength, callbackParam);
253 }
254
SetSecondaryEncoderEnabled(bool enabled)255 void tgvoip::OpusEncoder::SetSecondaryEncoderEnabled(bool enabled){
256 secondaryEncoderEnabled=enabled;
257 }
258
SetVadMode(bool vad)259 void tgvoip::OpusEncoder::SetVadMode(bool vad){
260 vadMode=vad;
261 }
AddAudioEffect(effects::AudioEffect * effect)262 void tgvoip::OpusEncoder::AddAudioEffect(effects::AudioEffect *effect){
263 postProcEffects.push_back(effect);
264 }
265
RemoveAudioEffect(effects::AudioEffect * effect)266 void tgvoip::OpusEncoder::RemoveAudioEffect(effects::AudioEffect *effect){
267 std::vector<effects::AudioEffect*>::iterator i=std::find(postProcEffects.begin(), postProcEffects.end(), effect);
268 if(i!=postProcEffects.end())
269 postProcEffects.erase(i);
270 }
271