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

View File

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