- Use C++11 loops in WebRtcVoiceMediaEngine/Channel.

- Pull out part of WebRtcVoiceMediaChannel::SetRecvCodecs() into WebRtcVoiceMediaChannel::SetRecvCodecsInternal().

BUG=webrtc:4690
R=pbos@webrtc.org

Review URL: https://codereview.webrtc.org/1291343002 .

Cr-Commit-Position: refs/heads/master@{#9785}
This commit is contained in:
Fredrik Solenberg
2015-08-26 10:45:53 +02:00
parent c464f504dc
commit af9fb21886
2 changed files with 179 additions and 212 deletions

View File

@ -214,11 +214,10 @@ static bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
static bool FindCodec(const std::vector<AudioCodec>& codecs, static bool FindCodec(const std::vector<AudioCodec>& codecs,
const AudioCodec& codec, const AudioCodec& codec,
AudioCodec* found_codec) { AudioCodec* found_codec) {
for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); for (const AudioCodec& c : codecs) {
it != codecs.end(); ++it) { if (c.Matches(codec)) {
if (it->Matches(codec)) {
if (found_codec != NULL) { if (found_codec != NULL) {
*found_codec = *it; *found_codec = c;
} }
return true; return true;
} }
@ -556,9 +555,8 @@ bool WebRtcVoiceEngine::InitInternal() {
// Print our codec list again for the call diagnostic log // Print our codec list again for the call diagnostic log
LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
for (std::vector<AudioCodec>::const_iterator it = codecs_.begin(); for (const AudioCodec& codec : codecs_) {
it != codecs_.end(); ++it) { LOG(LS_INFO) << ToString(codec);
LOG(LS_INFO) << ToString(*it);
} }
// Disable the DTMF playout when a tone is sent. // Disable the DTMF playout when a tone is sent.
@ -948,9 +946,7 @@ bool WebRtcVoiceEngine::SetDevices(const Device* in_device,
} }
// Must also pause all audio playback and capture. // Must also pause all audio playback and capture.
for (ChannelList::const_iterator i = channels_.begin(); for (WebRtcVoiceMediaChannel* channel : channels_) {
i != channels_.end(); ++i) {
WebRtcVoiceMediaChannel *channel = *i;
if (!channel->PausePlayout()) { if (!channel->PausePlayout()) {
LOG(LS_WARNING) << "Failed to pause playout"; LOG(LS_WARNING) << "Failed to pause playout";
ret = false; ret = false;
@ -988,9 +984,7 @@ bool WebRtcVoiceEngine::SetDevices(const Device* in_device,
} }
// Resume all audio playback and capture. // Resume all audio playback and capture.
for (ChannelList::const_iterator i = channels_.begin(); for (WebRtcVoiceMediaChannel* channel : channels_) {
i != channels_.end(); ++i) {
WebRtcVoiceMediaChannel *channel = *i;
if (!channel->ResumePlayout()) { if (!channel->ResumePlayout()) {
LOG(LS_WARNING) << "Failed to resume playout"; LOG(LS_WARNING) << "Failed to resume playout";
ret = false; ret = false;
@ -1328,11 +1322,10 @@ bool WebRtcVoiceEngine::FindChannelAndSsrc(
*channel = NULL; *channel = NULL;
*ssrc = 0; *ssrc = 0;
// Find corresponding channel and ssrc // Find corresponding channel and ssrc
for (ChannelList::const_iterator it = channels_.begin(); for (WebRtcVoiceMediaChannel* ch : channels_) {
it != channels_.end(); ++it) { DCHECK(ch != NULL);
DCHECK(*it != NULL); if (ch->FindSsrc(channel_num, ssrc)) {
if ((*it)->FindSsrc(channel_num, ssrc)) { *channel = ch;
*channel = *it;
return true; return true;
} }
} }
@ -1349,14 +1342,13 @@ bool WebRtcVoiceEngine::FindChannelNumFromSsrc(
*channel_num = -1; *channel_num = -1;
// Find corresponding channel for ssrc. // Find corresponding channel for ssrc.
for (ChannelList::const_iterator it = channels_.begin(); for (const WebRtcVoiceMediaChannel* ch : channels_) {
it != channels_.end(); ++it) { DCHECK(ch != NULL);
DCHECK(*it != NULL);
if (direction & MPD_RX) { if (direction & MPD_RX) {
*channel_num = (*it)->GetReceiveChannelNum(ssrc); *channel_num = ch->GetReceiveChannelNum(ssrc);
} }
if (*channel_num == -1 && (direction & MPD_TX)) { if (*channel_num == -1 && (direction & MPD_TX)) {
*channel_num = (*it)->GetSendChannelNum(ssrc); *channel_num = ch->GetSendChannelNum(ssrc);
} }
if (*channel_num != -1) { if (*channel_num != -1) {
return true; return true;
@ -1860,16 +1852,15 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs(
// Find all new codecs. We allow adding new codecs but don't allow changing // Find all new codecs. We allow adding new codecs but don't allow changing
// the payload type of codecs that is already configured since we might // the payload type of codecs that is already configured since we might
// already be receiving packets with that payload type. // already be receiving packets with that payload type.
for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); for (const AudioCodec& codec : codecs) {
it != codecs.end(); ++it) {
AudioCodec old_codec; AudioCodec old_codec;
if (FindCodec(recv_codecs_, *it, &old_codec)) { if (FindCodec(recv_codecs_, codec, &old_codec)) {
if (old_codec.id != it->id) { if (old_codec.id != codec.id) {
LOG(LS_ERROR) << it->name << " payload type changed."; LOG(LS_ERROR) << codec.name << " payload type changed.";
return false; return false;
} }
} else { } else {
new_codecs.push_back(*it); new_codecs.push_back(codec);
} }
} }
if (new_codecs.empty()) { if (new_codecs.empty()) {
@ -1884,50 +1875,15 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs(
PausePlayout(); PausePlayout();
} }
bool ret = true; bool result = SetRecvCodecsInternal(new_codecs);
for (std::vector<AudioCodec>::const_iterator it = new_codecs.begin(); if (result) {
it != new_codecs.end() && ret; ++it) {
webrtc::CodecInst voe_codec;
if (engine()->FindWebRtcCodec(*it, &voe_codec)) {
LOG(LS_INFO) << ToString(*it);
voe_codec.pltype = it->id;
if (default_receive_ssrc_ == 0) {
// Set the receive codecs on the default channel explicitly if the
// default channel is not used by |receive_channels_|, this happens in
// conference mode or in non-conference mode when there is no playout
// channel.
// TODO(xians): Figure out how we use the default channel in conference
// mode.
if (engine()->voe()->codec()->SetRecPayloadType(
voe_channel(), voe_codec) == -1) {
LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec));
ret = false;
}
}
// Set the receive codecs on all receiving channels.
for (ChannelMap::iterator it = receive_channels_.begin();
it != receive_channels_.end() && ret; ++it) {
if (engine()->voe()->codec()->SetRecPayloadType(
it->second->channel(), voe_codec) == -1) {
LOG_RTCERR2(SetRecPayloadType, it->second->channel(),
ToString(voe_codec));
ret = false;
}
}
} else {
LOG(LS_WARNING) << "Unknown codec " << ToString(*it);
ret = false;
}
}
if (ret) {
recv_codecs_ = codecs; recv_codecs_ = codecs;
} }
if (desired_playout_ && !playout_) { if (desired_playout_ && !playout_) {
ResumePlayout(); ResumePlayout();
} }
return ret; return result;
} }
bool WebRtcVoiceMediaChannel::SetSendCodecs( bool WebRtcVoiceMediaChannel::SetSendCodecs(
@ -1950,17 +1906,16 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
int opus_max_playback_rate = 0; int opus_max_playback_rate = 0;
// Set send codec (the first non-telephone-event/CN codec) // Set send codec (the first non-telephone-event/CN codec)
for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); for (const AudioCodec& codec : codecs) {
it != codecs.end(); ++it) {
// Ignore codecs we don't know about. The negotiation step should prevent // Ignore codecs we don't know about. The negotiation step should prevent
// this, but double-check to be sure. // this, but double-check to be sure.
webrtc::CodecInst voe_codec; webrtc::CodecInst voe_codec;
if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { if (!engine()->FindWebRtcCodec(codec, &voe_codec)) {
LOG(LS_WARNING) << "Unknown codec " << ToString(*it); LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
continue; continue;
} }
if (IsCodec(*it, kDtmfCodecName) || IsCodec(*it, kCnCodecName)) { if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
// Skip telephone-event/CN codec, which will be handled later. // Skip telephone-event/CN codec, which will be handled later.
continue; continue;
} }
@ -1969,33 +1924,33 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
// Be sure to use the payload type requested by the remote side. // Be sure to use the payload type requested by the remote side.
// "red", for RED audio, is a special case where the actual codec to be // "red", for RED audio, is a special case where the actual codec to be
// used is specified in params. // used is specified in params.
if (IsCodec(*it, kRedCodecName)) { if (IsCodec(codec, kRedCodecName)) {
// Parse out the RED parameters. If we fail, just ignore RED; // Parse out the RED parameters. If we fail, just ignore RED;
// we don't support all possible params/usage scenarios. // we don't support all possible params/usage scenarios.
if (!GetRedSendCodec(*it, codecs, &send_codec)) { if (!GetRedSendCodec(codec, codecs, &send_codec)) {
continue; continue;
} }
// Enable redundant encoding of the specified codec. Treat any // Enable redundant encoding of the specified codec. Treat any
// failure as a fatal internal error. // failure as a fatal internal error.
LOG(LS_INFO) << "Enabling RED on channel " << channel; LOG(LS_INFO) << "Enabling RED on channel " << channel;
if (engine()->voe()->rtp()->SetREDStatus(channel, true, it->id) == -1) { if (engine()->voe()->rtp()->SetREDStatus(channel, true, codec.id) == -1) {
LOG_RTCERR3(SetREDStatus, channel, true, it->id); LOG_RTCERR3(SetREDStatus, channel, true, codec.id);
return false; return false;
} }
} else { } else {
send_codec = voe_codec; send_codec = voe_codec;
nack_enabled = IsNackEnabled(*it); nack_enabled = IsNackEnabled(codec);
// For Opus as the send codec, we are to determine inband FEC, maximum // For Opus as the send codec, we are to determine inband FEC, maximum
// playback rate, and opus internal dtx. // playback rate, and opus internal dtx.
if (IsCodec(*it, kOpusCodecName)) { if (IsCodec(codec, kOpusCodecName)) {
GetOpusConfig(*it, &send_codec, &enable_codec_fec, GetOpusConfig(codec, &send_codec, &enable_codec_fec,
&opus_max_playback_rate, &enable_opus_dtx); &opus_max_playback_rate, &enable_opus_dtx);
} }
// Set packet size if the AudioCodec param kCodecParamPTime is set. // Set packet size if the AudioCodec param kCodecParamPTime is set.
int ptime_ms = 0; int ptime_ms = 0;
if (it->GetParam(kCodecParamPTime, &ptime_ms)) { if (codec.GetParam(kCodecParamPTime, &ptime_ms)) {
if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) { if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) {
LOG(LS_WARNING) << "Failed to set packet size for codec " LOG(LS_WARNING) << "Failed to set packet size for codec "
<< send_codec.plname; << send_codec.plname;
@ -2070,30 +2025,29 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
} }
// Loop through the codecs list again to config the telephone-event/CN codec. // Loop through the codecs list again to config the telephone-event/CN codec.
for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); for (const AudioCodec& codec : codecs) {
it != codecs.end(); ++it) {
// Ignore codecs we don't know about. The negotiation step should prevent // Ignore codecs we don't know about. The negotiation step should prevent
// this, but double-check to be sure. // this, but double-check to be sure.
webrtc::CodecInst voe_codec; webrtc::CodecInst voe_codec;
if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { if (!engine()->FindWebRtcCodec(codec, &voe_codec)) {
LOG(LS_WARNING) << "Unknown codec " << ToString(*it); LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
continue; continue;
} }
// Find the DTMF telephone event "codec" and tell VoiceEngine channels // Find the DTMF telephone event "codec" and tell VoiceEngine channels
// about it. // about it.
if (IsCodec(*it, kDtmfCodecName)) { if (IsCodec(codec, kDtmfCodecName)) {
if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType( if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType(
channel, it->id) == -1) { channel, codec.id) == -1) {
LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, it->id); LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, codec.id);
return false; return false;
} }
} else if (IsCodec(*it, kCnCodecName)) { } else if (IsCodec(codec, kCnCodecName)) {
// Turn voice activity detection/comfort noise on if supported. // Turn voice activity detection/comfort noise on if supported.
// Set the wideband CN payload type appropriately. // Set the wideband CN payload type appropriately.
// (narrowband always uses the static payload type 13). // (narrowband always uses the static payload type 13).
webrtc::PayloadFrequencies cn_freq; webrtc::PayloadFrequencies cn_freq;
switch (it->clockrate) { switch (codec.clockrate) {
case 8000: case 8000:
cn_freq = webrtc::kFreq8000Hz; cn_freq = webrtc::kFreq8000Hz;
break; break;
@ -2104,7 +2058,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
cn_freq = webrtc::kFreq32000Hz; cn_freq = webrtc::kFreq32000Hz;
break; break;
default: default:
LOG(LS_WARNING) << "CN frequency " << it->clockrate LOG(LS_WARNING) << "CN frequency " << codec.clockrate
<< " not supported."; << " not supported.";
continue; continue;
} }
@ -2112,8 +2066,8 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
// The CN payload type for 8000 Hz clockrate is fixed at 13. // The CN payload type for 8000 Hz clockrate is fixed at 13.
if (cn_freq != webrtc::kFreq8000Hz) { if (cn_freq != webrtc::kFreq8000Hz) {
if (engine()->voe()->codec()->SetSendCNPayloadType( if (engine()->voe()->codec()->SetSendCNPayloadType(
channel, it->id, cn_freq) == -1) { channel, codec.id, cn_freq) == -1) {
LOG_RTCERR3(SetSendCNPayloadType, channel, it->id, cn_freq); LOG_RTCERR3(SetSendCNPayloadType, channel, codec.id, cn_freq);
// TODO(ajm): This failure condition will be removed from VoE. // TODO(ajm): This failure condition will be removed from VoE.
// Restore the return here when we update to a new enough webrtc. // Restore the return here when we update to a new enough webrtc.
// //
@ -2126,7 +2080,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
} }
// Only turn on VAD if we have a CN payload type that matches the // Only turn on VAD if we have a CN payload type that matches the
// clockrate for the codec we are going to use. // clockrate for the codec we are going to use.
if (it->clockrate == send_codec.plfreq && send_codec.channels != 2) { if (codec.clockrate == send_codec.plfreq && send_codec.channels != 2) {
// TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
// interaction between VAD and Opus FEC. // interaction between VAD and Opus FEC.
LOG(LS_INFO) << "Enabling VAD"; LOG(LS_INFO) << "Enabling VAD";
@ -2143,19 +2097,17 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
bool WebRtcVoiceMediaChannel::SetSendCodecs( bool WebRtcVoiceMediaChannel::SetSendCodecs(
const std::vector<AudioCodec>& codecs) { const std::vector<AudioCodec>& codecs) {
dtmf_allowed_ = false; dtmf_allowed_ = false;
for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); for (const AudioCodec& codec : codecs) {
it != codecs.end(); ++it) {
// Find the DTMF telephone event "codec". // Find the DTMF telephone event "codec".
if (IsCodec(*it, kDtmfCodecName)) { if (IsCodec(codec, kDtmfCodecName)) {
dtmf_allowed_ = true; dtmf_allowed_ = true;
} }
} }
// Cache the codecs in order to configure the channel created later. // Cache the codecs in order to configure the channel created later.
send_codecs_ = codecs; send_codecs_ = codecs;
for (ChannelMap::iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) { if (!SetSendCodecs(ch.second->channel(), codecs)) {
if (!SetSendCodecs(iter->second->channel(), codecs)) {
return false; return false;
} }
} }
@ -2167,9 +2119,8 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
void WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels, void WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels,
bool nack_enabled) { bool nack_enabled) {
for (ChannelMap::const_iterator it = channels.begin(); for (const auto& ch : channels) {
it != channels.end(); ++it) { SetNack(ch.second->channel(), nack_enabled);
SetNack(it->second->channel(), nack_enabled);
} }
} }
@ -2187,9 +2138,8 @@ bool WebRtcVoiceMediaChannel::SetSendCodec(
const webrtc::CodecInst& send_codec) { const webrtc::CodecInst& send_codec) {
LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec) LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec)
<< ", bitrate=" << send_codec.rate; << ", bitrate=" << send_codec.rate;
for (ChannelMap::iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) { if (!SetSendCodec(ch.second->channel(), send_codec))
if (!SetSendCodec(iter->second->channel(), send_codec))
return false; return false;
} }
@ -2228,10 +2178,8 @@ bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions(
} }
// Loop through all receive channels and enable/disable the extensions. // Loop through all receive channels and enable/disable the extensions.
for (ChannelMap::const_iterator channel_it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
channel_it != receive_channels_.end(); ++channel_it) { if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) {
if (!SetChannelRecvRtpHeaderExtensions(channel_it->second->channel(),
extensions)) {
return false; return false;
} }
} }
@ -2298,10 +2246,8 @@ bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions(
} }
// Loop through all send channels and enable/disable the extensions. // Loop through all send channels and enable/disable the extensions.
for (ChannelMap::const_iterator channel_it = send_channels_.begin(); for (const auto& ch : send_channels_) {
channel_it != send_channels_.end(); ++channel_it) { if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) {
if (!SetChannelSendRtpHeaderExtensions(channel_it->second->channel(),
extensions)) {
return false; return false;
} }
} }
@ -2356,12 +2302,12 @@ bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) {
// Only toggle the default channel if we don't have any other channels. // Only toggle the default channel if we don't have any other channels.
result = SetPlayout(voe_channel(), playout); result = SetPlayout(voe_channel(), playout);
} }
for (ChannelMap::iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end() && result; ++it) { if (!SetPlayout(ch.second->channel(), playout)) {
if (!SetPlayout(it->second->channel(), playout)) {
LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " LOG(LS_ERROR) << "SetPlayout " << playout << " on channel "
<< it->second->channel() << " failed"; << ch.second->channel() << " failed";
result = false; result = false;
break;
} }
} }
@ -2396,9 +2342,8 @@ bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) {
engine()->SetOptionOverrides(options_); engine()->SetOptionOverrides(options_);
// Change the settings on each send channel. // Change the settings on each send channel.
for (ChannelMap::iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) { if (!ChangeSend(ch.second->channel(), send))
if (!ChangeSend(iter->second->channel(), send))
return false; return false;
} }
@ -2472,9 +2417,8 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
} }
bool default_channel_is_available = true; bool default_channel_is_available = true;
for (ChannelMap::const_iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) { if (IsDefaultChannel(ch.second->channel())) {
if (IsDefaultChannel(iter->second->channel())) {
default_channel_is_available = false; default_channel_is_available = false;
break; break;
} }
@ -2514,13 +2458,12 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
// well. Receive channels have to have the same SSRC as the default channel in // well. Receive channels have to have the same SSRC as the default channel in
// order to send receiver reports with this SSRC. // order to send receiver reports with this SSRC.
if (IsDefaultChannel(channel)) { if (IsDefaultChannel(channel)) {
for (ChannelMap::const_iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) {
// Only update the SSRC for non-default channels. // Only update the SSRC for non-default channels.
if (!IsDefaultChannel(it->second->channel())) { if (!IsDefaultChannel(ch.second->channel())) {
if (engine()->voe()->rtp()->SetLocalSSRC(it->second->channel(), if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(),
sp.first_ssrc()) != 0) { sp.first_ssrc()) != 0) {
LOG_RTCERR2(SetLocalSSRC, it->second->channel(), sp.first_ssrc()); LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc());
return false; return false;
} }
} }
@ -2662,11 +2605,10 @@ bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) {
// Use the same recv payload types as our default channel. // Use the same recv payload types as our default channel.
ResetRecvCodecs(channel); ResetRecvCodecs(channel);
if (!recv_codecs_.empty()) { if (!recv_codecs_.empty()) {
for (std::vector<AudioCodec>::const_iterator it = recv_codecs_.begin(); for (const auto& codec : recv_codecs_) {
it != recv_codecs_.end(); ++it) {
webrtc::CodecInst voe_codec; webrtc::CodecInst voe_codec;
if (engine()->FindWebRtcCodec(*it, &voe_codec)) { if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
voe_codec.pltype = it->id; voe_codec.pltype = codec.id;
voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC
if (engine()->voe()->codec()->GetRecPayloadType( if (engine()->voe()->codec()->GetRecPayloadType(
voe_channel(), voe_codec) != -1) { voe_channel(), voe_codec) != -1) {
@ -2811,11 +2753,10 @@ bool WebRtcVoiceMediaChannel::GetActiveStreams(
// In conference mode, the default channel should not be in // In conference mode, the default channel should not be in
// |receive_channels_|. // |receive_channels_|.
actives->clear(); actives->clear();
for (ChannelMap::iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) { int level = GetOutputLevel(ch.second->channel());
int level = GetOutputLevel(it->second->channel());
if (level > 0) { if (level > 0) {
actives->push_back(std::make_pair(it->first, level)); actives->push_back(std::make_pair(ch.first, level));
} }
} }
return true; return true;
@ -2824,9 +2765,8 @@ bool WebRtcVoiceMediaChannel::GetActiveStreams(
int WebRtcVoiceMediaChannel::GetOutputLevel() { int WebRtcVoiceMediaChannel::GetOutputLevel() {
// return the highest output level of all streams // return the highest output level of all streams
int highest = GetOutputLevel(voe_channel()); int highest = GetOutputLevel(voe_channel());
for (ChannelMap::iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) { int level = GetOutputLevel(ch.second->channel());
int level = GetOutputLevel(it->second->channel());
highest = std::max(level, highest); highest = std::max(level, highest);
} }
return highest; return highest;
@ -2867,9 +2807,8 @@ bool WebRtcVoiceMediaChannel::SetOutputScaling(
// playout. // playout.
if (default_receive_ssrc_ == 0) if (default_receive_ssrc_ == 0)
channels.push_back(voe_channel()); channels.push_back(voe_channel());
for (ChannelMap::const_iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) { channels.push_back(ch.second->channel());
channels.push_back(it->second->channel());
} }
} else { // Collect only the channel of the specified ssrc. } else { // Collect only the channel of the specified ssrc.
int channel = GetReceiveChannelNum(ssrc); int channel = GetReceiveChannelNum(ssrc);
@ -2887,22 +2826,21 @@ bool WebRtcVoiceMediaChannel::SetOutputScaling(
left /= scale; left /= scale;
right /= scale; right /= scale;
} }
for (std::vector<int>::const_iterator it = channels.begin(); for (int ch_id : channels) {
it != channels.end(); ++it) {
if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling( if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling(
*it, scale)) { ch_id, scale)) {
LOG_RTCERR2(SetChannelOutputVolumeScaling, *it, scale); LOG_RTCERR2(SetChannelOutputVolumeScaling, ch_id, scale);
return false; return false;
} }
if (-1 == engine()->voe()->volume()->SetOutputVolumePan( if (-1 == engine()->voe()->volume()->SetOutputVolumePan(
*it, static_cast<float>(left), static_cast<float>(right))) { ch_id, static_cast<float>(left), static_cast<float>(right))) {
LOG_RTCERR3(SetOutputVolumePan, *it, left, right); LOG_RTCERR3(SetOutputVolumePan, ch_id, left, right);
// Do not return if fails. SetOutputVolumePan is not available for all // Do not return if fails. SetOutputVolumePan is not available for all
// pltforms. // pltforms.
} }
LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale
<< " right=" << right * scale << " right=" << right * scale
<< " for channel " << *it << " and ssrc " << ssrc; << " for channel " << ch_id << " and ssrc " << ssrc;
} }
return true; return true;
} }
@ -3003,9 +2941,8 @@ bool WebRtcVoiceMediaChannel::InsertDtmf(uint32 ssrc, int event,
int channel = -1; int channel = -1;
if (ssrc == 0) { if (ssrc == 0) {
bool default_channel_is_inuse = false; bool default_channel_is_inuse = false;
for (ChannelMap::const_iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) { if (IsDefaultChannel(ch.second->channel())) {
if (IsDefaultChannel(iter->second->channel())) {
default_channel_is_inuse = true; default_channel_is_inuse = true;
break; break;
} }
@ -3121,15 +3058,14 @@ void WebRtcVoiceMediaChannel::OnRtcpReceived(
// SR may continue RR and any RR entry may correspond to any one of the send // SR may continue RR and any RR entry may correspond to any one of the send
// channels. So all RTCP packets must be forwarded all send channels. VoE // channels. So all RTCP packets must be forwarded all send channels. VoE
// will filter out RR internally. // will filter out RR internally.
for (ChannelMap::iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end(); ++iter) {
// Make sure not sending the same packet to default channel more than once. // Make sure not sending the same packet to default channel more than once.
if (IsDefaultChannel(iter->second->channel()) && if (IsDefaultChannel(ch.second->channel()) &&
has_sent_to_default_channel) has_sent_to_default_channel)
continue; continue;
engine()->voe()->network()->ReceivedRTCPPacket( engine()->voe()->network()->ReceivedRTCPPacket(
iter->second->channel(), packet->data(), packet->size()); ch.second->channel(), packet->data(), packet->size());
} }
} }
@ -3148,11 +3084,13 @@ bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) {
// the mic channel is muted/unmuted. We can't do it today because there // the mic channel is muted/unmuted. We can't do it today because there
// is no good way to know which stream is mapping to the mic channel. // is no good way to know which stream is mapping to the mic channel.
bool all_muted = muted; bool all_muted = muted;
for (ChannelMap::const_iterator iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
iter != send_channels_.end() && all_muted; ++iter) { if (!all_muted) {
if (engine()->voe()->volume()->GetInputMute(iter->second->channel(), break;
}
if (engine()->voe()->volume()->GetInputMute(ch.second->channel(),
all_muted)) { all_muted)) {
LOG_RTCERR1(GetInputMute, iter->second->channel()); LOG_RTCERR1(GetInputMute, ch.second->channel());
return false; return false;
} }
} }
@ -3251,9 +3189,8 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
webrtc::CodecInst codec; webrtc::CodecInst codec;
unsigned int level; unsigned int level;
for (ChannelMap::const_iterator channel_iter = send_channels_.begin(); for (const auto& ch : send_channels_) {
channel_iter != send_channels_.end(); ++channel_iter) { const int channel = ch.second->channel();
const int channel = channel_iter->second->channel();
// Fill in the sender info, based on what we know, and what the // Fill in the sender info, based on what we know, and what the
// remote side told us it got from its RTCP report. // remote side told us it got from its RTCP report.
@ -3282,19 +3219,17 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks(
channel, &receive_blocks) != -1 && channel, &receive_blocks) != -1 &&
engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) {
std::vector<webrtc::ReportBlock>::iterator iter; for (const webrtc::ReportBlock& block : receive_blocks) {
for (iter = receive_blocks.begin(); iter != receive_blocks.end();
++iter) {
// Lookup report for send ssrc only. // Lookup report for send ssrc only.
if (iter->source_SSRC == sinfo.ssrc()) { if (block.source_SSRC == sinfo.ssrc()) {
// Convert Q8 to floating point. // Convert Q8 to floating point.
sinfo.fraction_lost = static_cast<float>(iter->fraction_lost) / 256; sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256;
// Convert samples to milliseconds. // Convert samples to milliseconds.
if (codec.plfreq / 1000 > 0) { if (codec.plfreq / 1000 > 0) {
sinfo.jitter_ms = iter->interarrival_jitter / (codec.plfreq / 1000); sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000);
} }
sinfo.packets_lost = iter->cumulative_num_packets_lost; sinfo.packets_lost = block.cumulative_num_packets_lost;
sinfo.ext_seqnum = iter->extended_highest_sequence_number; sinfo.ext_seqnum = block.extended_highest_sequence_number;
break; break;
} }
} }
@ -3323,21 +3258,19 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
// Build the list of receivers, one for each receiving channel, or 1 in // Build the list of receivers, one for each receiving channel, or 1 in
// a 1:1 call. // a 1:1 call.
std::vector<int> channels; std::vector<int> channels;
for (ChannelMap::const_iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) { channels.push_back(ch.second->channel());
channels.push_back(it->second->channel());
} }
if (channels.empty()) { if (channels.empty()) {
channels.push_back(voe_channel()); channels.push_back(voe_channel());
} }
// Get the SSRC and stats for each receiver, based on our own calculations. // Get the SSRC and stats for each receiver, based on our own calculations.
for (std::vector<int>::const_iterator it = channels.begin(); for (int ch_id : channels) {
it != channels.end(); ++it) {
memset(&cs, 0, sizeof(cs)); memset(&cs, 0, sizeof(cs));
if (engine()->voe()->rtp()->GetRemoteSSRC(*it, ssrc) != -1 && if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 &&
engine()->voe()->rtp()->GetRTCPStatistics(*it, cs) != -1 && engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 &&
engine()->voe()->codec()->GetRecCodec(*it, codec) != -1) { engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) {
VoiceReceiverInfo rinfo; VoiceReceiverInfo rinfo;
rinfo.add_ssrc(ssrc); rinfo.add_ssrc(ssrc);
rinfo.bytes_rcvd = cs.bytesReceived; rinfo.bytes_rcvd = cs.bytesReceived;
@ -3360,7 +3293,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
webrtc::NetworkStatistics ns; webrtc::NetworkStatistics ns;
if (engine()->voe()->neteq() && if (engine()->voe()->neteq() &&
engine()->voe()->neteq()->GetNetworkStatistics( engine()->voe()->neteq()->GetNetworkStatistics(
*it, ns) != -1) { ch_id, ns) != -1) {
rinfo.jitter_buffer_ms = ns.currentBufferSize; rinfo.jitter_buffer_ms = ns.currentBufferSize;
rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
rinfo.expand_rate = rinfo.expand_rate =
@ -3378,7 +3311,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
webrtc::AudioDecodingCallStats ds; webrtc::AudioDecodingCallStats ds;
if (engine()->voe()->neteq() && if (engine()->voe()->neteq() &&
engine()->voe()->neteq()->GetDecodingCallStatistics( engine()->voe()->neteq()->GetDecodingCallStatistics(
*it, &ds) != -1) { ch_id, &ds) != -1) {
rinfo.decoding_calls_to_silence_generator = rinfo.decoding_calls_to_silence_generator =
ds.calls_to_silence_generator; ds.calls_to_silence_generator;
rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; rinfo.decoding_calls_to_neteq = ds.calls_to_neteq;
@ -3392,14 +3325,14 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
int jitter_buffer_delay_ms = 0; int jitter_buffer_delay_ms = 0;
int playout_buffer_delay_ms = 0; int playout_buffer_delay_ms = 0;
engine()->voe()->sync()->GetDelayEstimate( engine()->voe()->sync()->GetDelayEstimate(
*it, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); ch_id, &jitter_buffer_delay_ms, &playout_buffer_delay_ms);
rinfo.delay_estimate_ms = jitter_buffer_delay_ms + rinfo.delay_estimate_ms = jitter_buffer_delay_ms +
playout_buffer_delay_ms; playout_buffer_delay_ms;
} }
// Get speech level. // Get speech level.
rinfo.audio_level = (engine()->voe()->volume()-> rinfo.audio_level = (engine()->voe()->volume()->
GetSpeechOutputLevelFullRange(*it, level) != -1) ? level : -1; GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1;
info->receivers.push_back(rinfo); info->receivers.push_back(rinfo);
} }
} }
@ -3427,9 +3360,8 @@ bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
return true; return true;
} else { } else {
// Check whether this is a sending channel. // Check whether this is a sending channel.
for (ChannelMap::const_iterator it = send_channels_.begin(); for (const auto& ch : send_channels_) {
it != send_channels_.end(); ++it) { if (ch.second->channel() == channel_num) {
if (it->second->channel() == channel_num) {
// This is a sending channel. // This is a sending channel.
uint32 local_ssrc = 0; uint32 local_ssrc = 0;
if (engine()->voe()->rtp()->GetLocalSSRC( if (engine()->voe()->rtp()->GetLocalSSRC(
@ -3441,10 +3373,9 @@ bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
} }
// Check whether this is a receiving channel. // Check whether this is a receiving channel.
for (ChannelMap::const_iterator it = receive_channels_.begin(); for (const auto& ch : receive_channels_) {
it != receive_channels_.end(); ++it) { if (ch.second->channel() == channel_num) {
if (it->second->channel() == channel_num) { *ssrc = ch.first;
*ssrc = it->first;
return true; return true;
} }
} }
@ -3468,15 +3399,15 @@ int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) {
return (ret == 0) ? static_cast<int>(ulevel) : -1; return (ret == 0) ? static_cast<int>(ulevel) : -1;
} }
int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) { int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const {
ChannelMap::iterator it = receive_channels_.find(ssrc); ChannelMap::const_iterator it = receive_channels_.find(ssrc);
if (it != receive_channels_.end()) if (it != receive_channels_.end())
return it->second->channel(); return it->second->channel();
return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; return (ssrc == default_receive_ssrc_) ? voe_channel() : -1;
} }
int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) { int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const {
ChannelMap::iterator it = send_channels_.find(ssrc); ChannelMap::const_iterator it = send_channels_.find(ssrc);
if (it != send_channels_.end()) if (it != send_channels_.end())
return it->second->channel(); return it->second->channel();
@ -3523,24 +3454,21 @@ bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
} }
// Try to find red_pt in |codecs|. // Try to find red_pt in |codecs|.
std::vector<AudioCodec>::const_iterator codec; for (const AudioCodec& codec : all_codecs) {
for (codec = all_codecs.begin(); codec != all_codecs.end(); ++codec) { if (codec.id == red_pt) {
if (codec->id == red_pt)
break;
}
// If we find the right codec, that will be the codec we pass to // If we find the right codec, that will be the codec we pass to
// SetSendCodec, with the desired payload type. // SetSendCodec, with the desired payload type.
if (codec != all_codecs.end() && if (engine()->FindWebRtcCodec(codec, send_codec)) {
engine()->FindWebRtcCodec(*codec, send_codec)) { return true;
} else { } else {
break;
}
}
}
LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
return false; return false;
} }
return true;
}
bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) {
if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) {
LOG_RTCERR2(SetRTCPStatus, channel, 1); LOG_RTCERR2(SetRTCPStatus, channel, 1);
@ -3677,6 +3605,44 @@ void WebRtcVoiceMediaChannel::TryRemoveAudioRecvStream(uint32 ssrc) {
} }
} }
bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal(
const std::vector<AudioCodec>& new_codecs) {
for (const AudioCodec& codec : new_codecs) {
webrtc::CodecInst voe_codec;
if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
LOG(LS_INFO) << ToString(codec);
voe_codec.pltype = codec.id;
if (default_receive_ssrc_ == 0) {
// Set the receive codecs on the default channel explicitly if the
// default channel is not used by |receive_channels_|, this happens in
// conference mode or in non-conference mode when there is no playout
// channel.
// TODO(xians): Figure out how we use the default channel in conference
// mode.
if (engine()->voe()->codec()->SetRecPayloadType(
voe_channel(), voe_codec) == -1) {
LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec));
return false;
}
}
// Set the receive codecs on all receiving channels.
for (const auto& ch : receive_channels_) {
if (engine()->voe()->codec()->SetRecPayloadType(
ch.second->channel(), voe_codec) == -1) {
LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
ToString(voe_codec));
return false;
}
}
} else {
LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
return false;
}
}
return true;
}
int WebRtcSoundclipStream::Read(void *buf, size_t len) { int WebRtcSoundclipStream::Read(void *buf, size_t len) {
size_t res = 0; size_t res = 0;
mem_.Read(buf, len, &res, NULL); mem_.Read(buf, len, &res, NULL);

View File

@ -357,8 +357,8 @@ class WebRtcVoiceMediaChannel : public VoiceMediaChannel,
void OnError(uint32 ssrc, int error); void OnError(uint32 ssrc, int error);
bool sending() const { return send_ != SEND_NOTHING; } bool sending() const { return send_ != SEND_NOTHING; }
int GetReceiveChannelNum(uint32 ssrc); int GetReceiveChannelNum(uint32 ssrc) const;
int GetSendChannelNum(uint32 ssrc); int GetSendChannelNum(uint32 ssrc) const;
void SetCall(webrtc::Call* call); void SetCall(webrtc::Call* call);
@ -406,6 +406,7 @@ class WebRtcVoiceMediaChannel : public VoiceMediaChannel,
const RtpHeaderExtension* extension); const RtpHeaderExtension* extension);
void TryAddAudioRecvStream(uint32 ssrc); void TryAddAudioRecvStream(uint32 ssrc);
void TryRemoveAudioRecvStream(uint32 ssrc); void TryRemoveAudioRecvStream(uint32 ssrc);
bool SetRecvCodecsInternal(const std::vector<AudioCodec>& new_codecs);
bool SetChannelRecvRtpHeaderExtensions( bool SetChannelRecvRtpHeaderExtensions(
int channel_id, int channel_id,