Update to libjingle 0.5.8.
git-svn-id: http://libjingle.googlecode.com/svn/trunk@72 dd674b97-3498-5ee5-1854-bdd07cd0ff33
diff --git a/CHANGELOG b/CHANGELOG
index 427a699..8ab3d49 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
Libjingle
+0.5.8 - July 1, 2011
+ - Support for loudest speaker detection
+
0.5.7 - Jun 23, 2011
- Support for setting MUC display name
- Update STUN support to RFC5389
diff --git a/talk/examples/call/callclient.cc b/talk/examples/call/callclient.cc
index da2716f..3fbd579 100644
--- a/talk/examples/call/callclient.cc
+++ b/talk/examples/call/callclient.cc
@@ -49,6 +49,7 @@
#include "talk/p2p/client/sessionmanagertask.h"
#include "talk/session/phone/devicemanager.h"
#include "talk/session/phone/mediaengine.h"
+#include "talk/session/phone/mediamessages.h"
#include "talk/session/phone/mediasessionclient.h"
#include "talk/session/phone/videorendererfactory.h"
#include "talk/xmpp/constants.h"
@@ -416,11 +417,29 @@
console_->PrintLine("call not answered");
} else if (state == cricket::Session::STATE_INPROGRESS) {
console_->PrintLine("call in progress");
+ call->SignalSpeakerMonitor.connect(this, &CallClient::OnSpeakerChanged);
+ call->StartSpeakerMonitor(session);
} else if (state == cricket::Session::STATE_RECEIVEDTERMINATE) {
console_->PrintLine("other side hung up");
}
}
+void CallClient::OnSpeakerChanged(cricket::Call* call,
+ cricket::BaseSession* session,
+ const cricket::NamedSource& speaker) {
+ if (speaker.ssrc == 0) {
+ console_->PrintLine("Session %s has no current speaker.",
+ session->id().c_str());
+ } else if (speaker.nick.empty()) {
+ console_->PrintLine("Session %s speaker change to unknown (%u).",
+ session->id().c_str(), speaker.ssrc);
+ } else {
+ console_->PrintLine("Session %s speaker changed to %s (%u).",
+ session->id().c_str(), speaker.nick.c_str(),
+ speaker.ssrc);
+ }
+}
+
void CallClient::InitPresence() {
presence_push_ = new buzz::PresencePushTask(xmpp_client_, this);
presence_push_->SignalStatusUpdate.connect(
@@ -477,6 +496,7 @@
if (status.available() && status.voice_capability()) {
console_->PrintLine("Adding to roster: %s", key.c_str());
(*roster_)[key] = item;
+ // TODO: Make some of these constants.
} else {
console_->PrintLine("Removing from roster: %s", key.c_str());
RosterMap::iterator iter = roster_->find(key);
diff --git a/talk/examples/call/callclient.h b/talk/examples/call/callclient.h
index e39c9d4..5bfeb87 100644
--- a/talk/examples/call/callclient.h
+++ b/talk/examples/call/callclient.h
@@ -34,6 +34,7 @@
#include "talk/p2p/base/session.h"
#include "talk/session/phone/mediachannel.h"
+#include "talk/session/phone/mediamessages.h"
#include "talk/session/phone/mediasessionclient.h"
#include "talk/xmpp/xmppclient.h"
#include "talk/examples/call/status.h"
@@ -65,6 +66,7 @@
class PortAllocator;
class MediaEngine;
class MediaSessionClient;
+class NamedSource;
class Receiver;
class Call;
struct CallOptions;
@@ -166,6 +168,9 @@
void OnMediaSourcesUpdate(cricket::Call* call,
cricket::Session* session,
const cricket::MediaSources& sources);
+ void OnSpeakerChanged(cricket::Call* call,
+ cricket::BaseSession* session,
+ const cricket::NamedSource& speaker_source);
void OnRoomLookupResponse(const buzz::MucRoomInfo& room_info);
void OnRoomLookupError(const buzz::XmlElement* stanza);
buzz::Jid GenerateRandomMucJid();
diff --git a/talk/session/phone/call.cc b/talk/session/phone/call.cc
index 27ea76f..5925e30 100644
--- a/talk/session/phone/call.cc
+++ b/talk/session/phone/call.cc
@@ -44,6 +44,8 @@
const int kSendToVoicemailTimeout = 1000*20;
const int kNoVoicemailTimeout = 1000*180;
const int kMediaMonitorInterval = 1000*15;
+// In order to be the same as the server-side switching, this must be 100.
+const int kAudioMonitorPollPeriodMillis = 100;
}
Call::Call(MediaSessionClient* session_client)
@@ -319,6 +321,9 @@
session_client_->channel_manager()->DestroyVoiceChannel(voice_channel);
}
+ // Destroy speaker monitor
+ StopSpeakerMonitor(session);
+
// Signal client
SignalRemoveSession(this, session);
@@ -479,6 +484,43 @@
}
}
+bool Call::IsAudioMonitorRunning(BaseSession *session) {
+ VoiceChannel *voice_channel = GetVoiceChannel(session);
+ if (voice_channel) {
+ return voice_channel->IsAudioMonitorRunning();
+ } else {
+ return false;
+ }
+}
+
+void Call::StartSpeakerMonitor(BaseSession *session) {
+ if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
+ if (!IsAudioMonitorRunning(session)) {
+ StartAudioMonitor(session, kAudioMonitorPollPeriodMillis);
+ }
+ CurrentSpeakerMonitor* speaker_monitor =
+ new cricket::CurrentSpeakerMonitor(this, session);
+ speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor);
+ speaker_monitor->Start();
+ speaker_monitor_map_[session->id()] = speaker_monitor;
+ } else {
+ LOG(LS_WARNING) << "Already started speaker monitor for session "
+ << session->id() << ".";
+ }
+}
+
+void Call::StopSpeakerMonitor(BaseSession *session) {
+ if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
+ LOG(LS_WARNING) << "Speaker monitor for session "
+ << session->id() << " already stopped.";
+ } else {
+ CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()];
+ monitor->Stop();
+ speaker_monitor_map_.erase(session->id());
+ delete monitor;
+ }
+}
+
void Call::OnConnectionMonitor(VoiceChannel *channel,
const std::vector<ConnectionInfo> &infos) {
SignalConnectionMonitor(this, infos);
@@ -492,6 +534,13 @@
SignalAudioMonitor(this, info);
}
+void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) {
+ NamedSource source;
+ source.ssrc = ssrc;
+ media_sources_.GetAudioSourceBySsrc(ssrc, &source);
+ SignalSpeakerMonitor(this, monitor->session(), source);
+}
+
void Call::OnConnectionMonitor(VideoChannel *channel,
const std::vector<ConnectionInfo> &infos) {
SignalVideoConnectionMonitor(this, infos);
diff --git a/talk/session/phone/call.h b/talk/session/phone/call.h
index 38e0684..19dc59a 100644
--- a/talk/session/phone/call.h
+++ b/talk/session/phone/call.h
@@ -37,6 +37,7 @@
#include "talk/p2p/client/socketmonitor.h"
#include "talk/xmpp/jid.h"
#include "talk/session/phone/audiomonitor.h"
+#include "talk/session/phone/currentspeakermonitor.h"
#include "talk/session/phone/mediamessages.h"
#include "talk/session/phone/voicechannel.h"
@@ -64,6 +65,9 @@
void StopConnectionMonitor(BaseSession *session);
void StartAudioMonitor(BaseSession *session, int cms);
void StopAudioMonitor(BaseSession *session);
+ bool IsAudioMonitorRunning(BaseSession *session);
+ void StartSpeakerMonitor(BaseSession *session);
+ void StopSpeakerMonitor(BaseSession *session);
void Mute(bool mute);
void PressDTMF(int event);
@@ -94,6 +98,11 @@
SignalConnectionMonitor;
sigslot::signal2<Call *, const VoiceMediaInfo&> SignalMediaMonitor;
sigslot::signal2<Call *, const AudioInfo&> SignalAudioMonitor;
+ // Empty nick on NamedSource means "unknown".
+ // Ssrc of 0 on NamedSource means "no current speaker".
+ sigslot::signal3<Call *,
+ BaseSession *,
+ const NamedSource&> SignalSpeakerMonitor;
sigslot::signal2<Call *, const std::vector<ConnectionInfo> &>
SignalVideoConnectionMonitor;
sigslot::signal2<Call *, const VideoMediaInfo&> SignalVideoMediaMonitor;
@@ -117,6 +126,7 @@
const std::vector<ConnectionInfo> &infos);
void OnMediaMonitor(VoiceChannel *channel, const VoiceMediaInfo& info);
void OnAudioMonitor(VoiceChannel *channel, const AudioInfo& info);
+ void OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc);
void OnConnectionMonitor(VideoChannel *channel,
const std::vector<ConnectionInfo> &infos);
void OnMediaMonitor(VideoChannel *channel, const VideoMediaInfo& info);
@@ -134,6 +144,7 @@
MediaSources media_sources_;
std::map<std::string, VoiceChannel *> voice_channel_map_;
std::map<std::string, VideoChannel *> video_channel_map_;
+ std::map<std::string, CurrentSpeakerMonitor *> speaker_monitor_map_;
VideoRenderer* local_renderer_;
bool video_;
bool muted_;
diff --git a/talk/session/phone/channel.cc b/talk/session/phone/channel.cc
index b23d877..05366a5 100644
--- a/talk/session/phone/channel.cc
+++ b/talk/session/phone/channel.cc
@@ -729,6 +729,10 @@
}
}
+bool VoiceChannel::IsAudioMonitorRunning() const {
+ return (audio_monitor_.get() != NULL);
+}
+
int VoiceChannel::GetInputLevel_w() {
return media_engine()->GetInputLevel();
}
diff --git a/talk/session/phone/channel.h b/talk/session/phone/channel.h
index 7d6577a..241ca79 100644
--- a/talk/session/phone/channel.h
+++ b/talk/session/phone/channel.h
@@ -298,6 +298,7 @@
void StartAudioMonitor(int cms);
void StopAudioMonitor();
+ bool IsAudioMonitorRunning() const;
sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
int GetInputLevel_w();
diff --git a/talk/session/phone/currentspeakermonitor.cc b/talk/session/phone/currentspeakermonitor.cc
index d2d4d9a..bfc20a2 100644
--- a/talk/session/phone/currentspeakermonitor.cc
+++ b/talk/session/phone/currentspeakermonitor.cc
@@ -26,7 +26,9 @@
*/
#include "talk/session/phone/currentspeakermonitor.h"
+
#include "talk/base/logging.h"
+#include "talk/session/phone/call.h"
namespace cricket {
@@ -37,7 +39,7 @@
const int kDefaultMinTimeBetweenSwitches = 1000;
}
-CurrentSpeakerMonitor::CurrentSpeakerMonitor(Call* call, Session* session)
+CurrentSpeakerMonitor::CurrentSpeakerMonitor(Call* call, BaseSession* session)
: started_(false),
call_(call),
session_(session),
@@ -184,7 +186,8 @@
}
}
-void CurrentSpeakerMonitor::OnMediaSourcesUpdate(Call* call, Session* session,
+void CurrentSpeakerMonitor::OnMediaSourcesUpdate(Call* call,
+ Session* session,
const MediaSources& sources) {
if (call == call_ && session == session_) {
// Update the speaking state map based on new or removed sources.
diff --git a/talk/session/phone/currentspeakermonitor.h b/talk/session/phone/currentspeakermonitor.h
index 36e23d9..adf6b48 100644
--- a/talk/session/phone/currentspeakermonitor.h
+++ b/talk/session/phone/currentspeakermonitor.h
@@ -33,18 +33,26 @@
#include <map>
-#include "talk/session/phone/call.h"
+#include "talk/base/basictypes.h"
#include "talk/base/sigslot.h"
namespace cricket {
+class AudioInfo;
+class BaseSession;
+class Call;
+class MediaSources;
+class Session;
+
// Note that the call's audio monitor must be started before this is started.
// It's recommended that the audio monitor be started with a 100 ms period.
class CurrentSpeakerMonitor : public sigslot::has_slots<> {
public:
- CurrentSpeakerMonitor(Call* call, Session* session);
+ CurrentSpeakerMonitor(Call* call, BaseSession* session);
~CurrentSpeakerMonitor();
+ BaseSession* session() const { return session_; }
+
void Start();
void Stop();
@@ -77,7 +85,7 @@
bool started_;
Call* call_;
- Session* session_;
+ BaseSession* session_;
std::map<uint32, SpeakingState> ssrc_to_speaking_state_map_;
uint32 current_speaker_ssrc_;
// To prevent overswitching, switching is disabled for some time after a