1
Index: talk/session/phone/linphonemediaengine.h
2
===================================================================
3
--- talk/session/phone/linphonemediaengine.h (revision 1355325)
4
+++ talk/session/phone/linphonemediaengine.h (working copy)
6
#ifndef TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
7
#define TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
15
LinphoneMediaEngine(const std::string& ringWav, const std::string& callWav);
16
virtual ~LinphoneMediaEngine() {}
18
- // Should be called before codecs() and video_codecs() are called. We need to
19
- // set the voice and video codecs; otherwise, Jingle initiation will fail.
20
- void set_voice_codecs(const std::vector<AudioCodec>& codecs) {
21
- voice_codecs_ = codecs;
23
- void set_video_codecs(const std::vector<VideoCodec>& codecs) {
24
- video_codecs_ = codecs;
27
// Implement pure virtual methods of MediaEngine.
28
- virtual bool Init();
29
+ virtual bool Init() { return true; }
30
virtual void Terminate();
31
virtual int GetCapabilities();
32
virtual VoiceMediaChannel* CreateChannel();
34
virtual bool SetLocalRenderer(VideoRenderer* renderer) { return true; }
35
// TODO: control channel send?
36
virtual CaptureResult SetVideoCapture(bool capture) { return CR_SUCCESS; }
37
- virtual const std::vector<AudioCodec>& audio_codecs() {
38
- return voice_codecs_;
40
- virtual const std::vector<VideoCodec>& video_codecs() {
41
- return video_codecs_;
43
+ virtual const std::vector<AudioCodec>& audio_codecs() { return voice_codecs_; }
44
+ virtual const std::vector<VideoCodec>& video_codecs() { return video_codecs_; }
45
virtual bool FindAudioCodec(const AudioCodec& codec);
46
virtual bool FindVideoCodec(const VideoCodec& codec) { return true; }
47
virtual void SetVoiceLogging(int min_sev, const char* filter) {}
48
virtual void SetVideoLogging(int min_sev, const char* filter) {}
49
+ virtual bool SetVideoCapturer(cricket::VideoCapturer*, uint32) { return true; }
50
+ virtual bool GetOutputVolume(int*) { return true; }
51
+ virtual bool RegisterVideoProcessor(cricket::VideoProcessor*) { return true; }
52
+ virtual bool UnregisterVideoProcessor(cricket::VideoProcessor*) { return true; }
53
+ virtual bool RegisterVoiceProcessor(uint32, cricket::VoiceProcessor*, cricket::MediaProcessorDirection) { return true; }
54
+ virtual bool UnregisterVoiceProcessor(uint32, cricket::VoiceProcessor*, cricket::MediaProcessorDirection) { return true; }
56
std::string GetRingWav(){return ring_wav_;}
57
std::string GetCallWav(){return call_wav_;}
65
- std::string voice_input_filename_;
66
- std::string voice_output_filename_;
67
- std::string video_input_filename_;
68
- std::string video_output_filename_;
69
std::vector<AudioCodec> voice_codecs_;
70
std::vector<VideoCodec> video_codecs_;
73
virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs);
74
virtual bool SetPlayout(bool playout);
75
virtual bool SetSend(SendFlags flag);
76
- virtual bool AddStream(uint32 ssrc) { return true; }
77
- virtual bool RemoveStream(uint32 ssrc) { return true; }
78
virtual bool GetActiveStreams(AudioInfo::StreamList* actives) { return true; }
79
virtual int GetOutputLevel() { return 0; }
80
virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
82
virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
85
- virtual void SetRingbackTone(const char* buf, int len) {}
86
+ virtual bool SetRingbackTone(const char* buf, int len) { return true; }
87
virtual bool PlayRingbackTone(bool play, bool loop) { return true; }
88
virtual bool PressDTMF(int event, bool playout) { return true; }
89
virtual bool GetStats(VoiceMediaInfo* info) { return true; }
91
// Implement pure virtual methods of MediaChannel.
92
virtual void OnPacketReceived(talk_base::Buffer* packet);
93
- virtual void OnRtcpReceived(talk_base::Buffer* packet) {}
94
- virtual void SetSendSsrc(uint32 id) {} // TODO: change RTP packet?
95
- virtual bool SetRtcpCName(const std::string& cname) { return true; }
96
+ virtual void OnRtcpReceived(talk_base::Buffer* packet) { OnPacketReceived(packet); }
97
virtual bool Mute(bool on) { return mute_; }
98
virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
99
virtual bool SetOptions(int options) { return true; }
101
const std::vector<RtpHeaderExtension>& extensions) { return true; }
102
virtual bool SetSendRtpHeaderExtensions(
103
const std::vector<RtpHeaderExtension>& extensions) { return true; }
104
+ virtual bool AddSendStream(const cricket::StreamParams&) { return true; }
105
+ virtual bool RemoveSendStream(uint32) { return true; }
106
+ virtual bool AddRecvStream(const cricket::StreamParams&) { return true; }
107
+ virtual bool RemoveRecvStream(uint32) { return true; }
108
+ virtual int GetOptions() const { return 0; }
109
+ virtual bool PlayRingbackTone(uint32, bool, bool) { return true; }
111
virtual void StartRing(bool bIncomingCall);
112
virtual void StopRing();
114
talk_base::scoped_ptr<talk_base::AsyncSocket> socket_;
115
void OnIncomingData(talk_base::AsyncSocket *s);
117
+ int port1; // local port for audio_stream
118
+ int port2; // local port for rtp
120
DISALLOW_COPY_AND_ASSIGN(LinphoneVoiceChannel);
123
} // namespace cricket
125
+#endif // HAVE_LINPHONE
127
#endif // TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
128
Index: talk/session/phone/linphonemediaengine.cc
129
===================================================================
130
--- talk/session/phone/linphonemediaengine.cc (revision 1355325)
131
+++ talk/session/phone/linphonemediaengine.cc (working copy)
133
#define MSILBC_LIBRARY "/usr/lib/mediastreamer/plugins/libmsilbc.so"
136
+#define PORT_UNUSED -1
138
+#ifdef HAVE_LINPHONE
140
// LinphoneMediaEngine is a Linphone implementation of MediaEngine
142
#include <mediastreamer2/mediastream.h>
144
///////////////////////////////////////////////////////////////////////////
145
// Implementation of LinphoneMediaEngine.
146
///////////////////////////////////////////////////////////////////////////
147
-LinphoneMediaEngine::LinphoneMediaEngine(const std::string& ringWav, const std::string& callWav) : ring_wav_(ringWav), call_wav_(callWav) { }
149
-bool LinphoneMediaEngine::Init() {
150
+LinphoneMediaEngine::LinphoneMediaEngine(const std::string& ringWav, const std::string& callWav) : ring_wav_(ringWav), call_wav_(callWav) {
156
char * path = strdup(MSILBC_LIBRARY);
157
char * dirc = dirname(path);
158
ms_load_plugins(dirc);
162
if (ms_filter_codec_supported("iLBC"))
173
- voice_codecs_.push_back(AudioCodec(110, payload_type_speex_wb.mime_type, payload_type_speex_wb.clock_rate, 0, 1, 8));
174
- voice_codecs_.push_back(AudioCodec(111, payload_type_speex_nb.mime_type, payload_type_speex_nb.clock_rate, 0, 1, 7));
176
+ if (ms_filter_codec_supported("speex"))
179
+ have_speex = false;
182
+ if (ms_filter_codec_supported("gsm"))
188
+ voice_codecs_.push_back(AudioCodec(110, payload_type_speex_wb.mime_type, payload_type_speex_wb.clock_rate, 0, 1, 8));
189
+ voice_codecs_.push_back(AudioCodec(111, payload_type_speex_nb.mime_type, payload_type_speex_nb.clock_rate, 0, 1, 7));
193
voice_codecs_.push_back(AudioCodec(102, payload_type_ilbc.mime_type, payload_type_ilbc.clock_rate, 0, 1, 4));
197
+ voice_codecs_.push_back(AudioCodec(3, payload_type_gsm.mime_type, payload_type_gsm.clock_rate, 0, 1, 3));
199
voice_codecs_.push_back(AudioCodec(0, payload_type_pcmu8000.mime_type, payload_type_pcmu8000.clock_rate, 0, 1, 2));
200
voice_codecs_.push_back(AudioCodec(101, payload_type_telephone_event.mime_type, payload_type_telephone_event.clock_rate, 0, 1, 1));
204
void LinphoneMediaEngine::Terminate() {
205
@@ -114,19 +124,18 @@
207
if (c.name == payload_type_telephone_event.mime_type)
210
- if (c.name == payload_type_speex_wb.mime_type && c.clockrate == payload_type_speex_wb.clock_rate)
211
+ if (have_speex && c.name == payload_type_speex_wb.mime_type && c.clockrate == payload_type_speex_wb.clock_rate)
213
- if (c.name == payload_type_speex_nb.mime_type && c.clockrate == payload_type_speex_nb.clock_rate)
214
+ if (have_speex && c.name == payload_type_speex_nb.mime_type && c.clockrate == payload_type_speex_nb.clock_rate)
218
if (have_ilbc && c.name == payload_type_ilbc.mime_type)
221
+ if (have_gsm && c.name == payload_type_gsm.mime_type)
227
///////////////////////////////////////////////////////////////////////////
228
// Implementation of LinphoneVoiceChannel.
229
///////////////////////////////////////////////////////////////////////////
230
@@ -137,11 +146,13 @@
234
- talk_base::Thread *thread = talk_base::ThreadManager::CurrentThread();
235
+ talk_base::Thread *thread = talk_base::ThreadManager::Instance()->CurrentThread();
236
talk_base::SocketServer *ss = thread->socketserver();
237
socket_.reset(ss->CreateAsyncSocket(SOCK_DGRAM));
239
- socket_->Bind(talk_base::SocketAddress("localhost",3000));
240
+ socket_->Bind(talk_base::SocketAddress("localhost", 0)); /* 0 means that OS will choose some free port */
241
+ port1 = socket_->GetLocalAddress().port(); /* and here we get port choosed by OS */
242
+ port2 = PORT_UNUSED;
243
socket_->SignalReadEvent.connect(this, &LinphoneVoiceChannel::OnIncomingData);
246
@@ -171,31 +182,25 @@
248
if (!engine_->FindAudioCodec(*i))
251
if (engine_->have_ilbc && i->name == payload_type_ilbc.mime_type) {
252
rtp_profile_set_payload(&av_profile, i->id, &payload_type_ilbc);
256
- if (i->name == payload_type_speex_wb.mime_type && i->clockrate == payload_type_speex_wb.clock_rate) {
257
+ } else if (engine_->have_speex && i->name == payload_type_speex_wb.mime_type && i->clockrate == payload_type_speex_wb.clock_rate) {
258
rtp_profile_set_payload(&av_profile, i->id, &payload_type_speex_wb);
259
- } else if (i->name == payload_type_speex_nb.mime_type && i->clockrate == payload_type_speex_nb.clock_rate) {
260
+ } else if (engine_->have_speex && i->name == payload_type_speex_nb.mime_type && i->clockrate == payload_type_speex_nb.clock_rate) {
261
rtp_profile_set_payload(&av_profile, i->id, &payload_type_speex_nb);
266
+ } else if (engine_->have_gsm && i->name == payload_type_gsm.mime_type) {
267
+ rtp_profile_set_payload(&av_profile, i->id, &payload_type_gsm);
268
+ } else if (i->name == payload_type_telephone_event.mime_type) {
269
+ rtp_profile_set_payload(&av_profile, i->id, &payload_type_telephone_event);
270
+ } else if (i->id == 0)
271
rtp_profile_set_payload(&av_profile, 0, &payload_type_pcmu8000);
273
- if (i->name == payload_type_telephone_event.mime_type) {
274
- rtp_profile_set_payload(&av_profile, i->id, &payload_type_telephone_event);
279
LOG(LS_INFO) << "Using " << i->name << "/" << i->clockrate;
281
- audio_stream_ = audio_stream_start(&av_profile, 2000, "127.0.0.1", 3000, i->id, 250, 0);
282
+ audio_stream_ = audio_stream_start(&av_profile, -1, "localhost", port1, i->id, 250, 0); /* -1 means that function will choose some free port */
283
+ port2 = rtp_session_get_local_port(audio_stream_->session);
288
// We're being asked to set an empty list of codecs. This will only happen when
289
// working with a buggy client; let's try PCMU.
290
LOG(LS_WARNING) << "Received empty list of codces; using PCMU/8000";
291
- audio_stream_ = audio_stream_start(&av_profile, 2000, "127.0.0.1", 3000, 0, 250, 0);
292
+ audio_stream_ = audio_stream_start(&av_profile, -1, "localhost", port1, 0, 250, 0); /* -1 means that function will choose some free port */
293
+ port2 = rtp_session_get_local_port(audio_stream_->session);
297
@@ -222,12 +228,15 @@
299
memcpy(buf, data, len);
301
+ if (port2 == PORT_UNUSED)
304
/* We may receive packets with payload type 13: comfort noise. Linphone can't
305
* handle them, so let's ignore those packets.
307
int payloadtype = buf[1] & 0x7f;
308
if (play_ && payloadtype != 13)
309
- socket_->SendTo(buf, len, talk_base::SocketAddress("localhost",2000));
310
+ socket_->SendTo(buf, len, talk_base::SocketAddress("localhost",port2));
313
void LinphoneVoiceChannel::StartRing(bool bIncomingCall)
317
len = s->Recv(buf, sizeof(buf));
318
- talk_base::Buffer packet(buf, len);
319
+ talk_base::Buffer packet(buf, len, sizeof(buf));
320
if (network_interface_ && !mute_)
321
network_interface_->SendPacket(&packet);
326
+#endif // HAVE_LINPHONE