OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 audio_source_context_->SignalMediaStreamsUpdate.disconnect(this); | 73 audio_source_context_->SignalMediaStreamsUpdate.disconnect(this); |
74 | 74 |
75 started_ = false; | 75 started_ = false; |
76 ssrc_to_speaking_state_map_.clear(); | 76 ssrc_to_speaking_state_map_.clear(); |
77 current_speaker_ssrc_ = 0; | 77 current_speaker_ssrc_ = 0; |
78 earliest_permitted_switch_time_ = 0; | 78 earliest_permitted_switch_time_ = 0; |
79 } | 79 } |
80 } | 80 } |
81 | 81 |
82 void CurrentSpeakerMonitor::set_min_time_between_switches( | 82 void CurrentSpeakerMonitor::set_min_time_between_switches( |
83 uint32 min_time_between_switches) { | 83 uint32_t min_time_between_switches) { |
84 min_time_between_switches_ = min_time_between_switches; | 84 min_time_between_switches_ = min_time_between_switches; |
85 } | 85 } |
86 | 86 |
87 void CurrentSpeakerMonitor::OnAudioMonitor( | 87 void CurrentSpeakerMonitor::OnAudioMonitor( |
88 AudioSourceContext* audio_source_context, const AudioInfo& info) { | 88 AudioSourceContext* audio_source_context, const AudioInfo& info) { |
89 std::map<uint32, int> active_ssrc_to_level_map; | 89 std::map<uint32_t, int> active_ssrc_to_level_map; |
90 cricket::AudioInfo::StreamList::const_iterator stream_list_it; | 90 cricket::AudioInfo::StreamList::const_iterator stream_list_it; |
91 for (stream_list_it = info.active_streams.begin(); | 91 for (stream_list_it = info.active_streams.begin(); |
92 stream_list_it != info.active_streams.end(); ++stream_list_it) { | 92 stream_list_it != info.active_streams.end(); ++stream_list_it) { |
93 uint32 ssrc = stream_list_it->first; | 93 uint32_t ssrc = stream_list_it->first; |
94 active_ssrc_to_level_map[ssrc] = stream_list_it->second; | 94 active_ssrc_to_level_map[ssrc] = stream_list_it->second; |
95 | 95 |
96 // It's possible we haven't yet added this source to our map. If so, | 96 // It's possible we haven't yet added this source to our map. If so, |
97 // add it now with a "not speaking" state. | 97 // add it now with a "not speaking" state. |
98 if (ssrc_to_speaking_state_map_.find(ssrc) == | 98 if (ssrc_to_speaking_state_map_.find(ssrc) == |
99 ssrc_to_speaking_state_map_.end()) { | 99 ssrc_to_speaking_state_map_.end()) { |
100 ssrc_to_speaking_state_map_[ssrc] = SS_NOT_SPEAKING; | 100 ssrc_to_speaking_state_map_[ssrc] = SS_NOT_SPEAKING; |
101 } | 101 } |
102 } | 102 } |
103 | 103 |
104 int max_level = 0; | 104 int max_level = 0; |
105 uint32 loudest_speaker_ssrc = 0; | 105 uint32_t loudest_speaker_ssrc = 0; |
106 | 106 |
107 // Update the speaking states of all participants based on the new audio | 107 // Update the speaking states of all participants based on the new audio |
108 // level information. Also retain loudest speaker. | 108 // level information. Also retain loudest speaker. |
109 std::map<uint32, SpeakingState>::iterator state_it; | 109 std::map<uint32_t, SpeakingState>::iterator state_it; |
110 for (state_it = ssrc_to_speaking_state_map_.begin(); | 110 for (state_it = ssrc_to_speaking_state_map_.begin(); |
111 state_it != ssrc_to_speaking_state_map_.end(); ++state_it) { | 111 state_it != ssrc_to_speaking_state_map_.end(); ++state_it) { |
112 bool is_previous_speaker = current_speaker_ssrc_ == state_it->first; | 112 bool is_previous_speaker = current_speaker_ssrc_ == state_it->first; |
113 | 113 |
114 // This uses a state machine in order to gradually identify | 114 // This uses a state machine in order to gradually identify |
115 // members as having started or stopped speaking. Matches the | 115 // members as having started or stopped speaking. Matches the |
116 // algorithm used by the hangouts js code. | 116 // algorithm used by the hangouts js code. |
117 | 117 |
118 std::map<uint32, int>::const_iterator level_it = | 118 std::map<uint32_t, int>::const_iterator level_it = |
119 active_ssrc_to_level_map.find(state_it->first); | 119 active_ssrc_to_level_map.find(state_it->first); |
120 // Note that the stream map only contains streams with non-zero audio | 120 // Note that the stream map only contains streams with non-zero audio |
121 // levels. | 121 // levels. |
122 int level = (level_it != active_ssrc_to_level_map.end()) ? | 122 int level = (level_it != active_ssrc_to_level_map.end()) ? |
123 level_it->second : 0; | 123 level_it->second : 0; |
124 switch (state_it->second) { | 124 switch (state_it->second) { |
125 case SS_NOT_SPEAKING: | 125 case SS_NOT_SPEAKING: |
126 if (level > 0) { | 126 if (level > 0) { |
127 // Reset level because we don't think they're really speaking. | 127 // Reset level because we don't think they're really speaking. |
128 level = 0; | 128 level = 0; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 loudest_speaker_ssrc = state_it->first; | 175 loudest_speaker_ssrc = state_it->first; |
176 max_level = level; | 176 max_level = level; |
177 } else if (level > 0 && level == max_level && is_previous_speaker) { | 177 } else if (level > 0 && level == max_level && is_previous_speaker) { |
178 // Favor continuity of loudest speakers if audio levels are equal. | 178 // Favor continuity of loudest speakers if audio levels are equal. |
179 loudest_speaker_ssrc = state_it->first; | 179 loudest_speaker_ssrc = state_it->first; |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 // We avoid over-switching by disabling switching for a period of time after | 183 // We avoid over-switching by disabling switching for a period of time after |
184 // a switch is done. | 184 // a switch is done. |
185 uint32 now = rtc::Time(); | 185 uint32_t now = rtc::Time(); |
186 if (earliest_permitted_switch_time_ <= now && | 186 if (earliest_permitted_switch_time_ <= now && |
187 current_speaker_ssrc_ != loudest_speaker_ssrc) { | 187 current_speaker_ssrc_ != loudest_speaker_ssrc) { |
188 current_speaker_ssrc_ = loudest_speaker_ssrc; | 188 current_speaker_ssrc_ = loudest_speaker_ssrc; |
189 LOG(LS_INFO) << "Current speaker changed to " << current_speaker_ssrc_; | 189 LOG(LS_INFO) << "Current speaker changed to " << current_speaker_ssrc_; |
190 earliest_permitted_switch_time_ = now + min_time_between_switches_; | 190 earliest_permitted_switch_time_ = now + min_time_between_switches_; |
191 SignalUpdate(this, current_speaker_ssrc_); | 191 SignalUpdate(this, current_speaker_ssrc_); |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 void CurrentSpeakerMonitor::OnMediaStreamsUpdate( | 195 void CurrentSpeakerMonitor::OnMediaStreamsUpdate( |
(...skipping 15 matching lines...) Expand all Loading... |
211 } | 211 } |
212 | 212 |
213 void CurrentSpeakerMonitor::OnMediaStreamsReset( | 213 void CurrentSpeakerMonitor::OnMediaStreamsReset( |
214 AudioSourceContext* audio_source_context, BaseSession* session) { | 214 AudioSourceContext* audio_source_context, BaseSession* session) { |
215 if (audio_source_context == audio_source_context_ && session == session_) { | 215 if (audio_source_context == audio_source_context_ && session == session_) { |
216 ssrc_to_speaking_state_map_.clear(); | 216 ssrc_to_speaking_state_map_.clear(); |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 } // namespace cricket | 220 } // namespace cricket |
OLD | NEW |