3
* Copyright 2004--2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#ifndef TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_
29
#define TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_
36
#include "talk/base/buffer.h"
37
#include "talk/base/byteorder.h"
38
#include "talk/base/logging.h"
39
#include "talk/base/scoped_ptr.h"
40
#include "talk/base/stream.h"
41
#include "talk/session/phone/channel.h"
42
#include "talk/session/phone/rtputils.h"
43
#include "talk/session/phone/webrtccommon.h"
44
#include "talk/session/phone/webrtcvoe.h"
45
#ifdef WEBRTC_RELATIVE_PATH
46
#include "voice_engine/main/interface/voe_base.h"
48
#include "third_party/webrtc/files/include/voe_base.h"
49
#endif // WEBRTC_RELATIVE_PATH
53
// WebRtcSoundclipStream is an adapter object that allows a memory stream to be
54
// passed into WebRtc, and support looping.
55
class WebRtcSoundclipStream : public webrtc::InStream {
57
WebRtcSoundclipStream(const char* buf, size_t len)
58
: mem_(buf, len), loop_(true) {
60
void set_loop(bool loop) { loop_ = loop; }
61
virtual int Read(void* buf, int len);
65
talk_base::MemoryStream mem_;
69
// WebRtcMonitorStream is used to monitor a stream coming from WebRtc.
70
// For now we just dump the data.
71
class WebRtcMonitorStream : public webrtc::OutStream {
72
virtual bool Write(const void *buf, int len) {
77
class AudioDeviceModule;
78
class VoETraceWrapper;
81
class WebRtcSoundclipMedia;
82
class WebRtcVoiceMediaChannel;
84
// WebRtcVoiceEngine is a class to be used with CompositeMediaEngine.
85
// It uses the WebRtc VoiceEngine library for audio handling.
86
class WebRtcVoiceEngine
87
: public webrtc::VoiceEngineObserver,
88
public webrtc::TraceCallback,
89
public webrtc::VoEMediaProcess {
92
// Dependency injection for testing.
93
WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
94
VoEWrapper* voe_wrapper_sc,
95
VoETraceWrapper* tracing);
100
int GetCapabilities();
101
VoiceMediaChannel* CreateChannel();
103
SoundclipMedia* CreateSoundclip();
105
bool SetOptions(int options);
106
bool SetDevices(const Device* in_device, const Device* out_device);
107
bool GetOutputVolume(int* level);
108
bool SetOutputVolume(int level);
110
bool SetLocalMonitor(bool enable);
112
const std::vector<AudioCodec>& codecs();
113
bool FindCodec(const AudioCodec& codec);
114
bool FindWebRtcCodec(const AudioCodec& codec, webrtc::CodecInst* gcodec);
116
void SetLogging(int min_sev, const char* filter);
118
bool RegisterProcessor(uint32 ssrc,
119
VoiceProcessor* voice_processor,
120
MediaProcessorDirection direction);
121
bool UnregisterProcessor(uint32 ssrc,
122
VoiceProcessor* voice_processor,
123
MediaProcessorDirection direction);
125
// Method from webrtc::VoEMediaProcess
126
virtual void Process(const int channel,
127
const webrtc::ProcessingTypes type,
128
WebRtc_Word16 audio10ms[],
130
const int sampling_freq,
131
const bool is_stereo);
133
// For tracking WebRtc channels. Needed because we have to pause them
134
// all when switching devices.
135
// May only be called by WebRtcVoiceMediaChannel.
136
void RegisterChannel(WebRtcVoiceMediaChannel *channel);
137
void UnregisterChannel(WebRtcVoiceMediaChannel *channel);
139
// May only be called by WebRtcSoundclipMedia.
140
void RegisterSoundclip(WebRtcSoundclipMedia *channel);
141
void UnregisterSoundclip(WebRtcSoundclipMedia *channel);
143
// Called by WebRtcVoiceMediaChannel to set a gain offset from
144
// the default AGC target level.
145
bool AdjustAgcLevel(int delta);
147
// Called by WebRtcVoiceMediaChannel to configure echo cancellation
148
// and noise suppression modes.
149
bool SetConferenceMode(bool enable);
151
VoEWrapper* voe() { return voe_wrapper_.get(); }
152
VoEWrapper* voe_sc() { return voe_wrapper_sc_.get(); }
153
int GetLastEngineError();
155
// Set the external ADMs. This can only be called before Init.
156
bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
157
webrtc::AudioDeviceModule* adm_sc);
159
// Check whether the supplied trace should be ignored.
160
bool ShouldIgnoreTrace(const std::string& trace);
163
typedef std::vector<WebRtcSoundclipMedia *> SoundclipList;
164
typedef std::vector<WebRtcVoiceMediaChannel *> ChannelList;
166
signal3<uint32, MediaProcessorDirection, AudioFrame*> FrameSignal;
175
void ConstructCodecs();
177
void ApplyLogging(const std::string& log_filter);
178
virtual void Print(const webrtc::TraceLevel level,
179
const char* trace_string, const int length);
180
virtual void CallbackOnError(const int channel, const int errCode);
181
// Given the device type, name, and id, find device id. Return true and
182
// set the output parameter rtc_id if successful.
183
bool FindWebRtcAudioDeviceId(
184
bool is_input, const std::string& dev_name, int dev_id, int* rtc_id);
185
bool FindChannelAndSsrc(int channel_num,
186
WebRtcVoiceMediaChannel** channel,
188
bool FindChannelNumFromSsrc(uint32 ssrc,
189
MediaProcessorDirection direction,
191
bool ChangeLocalMonitor(bool enable);
192
bool PauseLocalMonitor();
193
bool ResumeLocalMonitor();
195
bool UnregisterProcessorChannel(MediaProcessorDirection channel_direction,
197
VoiceProcessor* voice_processor,
198
MediaProcessorDirection processor_direction);
200
// When a voice processor registers with the engine, it is connected
201
// to either the Rx or Tx signals, based on the direction parameter.
202
// SignalXXMediaFrame will be invoked for every audio packet.
203
FrameSignal SignalRxMediaFrame;
204
FrameSignal SignalTxMediaFrame;
206
static const int kDefaultLogSeverity = talk_base::LS_WARNING;
207
static const CodecPref kCodecPrefs[];
209
// The primary instance of WebRtc VoiceEngine.
210
talk_base::scoped_ptr<VoEWrapper> voe_wrapper_;
211
// A secondary instance, for playing out soundclips (on the 'ring' device).
212
talk_base::scoped_ptr<VoEWrapper> voe_wrapper_sc_;
213
talk_base::scoped_ptr<VoETraceWrapper> tracing_;
214
// The external audio device manager
215
webrtc::AudioDeviceModule* adm_;
216
webrtc::AudioDeviceModule* adm_sc_;
218
std::string log_filter_;
219
bool is_dumping_aec_;
220
std::vector<AudioCodec> codecs_;
221
bool desired_local_monitor_enable_;
222
talk_base::scoped_ptr<WebRtcMonitorStream> monitor_;
223
SoundclipList soundclips_;
224
ChannelList channels_;
225
// channels_ can be read from WebRtc callback thread. We need a lock on that
226
// callback as well as the RegisterChannel/UnregisterChannel.
227
talk_base::CriticalSection channels_cs_;
228
webrtc::AgcConfig default_agc_config_;
231
talk_base::CriticalSection signal_media_critical_;
234
// WebRtcMediaChannel is a class that implements the common WebRtc channel
236
template <class T, class E>
237
class WebRtcMediaChannel : public T, public webrtc::Transport {
239
WebRtcMediaChannel(E *engine, int channel)
240
: engine_(engine), voe_channel_(channel), sequence_number_(-1) {}
241
E *engine() { return engine_; }
242
int voe_channel() const { return voe_channel_; }
243
bool valid() const { return voe_channel_ != -1; }
246
// implements Transport interface
247
virtual int SendPacket(int channel, const void *data, int len) {
248
if (!T::network_interface_) {
252
// We need to store the sequence number to be able to pick up
253
// the same sequence when the device is restarted.
254
// TODO: Remove when WebRtc has fixed the problem.
256
if (!GetRtpSeqNum(data, len, &seq_num)) {
259
if (sequence_number() == -1) {
260
LOG(INFO) << "WebRtcVoiceMediaChannel sends first packet seqnum="
263
sequence_number_ = seq_num;
265
talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
266
return T::network_interface_->SendPacket(&packet) ? len : -1;
268
virtual int SendRTCPPacket(int channel, const void *data, int len) {
269
if (!T::network_interface_) {
273
talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
274
return T::network_interface_->SendRtcp(&packet) ? len : -1;
276
int sequence_number() const {
277
return sequence_number_;
283
int sequence_number_;
286
// WebRtcVoiceMediaChannel is an implementation of VoiceMediaChannel that uses
287
// WebRtc Voice Engine.
288
class WebRtcVoiceMediaChannel
289
: public WebRtcMediaChannel<VoiceMediaChannel, WebRtcVoiceEngine> {
291
explicit WebRtcVoiceMediaChannel(WebRtcVoiceEngine *engine);
292
virtual ~WebRtcVoiceMediaChannel();
293
virtual bool SetOptions(int options);
294
virtual int GetOptions() const { return options_; }
295
virtual bool SetRecvCodecs(const std::vector<AudioCodec> &codecs);
296
virtual bool SetSendCodecs(const std::vector<AudioCodec> &codecs);
297
virtual bool SetRecvRtpHeaderExtensions(
298
const std::vector<RtpHeaderExtension>& extensions);
299
virtual bool SetSendRtpHeaderExtensions(
300
const std::vector<RtpHeaderExtension>& extensions);
301
virtual bool SetPlayout(bool playout);
303
bool ResumePlayout();
304
virtual bool SetSend(SendFlags send);
307
virtual bool AddSendStream(const StreamParams& sp);
308
virtual bool RemoveSendStream(uint32 ssrc);
309
virtual bool AddRecvStream(const StreamParams& sp);
310
virtual bool RemoveRecvStream(uint32 ssrc);
311
virtual bool GetActiveStreams(AudioInfo::StreamList* actives);
312
virtual int GetOutputLevel();
313
virtual bool SetOutputScaling(uint32 ssrc, double left, double right);
314
virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right);
316
virtual bool SetRingbackTone(const char *buf, int len);
317
virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
318
virtual bool PressDTMF(int event, bool playout);
320
virtual void OnPacketReceived(talk_base::Buffer* packet);
321
virtual void OnRtcpReceived(talk_base::Buffer* packet);
322
virtual bool Mute(bool mute);
323
virtual bool SetSendBandwidth(bool autobw, int bps) { return false; }
324
virtual bool GetStats(VoiceMediaInfo* info);
325
// Gets last reported error from WebRtc voice engine. This should be only
326
// called in response a failure.
327
virtual void GetLastMediaError(uint32* ssrc,
328
VoiceMediaChannel::Error* error);
329
bool FindSsrc(int channel_num, uint32* ssrc);
330
void OnError(uint32 ssrc, int error);
332
bool sending() const { return send_ != SEND_NOTHING; }
333
int GetChannelNum(uint32 ssrc);
336
int GetLastEngineError() { return engine()->GetLastEngineError(); }
337
int GetOutputLevel(int channel);
338
bool GetRedSendCodec(const AudioCodec& red_codec,
339
const std::vector<AudioCodec>& all_codecs,
340
webrtc::CodecInst* send_codec);
341
bool EnableRtcp(int channel);
342
bool ResetRecvCodecs(int channel);
343
bool SetPlayout(int channel, bool playout);
344
static uint32 ParseSsrc(const void* data, size_t len, bool rtcp);
345
static Error WebRtcErrorToChannelError(int err_code);
348
// A -10dB gain adjustment is actually +10 in
349
// AgcConfig.targetLeveldBOv
350
static const int kMinus10DbAdjustment = 10;
352
bool ChangePlayout(bool playout);
353
bool ChangeSend(SendFlags send);
355
typedef std::map<uint32, int> ChannelMap;
356
talk_base::scoped_ptr<WebRtcSoundclipStream> ringback_tone_;
357
std::set<int> ringback_channels_; // channels playing ringback
358
bool recv_codecs_set_;
359
talk_base::scoped_ptr<webrtc::CodecInst> send_codec_;
363
bool desired_playout_;
365
SendFlags desired_send_;
369
ChannelMap mux_channels_; // for multiple sources
370
// mux_channels_ can be read from WebRtc callback thread. Accesses off the
371
// WebRtc thread must be synchronized with edits on the worker thread. Reads
372
// on the worker thread are ok.
373
mutable talk_base::CriticalSection mux_channels_cs_;
376
} // namespace cricket
378
#endif // TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_