| 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 |