OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 kCodecPrefs[i].clockrate == codec.plfreq) { | 207 kCodecPrefs[i].clockrate == codec.plfreq) { |
208 return kCodecPrefs[i].is_multi_rate; | 208 return kCodecPrefs[i].is_multi_rate; |
209 } | 209 } |
210 } | 210 } |
211 return false; | 211 return false; |
212 } | 212 } |
213 | 213 |
214 static bool FindCodec(const std::vector<AudioCodec>& codecs, | 214 static bool FindCodec(const std::vector<AudioCodec>& codecs, |
215 const AudioCodec& codec, | 215 const AudioCodec& codec, |
216 AudioCodec* found_codec) { | 216 AudioCodec* found_codec) { |
217 for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); | 217 for (const AudioCodec& c : codecs) { |
218 it != codecs.end(); ++it) { | 218 if (c.Matches(codec)) { |
219 if (it->Matches(codec)) { | |
220 if (found_codec != NULL) { | 219 if (found_codec != NULL) { |
221 *found_codec = *it; | 220 *found_codec = c; |
222 } | 221 } |
223 return true; | 222 return true; |
224 } | 223 } |
225 } | 224 } |
226 return false; | 225 return false; |
227 } | 226 } |
228 | 227 |
229 static bool IsNackEnabled(const AudioCodec& codec) { | 228 static bool IsNackEnabled(const AudioCodec& codec) { |
230 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, | 229 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, |
231 kParamValueEmpty)); | 230 kParamValueEmpty)); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 | 548 |
550 // Set defaults for options, so that ApplyOptions applies them explicitly | 549 // Set defaults for options, so that ApplyOptions applies them explicitly |
551 // when we clear option (channel) overrides. External clients can still | 550 // when we clear option (channel) overrides. External clients can still |
552 // modify the defaults via SetOptions (on the media engine). | 551 // modify the defaults via SetOptions (on the media engine). |
553 if (!SetOptions(GetDefaultEngineOptions())) { | 552 if (!SetOptions(GetDefaultEngineOptions())) { |
554 return false; | 553 return false; |
555 } | 554 } |
556 | 555 |
557 // Print our codec list again for the call diagnostic log | 556 // Print our codec list again for the call diagnostic log |
558 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; | 557 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; |
559 for (std::vector<AudioCodec>::const_iterator it = codecs_.begin(); | 558 for (const AudioCodec& codec : codecs_) { |
560 it != codecs_.end(); ++it) { | 559 LOG(LS_INFO) << ToString(codec); |
561 LOG(LS_INFO) << ToString(*it); | |
562 } | 560 } |
563 | 561 |
564 // Disable the DTMF playout when a tone is sent. | 562 // Disable the DTMF playout when a tone is sent. |
565 // PlayDtmfTone will be used if local playout is needed. | 563 // PlayDtmfTone will be used if local playout is needed. |
566 if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) { | 564 if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) { |
567 LOG_RTCERR1(SetDtmfFeedbackStatus, false); | 565 LOG_RTCERR1(SetDtmfFeedbackStatus, false); |
568 } | 566 } |
569 | 567 |
570 initialized_ = true; | 568 initialized_ = true; |
571 return true; | 569 return true; |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 << ")"; | 939 << ")"; |
942 | 940 |
943 // If we're running the local monitor, we need to stop it first. | 941 // If we're running the local monitor, we need to stop it first. |
944 bool ret = true; | 942 bool ret = true; |
945 if (!PauseLocalMonitor()) { | 943 if (!PauseLocalMonitor()) { |
946 LOG(LS_WARNING) << "Failed to pause local monitor"; | 944 LOG(LS_WARNING) << "Failed to pause local monitor"; |
947 ret = false; | 945 ret = false; |
948 } | 946 } |
949 | 947 |
950 // Must also pause all audio playback and capture. | 948 // Must also pause all audio playback and capture. |
951 for (ChannelList::const_iterator i = channels_.begin(); | 949 for (WebRtcVoiceMediaChannel* channel : channels_) { |
952 i != channels_.end(); ++i) { | |
953 WebRtcVoiceMediaChannel *channel = *i; | |
954 if (!channel->PausePlayout()) { | 950 if (!channel->PausePlayout()) { |
955 LOG(LS_WARNING) << "Failed to pause playout"; | 951 LOG(LS_WARNING) << "Failed to pause playout"; |
956 ret = false; | 952 ret = false; |
957 } | 953 } |
958 if (!channel->PauseSend()) { | 954 if (!channel->PauseSend()) { |
959 LOG(LS_WARNING) << "Failed to pause send"; | 955 LOG(LS_WARNING) << "Failed to pause send"; |
960 ret = false; | 956 ret = false; |
961 } | 957 } |
962 } | 958 } |
963 | 959 |
(...skipping 17 matching lines...) Expand all Loading... |
981 ret = false; | 977 ret = false; |
982 } | 978 } |
983 if (ret) { | 979 if (ret) { |
984 if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) { | 980 if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) { |
985 LOG_RTCERR2(SetPlayoutDevice, out_name, out_id); | 981 LOG_RTCERR2(SetPlayoutDevice, out_name, out_id); |
986 ret = false; | 982 ret = false; |
987 } | 983 } |
988 } | 984 } |
989 | 985 |
990 // Resume all audio playback and capture. | 986 // Resume all audio playback and capture. |
991 for (ChannelList::const_iterator i = channels_.begin(); | 987 for (WebRtcVoiceMediaChannel* channel : channels_) { |
992 i != channels_.end(); ++i) { | |
993 WebRtcVoiceMediaChannel *channel = *i; | |
994 if (!channel->ResumePlayout()) { | 988 if (!channel->ResumePlayout()) { |
995 LOG(LS_WARNING) << "Failed to resume playout"; | 989 LOG(LS_WARNING) << "Failed to resume playout"; |
996 ret = false; | 990 ret = false; |
997 } | 991 } |
998 if (!channel->ResumeSend()) { | 992 if (!channel->ResumeSend()) { |
999 LOG(LS_WARNING) << "Failed to resume send"; | 993 LOG(LS_WARNING) << "Failed to resume send"; |
1000 ret = false; | 994 ret = false; |
1001 } | 995 } |
1002 } | 996 } |
1003 | 997 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 } | 1315 } |
1322 } | 1316 } |
1323 | 1317 |
1324 bool WebRtcVoiceEngine::FindChannelAndSsrc( | 1318 bool WebRtcVoiceEngine::FindChannelAndSsrc( |
1325 int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const { | 1319 int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const { |
1326 DCHECK(channel != NULL && ssrc != NULL); | 1320 DCHECK(channel != NULL && ssrc != NULL); |
1327 | 1321 |
1328 *channel = NULL; | 1322 *channel = NULL; |
1329 *ssrc = 0; | 1323 *ssrc = 0; |
1330 // Find corresponding channel and ssrc | 1324 // Find corresponding channel and ssrc |
1331 for (ChannelList::const_iterator it = channels_.begin(); | 1325 for (WebRtcVoiceMediaChannel* ch : channels_) { |
1332 it != channels_.end(); ++it) { | 1326 DCHECK(ch != NULL); |
1333 DCHECK(*it != NULL); | 1327 if (ch->FindSsrc(channel_num, ssrc)) { |
1334 if ((*it)->FindSsrc(channel_num, ssrc)) { | 1328 *channel = ch; |
1335 *channel = *it; | |
1336 return true; | 1329 return true; |
1337 } | 1330 } |
1338 } | 1331 } |
1339 | 1332 |
1340 return false; | 1333 return false; |
1341 } | 1334 } |
1342 | 1335 |
1343 // This method will search through the WebRtcVoiceMediaChannels and | 1336 // This method will search through the WebRtcVoiceMediaChannels and |
1344 // obtain the voice engine's channel number. | 1337 // obtain the voice engine's channel number. |
1345 bool WebRtcVoiceEngine::FindChannelNumFromSsrc( | 1338 bool WebRtcVoiceEngine::FindChannelNumFromSsrc( |
1346 uint32 ssrc, MediaProcessorDirection direction, int* channel_num) { | 1339 uint32 ssrc, MediaProcessorDirection direction, int* channel_num) { |
1347 DCHECK(channel_num != NULL); | 1340 DCHECK(channel_num != NULL); |
1348 DCHECK(direction == MPD_RX || direction == MPD_TX); | 1341 DCHECK(direction == MPD_RX || direction == MPD_TX); |
1349 | 1342 |
1350 *channel_num = -1; | 1343 *channel_num = -1; |
1351 // Find corresponding channel for ssrc. | 1344 // Find corresponding channel for ssrc. |
1352 for (ChannelList::const_iterator it = channels_.begin(); | 1345 for (const WebRtcVoiceMediaChannel* ch : channels_) { |
1353 it != channels_.end(); ++it) { | 1346 DCHECK(ch != NULL); |
1354 DCHECK(*it != NULL); | |
1355 if (direction & MPD_RX) { | 1347 if (direction & MPD_RX) { |
1356 *channel_num = (*it)->GetReceiveChannelNum(ssrc); | 1348 *channel_num = ch->GetReceiveChannelNum(ssrc); |
1357 } | 1349 } |
1358 if (*channel_num == -1 && (direction & MPD_TX)) { | 1350 if (*channel_num == -1 && (direction & MPD_TX)) { |
1359 *channel_num = (*it)->GetSendChannelNum(ssrc); | 1351 *channel_num = ch->GetSendChannelNum(ssrc); |
1360 } | 1352 } |
1361 if (*channel_num != -1) { | 1353 if (*channel_num != -1) { |
1362 return true; | 1354 return true; |
1363 } | 1355 } |
1364 } | 1356 } |
1365 LOG(LS_WARNING) << "FindChannelFromSsrc. No Channel Found for Ssrc: " << ssrc; | 1357 LOG(LS_WARNING) << "FindChannelFromSsrc. No Channel Found for Ssrc: " << ssrc; |
1366 return false; | 1358 return false; |
1367 } | 1359 } |
1368 | 1360 |
1369 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel *channel) { | 1361 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel *channel) { |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 | 1845 |
1854 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1846 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1855 const std::vector<AudioCodec>& codecs) { | 1847 const std::vector<AudioCodec>& codecs) { |
1856 // Set the payload types to be used for incoming media. | 1848 // Set the payload types to be used for incoming media. |
1857 LOG(LS_INFO) << "Setting receive voice codecs:"; | 1849 LOG(LS_INFO) << "Setting receive voice codecs:"; |
1858 | 1850 |
1859 std::vector<AudioCodec> new_codecs; | 1851 std::vector<AudioCodec> new_codecs; |
1860 // Find all new codecs. We allow adding new codecs but don't allow changing | 1852 // Find all new codecs. We allow adding new codecs but don't allow changing |
1861 // the payload type of codecs that is already configured since we might | 1853 // the payload type of codecs that is already configured since we might |
1862 // already be receiving packets with that payload type. | 1854 // already be receiving packets with that payload type. |
1863 for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); | 1855 for (const AudioCodec& codec : codecs) { |
1864 it != codecs.end(); ++it) { | |
1865 AudioCodec old_codec; | 1856 AudioCodec old_codec; |
1866 if (FindCodec(recv_codecs_, *it, &old_codec)) { | 1857 if (FindCodec(recv_codecs_, codec, &old_codec)) { |
1867 if (old_codec.id != it->id) { | 1858 if (old_codec.id != codec.id) { |
1868 LOG(LS_ERROR) << it->name << " payload type changed."; | 1859 LOG(LS_ERROR) << codec.name << " payload type changed."; |
1869 return false; | 1860 return false; |
1870 } | 1861 } |
1871 } else { | 1862 } else { |
1872 new_codecs.push_back(*it); | 1863 new_codecs.push_back(codec); |
1873 } | 1864 } |
1874 } | 1865 } |
1875 if (new_codecs.empty()) { | 1866 if (new_codecs.empty()) { |
1876 // There are no new codecs to configure. Already configured codecs are | 1867 // There are no new codecs to configure. Already configured codecs are |
1877 // never removed. | 1868 // never removed. |
1878 return true; | 1869 return true; |
1879 } | 1870 } |
1880 | 1871 |
1881 if (playout_) { | 1872 if (playout_) { |
1882 // Receive codecs can not be changed while playing. So we temporarily | 1873 // Receive codecs can not be changed while playing. So we temporarily |
1883 // pause playout. | 1874 // pause playout. |
1884 PausePlayout(); | 1875 PausePlayout(); |
1885 } | 1876 } |
1886 | 1877 |
1887 bool ret = true; | 1878 bool result = SetRecvCodecsInternal(new_codecs); |
1888 for (std::vector<AudioCodec>::const_iterator it = new_codecs.begin(); | 1879 if (result) { |
1889 it != new_codecs.end() && ret; ++it) { | |
1890 webrtc::CodecInst voe_codec; | |
1891 if (engine()->FindWebRtcCodec(*it, &voe_codec)) { | |
1892 LOG(LS_INFO) << ToString(*it); | |
1893 voe_codec.pltype = it->id; | |
1894 if (default_receive_ssrc_ == 0) { | |
1895 // Set the receive codecs on the default channel explicitly if the | |
1896 // default channel is not used by |receive_channels_|, this happens in | |
1897 // conference mode or in non-conference mode when there is no playout | |
1898 // channel. | |
1899 // TODO(xians): Figure out how we use the default channel in conference | |
1900 // mode. | |
1901 if (engine()->voe()->codec()->SetRecPayloadType( | |
1902 voe_channel(), voe_codec) == -1) { | |
1903 LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec)); | |
1904 ret = false; | |
1905 } | |
1906 } | |
1907 | |
1908 // Set the receive codecs on all receiving channels. | |
1909 for (ChannelMap::iterator it = receive_channels_.begin(); | |
1910 it != receive_channels_.end() && ret; ++it) { | |
1911 if (engine()->voe()->codec()->SetRecPayloadType( | |
1912 it->second->channel(), voe_codec) == -1) { | |
1913 LOG_RTCERR2(SetRecPayloadType, it->second->channel(), | |
1914 ToString(voe_codec)); | |
1915 ret = false; | |
1916 } | |
1917 } | |
1918 } else { | |
1919 LOG(LS_WARNING) << "Unknown codec " << ToString(*it); | |
1920 ret = false; | |
1921 } | |
1922 } | |
1923 if (ret) { | |
1924 recv_codecs_ = codecs; | 1880 recv_codecs_ = codecs; |
1925 } | 1881 } |
1926 | 1882 |
1927 if (desired_playout_ && !playout_) { | 1883 if (desired_playout_ && !playout_) { |
1928 ResumePlayout(); | 1884 ResumePlayout(); |
1929 } | 1885 } |
1930 return ret; | 1886 return result; |
1931 } | 1887 } |
1932 | 1888 |
1933 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1889 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1934 int channel, const std::vector<AudioCodec>& codecs) { | 1890 int channel, const std::vector<AudioCodec>& codecs) { |
1935 // Disable VAD, FEC, and RED unless we know the other side wants them. | 1891 // Disable VAD, FEC, and RED unless we know the other side wants them. |
1936 engine()->voe()->codec()->SetVADStatus(channel, false); | 1892 engine()->voe()->codec()->SetVADStatus(channel, false); |
1937 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | 1893 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); |
1938 engine()->voe()->rtp()->SetREDStatus(channel, false); | 1894 engine()->voe()->rtp()->SetREDStatus(channel, false); |
1939 engine()->voe()->codec()->SetFECStatus(channel, false); | 1895 engine()->voe()->codec()->SetFECStatus(channel, false); |
1940 | 1896 |
1941 // Scan through the list to figure out the codec to use for sending, along | 1897 // Scan through the list to figure out the codec to use for sending, along |
1942 // with the proper configuration for VAD and DTMF. | 1898 // with the proper configuration for VAD and DTMF. |
1943 bool found_send_codec = false; | 1899 bool found_send_codec = false; |
1944 webrtc::CodecInst send_codec; | 1900 webrtc::CodecInst send_codec; |
1945 memset(&send_codec, 0, sizeof(send_codec)); | 1901 memset(&send_codec, 0, sizeof(send_codec)); |
1946 | 1902 |
1947 bool nack_enabled = nack_enabled_; | 1903 bool nack_enabled = nack_enabled_; |
1948 bool enable_codec_fec = false; | 1904 bool enable_codec_fec = false; |
1949 bool enable_opus_dtx = false; | 1905 bool enable_opus_dtx = false; |
1950 int opus_max_playback_rate = 0; | 1906 int opus_max_playback_rate = 0; |
1951 | 1907 |
1952 // Set send codec (the first non-telephone-event/CN codec) | 1908 // Set send codec (the first non-telephone-event/CN codec) |
1953 for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); | 1909 for (const AudioCodec& codec : codecs) { |
1954 it != codecs.end(); ++it) { | |
1955 // Ignore codecs we don't know about. The negotiation step should prevent | 1910 // Ignore codecs we don't know about. The negotiation step should prevent |
1956 // this, but double-check to be sure. | 1911 // this, but double-check to be sure. |
1957 webrtc::CodecInst voe_codec; | 1912 webrtc::CodecInst voe_codec; |
1958 if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { | 1913 if (!engine()->FindWebRtcCodec(codec, &voe_codec)) { |
1959 LOG(LS_WARNING) << "Unknown codec " << ToString(*it); | 1914 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
1960 continue; | 1915 continue; |
1961 } | 1916 } |
1962 | 1917 |
1963 if (IsCodec(*it, kDtmfCodecName) || IsCodec(*it, kCnCodecName)) { | 1918 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { |
1964 // Skip telephone-event/CN codec, which will be handled later. | 1919 // Skip telephone-event/CN codec, which will be handled later. |
1965 continue; | 1920 continue; |
1966 } | 1921 } |
1967 | 1922 |
1968 // We'll use the first codec in the list to actually send audio data. | 1923 // We'll use the first codec in the list to actually send audio data. |
1969 // Be sure to use the payload type requested by the remote side. | 1924 // Be sure to use the payload type requested by the remote side. |
1970 // "red", for RED audio, is a special case where the actual codec to be | 1925 // "red", for RED audio, is a special case where the actual codec to be |
1971 // used is specified in params. | 1926 // used is specified in params. |
1972 if (IsCodec(*it, kRedCodecName)) { | 1927 if (IsCodec(codec, kRedCodecName)) { |
1973 // Parse out the RED parameters. If we fail, just ignore RED; | 1928 // Parse out the RED parameters. If we fail, just ignore RED; |
1974 // we don't support all possible params/usage scenarios. | 1929 // we don't support all possible params/usage scenarios. |
1975 if (!GetRedSendCodec(*it, codecs, &send_codec)) { | 1930 if (!GetRedSendCodec(codec, codecs, &send_codec)) { |
1976 continue; | 1931 continue; |
1977 } | 1932 } |
1978 | 1933 |
1979 // Enable redundant encoding of the specified codec. Treat any | 1934 // Enable redundant encoding of the specified codec. Treat any |
1980 // failure as a fatal internal error. | 1935 // failure as a fatal internal error. |
1981 LOG(LS_INFO) << "Enabling RED on channel " << channel; | 1936 LOG(LS_INFO) << "Enabling RED on channel " << channel; |
1982 if (engine()->voe()->rtp()->SetREDStatus(channel, true, it->id) == -1) { | 1937 if (engine()->voe()->rtp()->SetREDStatus(channel, true, codec.id) == -1) { |
1983 LOG_RTCERR3(SetREDStatus, channel, true, it->id); | 1938 LOG_RTCERR3(SetREDStatus, channel, true, codec.id); |
1984 return false; | 1939 return false; |
1985 } | 1940 } |
1986 } else { | 1941 } else { |
1987 send_codec = voe_codec; | 1942 send_codec = voe_codec; |
1988 nack_enabled = IsNackEnabled(*it); | 1943 nack_enabled = IsNackEnabled(codec); |
1989 // For Opus as the send codec, we are to determine inband FEC, maximum | 1944 // For Opus as the send codec, we are to determine inband FEC, maximum |
1990 // playback rate, and opus internal dtx. | 1945 // playback rate, and opus internal dtx. |
1991 if (IsCodec(*it, kOpusCodecName)) { | 1946 if (IsCodec(codec, kOpusCodecName)) { |
1992 GetOpusConfig(*it, &send_codec, &enable_codec_fec, | 1947 GetOpusConfig(codec, &send_codec, &enable_codec_fec, |
1993 &opus_max_playback_rate, &enable_opus_dtx); | 1948 &opus_max_playback_rate, &enable_opus_dtx); |
1994 } | 1949 } |
1995 | 1950 |
1996 // Set packet size if the AudioCodec param kCodecParamPTime is set. | 1951 // Set packet size if the AudioCodec param kCodecParamPTime is set. |
1997 int ptime_ms = 0; | 1952 int ptime_ms = 0; |
1998 if (it->GetParam(kCodecParamPTime, &ptime_ms)) { | 1953 if (codec.GetParam(kCodecParamPTime, &ptime_ms)) { |
1999 if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) { | 1954 if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) { |
2000 LOG(LS_WARNING) << "Failed to set packet size for codec " | 1955 LOG(LS_WARNING) << "Failed to set packet size for codec " |
2001 << send_codec.plname; | 1956 << send_codec.plname; |
2002 return false; | 1957 return false; |
2003 } | 1958 } |
2004 } | 1959 } |
2005 } | 1960 } |
2006 found_send_codec = true; | 1961 found_send_codec = true; |
2007 break; | 1962 break; |
2008 } | 1963 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2063 } | 2018 } |
2064 | 2019 |
2065 // Always update the |send_codec_| to the currently set send codec. | 2020 // Always update the |send_codec_| to the currently set send codec. |
2066 send_codec_.reset(new webrtc::CodecInst(send_codec)); | 2021 send_codec_.reset(new webrtc::CodecInst(send_codec)); |
2067 | 2022 |
2068 if (send_bitrate_setting_) { | 2023 if (send_bitrate_setting_) { |
2069 SetSendBitrateInternal(send_bitrate_bps_); | 2024 SetSendBitrateInternal(send_bitrate_bps_); |
2070 } | 2025 } |
2071 | 2026 |
2072 // Loop through the codecs list again to config the telephone-event/CN codec. | 2027 // Loop through the codecs list again to config the telephone-event/CN codec. |
2073 for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); | 2028 for (const AudioCodec& codec : codecs) { |
2074 it != codecs.end(); ++it) { | |
2075 // Ignore codecs we don't know about. The negotiation step should prevent | 2029 // Ignore codecs we don't know about. The negotiation step should prevent |
2076 // this, but double-check to be sure. | 2030 // this, but double-check to be sure. |
2077 webrtc::CodecInst voe_codec; | 2031 webrtc::CodecInst voe_codec; |
2078 if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { | 2032 if (!engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2079 LOG(LS_WARNING) << "Unknown codec " << ToString(*it); | 2033 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
2080 continue; | 2034 continue; |
2081 } | 2035 } |
2082 | 2036 |
2083 // Find the DTMF telephone event "codec" and tell VoiceEngine channels | 2037 // Find the DTMF telephone event "codec" and tell VoiceEngine channels |
2084 // about it. | 2038 // about it. |
2085 if (IsCodec(*it, kDtmfCodecName)) { | 2039 if (IsCodec(codec, kDtmfCodecName)) { |
2086 if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType( | 2040 if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType( |
2087 channel, it->id) == -1) { | 2041 channel, codec.id) == -1) { |
2088 LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, it->id); | 2042 LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, codec.id); |
2089 return false; | 2043 return false; |
2090 } | 2044 } |
2091 } else if (IsCodec(*it, kCnCodecName)) { | 2045 } else if (IsCodec(codec, kCnCodecName)) { |
2092 // Turn voice activity detection/comfort noise on if supported. | 2046 // Turn voice activity detection/comfort noise on if supported. |
2093 // Set the wideband CN payload type appropriately. | 2047 // Set the wideband CN payload type appropriately. |
2094 // (narrowband always uses the static payload type 13). | 2048 // (narrowband always uses the static payload type 13). |
2095 webrtc::PayloadFrequencies cn_freq; | 2049 webrtc::PayloadFrequencies cn_freq; |
2096 switch (it->clockrate) { | 2050 switch (codec.clockrate) { |
2097 case 8000: | 2051 case 8000: |
2098 cn_freq = webrtc::kFreq8000Hz; | 2052 cn_freq = webrtc::kFreq8000Hz; |
2099 break; | 2053 break; |
2100 case 16000: | 2054 case 16000: |
2101 cn_freq = webrtc::kFreq16000Hz; | 2055 cn_freq = webrtc::kFreq16000Hz; |
2102 break; | 2056 break; |
2103 case 32000: | 2057 case 32000: |
2104 cn_freq = webrtc::kFreq32000Hz; | 2058 cn_freq = webrtc::kFreq32000Hz; |
2105 break; | 2059 break; |
2106 default: | 2060 default: |
2107 LOG(LS_WARNING) << "CN frequency " << it->clockrate | 2061 LOG(LS_WARNING) << "CN frequency " << codec.clockrate |
2108 << " not supported."; | 2062 << " not supported."; |
2109 continue; | 2063 continue; |
2110 } | 2064 } |
2111 // Set the CN payloadtype and the VAD status. | 2065 // Set the CN payloadtype and the VAD status. |
2112 // The CN payload type for 8000 Hz clockrate is fixed at 13. | 2066 // The CN payload type for 8000 Hz clockrate is fixed at 13. |
2113 if (cn_freq != webrtc::kFreq8000Hz) { | 2067 if (cn_freq != webrtc::kFreq8000Hz) { |
2114 if (engine()->voe()->codec()->SetSendCNPayloadType( | 2068 if (engine()->voe()->codec()->SetSendCNPayloadType( |
2115 channel, it->id, cn_freq) == -1) { | 2069 channel, codec.id, cn_freq) == -1) { |
2116 LOG_RTCERR3(SetSendCNPayloadType, channel, it->id, cn_freq); | 2070 LOG_RTCERR3(SetSendCNPayloadType, channel, codec.id, cn_freq); |
2117 // TODO(ajm): This failure condition will be removed from VoE. | 2071 // TODO(ajm): This failure condition will be removed from VoE. |
2118 // Restore the return here when we update to a new enough webrtc. | 2072 // Restore the return here when we update to a new enough webrtc. |
2119 // | 2073 // |
2120 // Not returning false because the SetSendCNPayloadType will fail if | 2074 // Not returning false because the SetSendCNPayloadType will fail if |
2121 // the channel is already sending. | 2075 // the channel is already sending. |
2122 // This can happen if the remote description is applied twice, for | 2076 // This can happen if the remote description is applied twice, for |
2123 // example in the case of ROAP on top of JSEP, where both side will | 2077 // example in the case of ROAP on top of JSEP, where both side will |
2124 // send the offer. | 2078 // send the offer. |
2125 } | 2079 } |
2126 } | 2080 } |
2127 // Only turn on VAD if we have a CN payload type that matches the | 2081 // Only turn on VAD if we have a CN payload type that matches the |
2128 // clockrate for the codec we are going to use. | 2082 // clockrate for the codec we are going to use. |
2129 if (it->clockrate == send_codec.plfreq && send_codec.channels != 2) { | 2083 if (codec.clockrate == send_codec.plfreq && send_codec.channels != 2) { |
2130 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the | 2084 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the |
2131 // interaction between VAD and Opus FEC. | 2085 // interaction between VAD and Opus FEC. |
2132 LOG(LS_INFO) << "Enabling VAD"; | 2086 LOG(LS_INFO) << "Enabling VAD"; |
2133 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { | 2087 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { |
2134 LOG_RTCERR2(SetVADStatus, channel, true); | 2088 LOG_RTCERR2(SetVADStatus, channel, true); |
2135 return false; | 2089 return false; |
2136 } | 2090 } |
2137 } | 2091 } |
2138 } | 2092 } |
2139 } | 2093 } |
2140 return true; | 2094 return true; |
2141 } | 2095 } |
2142 | 2096 |
2143 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 2097 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
2144 const std::vector<AudioCodec>& codecs) { | 2098 const std::vector<AudioCodec>& codecs) { |
2145 dtmf_allowed_ = false; | 2099 dtmf_allowed_ = false; |
2146 for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); | 2100 for (const AudioCodec& codec : codecs) { |
2147 it != codecs.end(); ++it) { | |
2148 // Find the DTMF telephone event "codec". | 2101 // Find the DTMF telephone event "codec". |
2149 if (IsCodec(*it, kDtmfCodecName)) { | 2102 if (IsCodec(codec, kDtmfCodecName)) { |
2150 dtmf_allowed_ = true; | 2103 dtmf_allowed_ = true; |
2151 } | 2104 } |
2152 } | 2105 } |
2153 | 2106 |
2154 // Cache the codecs in order to configure the channel created later. | 2107 // Cache the codecs in order to configure the channel created later. |
2155 send_codecs_ = codecs; | 2108 send_codecs_ = codecs; |
2156 for (ChannelMap::iterator iter = send_channels_.begin(); | 2109 for (const auto& ch : send_channels_) { |
2157 iter != send_channels_.end(); ++iter) { | 2110 if (!SetSendCodecs(ch.second->channel(), codecs)) { |
2158 if (!SetSendCodecs(iter->second->channel(), codecs)) { | |
2159 return false; | 2111 return false; |
2160 } | 2112 } |
2161 } | 2113 } |
2162 | 2114 |
2163 // Set nack status on receive channels and update |nack_enabled_|. | 2115 // Set nack status on receive channels and update |nack_enabled_|. |
2164 SetNack(receive_channels_, nack_enabled_); | 2116 SetNack(receive_channels_, nack_enabled_); |
2165 return true; | 2117 return true; |
2166 } | 2118 } |
2167 | 2119 |
2168 void WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels, | 2120 void WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels, |
2169 bool nack_enabled) { | 2121 bool nack_enabled) { |
2170 for (ChannelMap::const_iterator it = channels.begin(); | 2122 for (const auto& ch : channels) { |
2171 it != channels.end(); ++it) { | 2123 SetNack(ch.second->channel(), nack_enabled); |
2172 SetNack(it->second->channel(), nack_enabled); | |
2173 } | 2124 } |
2174 } | 2125 } |
2175 | 2126 |
2176 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { | 2127 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { |
2177 if (nack_enabled) { | 2128 if (nack_enabled) { |
2178 LOG(LS_INFO) << "Enabling NACK for channel " << channel; | 2129 LOG(LS_INFO) << "Enabling NACK for channel " << channel; |
2179 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); | 2130 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); |
2180 } else { | 2131 } else { |
2181 LOG(LS_INFO) << "Disabling NACK for channel " << channel; | 2132 LOG(LS_INFO) << "Disabling NACK for channel " << channel; |
2182 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | 2133 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); |
2183 } | 2134 } |
2184 } | 2135 } |
2185 | 2136 |
2186 bool WebRtcVoiceMediaChannel::SetSendCodec( | 2137 bool WebRtcVoiceMediaChannel::SetSendCodec( |
2187 const webrtc::CodecInst& send_codec) { | 2138 const webrtc::CodecInst& send_codec) { |
2188 LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec) | 2139 LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec) |
2189 << ", bitrate=" << send_codec.rate; | 2140 << ", bitrate=" << send_codec.rate; |
2190 for (ChannelMap::iterator iter = send_channels_.begin(); | 2141 for (const auto& ch : send_channels_) { |
2191 iter != send_channels_.end(); ++iter) { | 2142 if (!SetSendCodec(ch.second->channel(), send_codec)) |
2192 if (!SetSendCodec(iter->second->channel(), send_codec)) | |
2193 return false; | 2143 return false; |
2194 } | 2144 } |
2195 | 2145 |
2196 return true; | 2146 return true; |
2197 } | 2147 } |
2198 | 2148 |
2199 bool WebRtcVoiceMediaChannel::SetSendCodec( | 2149 bool WebRtcVoiceMediaChannel::SetSendCodec( |
2200 int channel, const webrtc::CodecInst& send_codec) { | 2150 int channel, const webrtc::CodecInst& send_codec) { |
2201 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " | 2151 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " |
2202 << ToString(send_codec) << ", bitrate=" << send_codec.rate; | 2152 << ToString(send_codec) << ", bitrate=" << send_codec.rate; |
(...skipping 18 matching lines...) Expand all Loading... |
2221 return true; | 2171 return true; |
2222 } | 2172 } |
2223 | 2173 |
2224 // The default channel may or may not be in |receive_channels_|. Set the rtp | 2174 // The default channel may or may not be in |receive_channels_|. Set the rtp |
2225 // header extensions for default channel regardless. | 2175 // header extensions for default channel regardless. |
2226 if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { | 2176 if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { |
2227 return false; | 2177 return false; |
2228 } | 2178 } |
2229 | 2179 |
2230 // Loop through all receive channels and enable/disable the extensions. | 2180 // Loop through all receive channels and enable/disable the extensions. |
2231 for (ChannelMap::const_iterator channel_it = receive_channels_.begin(); | 2181 for (const auto& ch : receive_channels_) { |
2232 channel_it != receive_channels_.end(); ++channel_it) { | 2182 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { |
2233 if (!SetChannelRecvRtpHeaderExtensions(channel_it->second->channel(), | |
2234 extensions)) { | |
2235 return false; | 2183 return false; |
2236 } | 2184 } |
2237 } | 2185 } |
2238 | 2186 |
2239 receive_extensions_ = extensions; | 2187 receive_extensions_ = extensions; |
2240 | 2188 |
2241 // Recreate AudioReceiveStream:s. | 2189 // Recreate AudioReceiveStream:s. |
2242 { | 2190 { |
2243 std::vector<webrtc::RtpExtension> exts; | 2191 std::vector<webrtc::RtpExtension> exts; |
2244 | 2192 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 } | 2239 } |
2292 | 2240 |
2293 // The default channel may or may not be in |send_channels_|. Set the rtp | 2241 // The default channel may or may not be in |send_channels_|. Set the rtp |
2294 // header extensions for default channel regardless. | 2242 // header extensions for default channel regardless. |
2295 | 2243 |
2296 if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { | 2244 if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { |
2297 return false; | 2245 return false; |
2298 } | 2246 } |
2299 | 2247 |
2300 // Loop through all send channels and enable/disable the extensions. | 2248 // Loop through all send channels and enable/disable the extensions. |
2301 for (ChannelMap::const_iterator channel_it = send_channels_.begin(); | 2249 for (const auto& ch : send_channels_) { |
2302 channel_it != send_channels_.end(); ++channel_it) { | 2250 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { |
2303 if (!SetChannelSendRtpHeaderExtensions(channel_it->second->channel(), | |
2304 extensions)) { | |
2305 return false; | 2251 return false; |
2306 } | 2252 } |
2307 } | 2253 } |
2308 | 2254 |
2309 send_extensions_ = extensions; | 2255 send_extensions_ = extensions; |
2310 return true; | 2256 return true; |
2311 } | 2257 } |
2312 | 2258 |
2313 bool WebRtcVoiceMediaChannel::SetChannelSendRtpHeaderExtensions( | 2259 bool WebRtcVoiceMediaChannel::SetChannelSendRtpHeaderExtensions( |
2314 int channel_id, const std::vector<RtpHeaderExtension>& extensions) { | 2260 int channel_id, const std::vector<RtpHeaderExtension>& extensions) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2349 if (playout_ == playout) { | 2295 if (playout_ == playout) { |
2350 return true; | 2296 return true; |
2351 } | 2297 } |
2352 | 2298 |
2353 // Change the playout of all channels to the new state. | 2299 // Change the playout of all channels to the new state. |
2354 bool result = true; | 2300 bool result = true; |
2355 if (receive_channels_.empty()) { | 2301 if (receive_channels_.empty()) { |
2356 // Only toggle the default channel if we don't have any other channels. | 2302 // Only toggle the default channel if we don't have any other channels. |
2357 result = SetPlayout(voe_channel(), playout); | 2303 result = SetPlayout(voe_channel(), playout); |
2358 } | 2304 } |
2359 for (ChannelMap::iterator it = receive_channels_.begin(); | 2305 for (const auto& ch : receive_channels_) { |
2360 it != receive_channels_.end() && result; ++it) { | 2306 if (!SetPlayout(ch.second->channel(), playout)) { |
2361 if (!SetPlayout(it->second->channel(), playout)) { | |
2362 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " | 2307 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " |
2363 << it->second->channel() << " failed"; | 2308 << ch.second->channel() << " failed"; |
2364 result = false; | 2309 result = false; |
| 2310 break; |
2365 } | 2311 } |
2366 } | 2312 } |
2367 | 2313 |
2368 if (result) { | 2314 if (result) { |
2369 playout_ = playout; | 2315 playout_ = playout; |
2370 } | 2316 } |
2371 return result; | 2317 return result; |
2372 } | 2318 } |
2373 | 2319 |
2374 bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) { | 2320 bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) { |
(...skipping 14 matching lines...) Expand all Loading... |
2389 bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) { | 2335 bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) { |
2390 if (send_ == send) { | 2336 if (send_ == send) { |
2391 return true; | 2337 return true; |
2392 } | 2338 } |
2393 | 2339 |
2394 // Change the settings on each send channel. | 2340 // Change the settings on each send channel. |
2395 if (send == SEND_MICROPHONE) | 2341 if (send == SEND_MICROPHONE) |
2396 engine()->SetOptionOverrides(options_); | 2342 engine()->SetOptionOverrides(options_); |
2397 | 2343 |
2398 // Change the settings on each send channel. | 2344 // Change the settings on each send channel. |
2399 for (ChannelMap::iterator iter = send_channels_.begin(); | 2345 for (const auto& ch : send_channels_) { |
2400 iter != send_channels_.end(); ++iter) { | 2346 if (!ChangeSend(ch.second->channel(), send)) |
2401 if (!ChangeSend(iter->second->channel(), send)) | |
2402 return false; | 2347 return false; |
2403 } | 2348 } |
2404 | 2349 |
2405 // Clear up the options after stopping sending. | 2350 // Clear up the options after stopping sending. |
2406 if (send == SEND_NOTHING) | 2351 if (send == SEND_NOTHING) |
2407 engine()->ClearOptionOverrides(); | 2352 engine()->ClearOptionOverrides(); |
2408 | 2353 |
2409 send_ = send; | 2354 send_ = send; |
2410 return true; | 2355 return true; |
2411 } | 2356 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2465 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2410 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
2466 // If the default channel is already used for sending create a new channel | 2411 // If the default channel is already used for sending create a new channel |
2467 // otherwise use the default channel for sending. | 2412 // otherwise use the default channel for sending. |
2468 int channel = GetSendChannelNum(sp.first_ssrc()); | 2413 int channel = GetSendChannelNum(sp.first_ssrc()); |
2469 if (channel != -1) { | 2414 if (channel != -1) { |
2470 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); | 2415 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); |
2471 return false; | 2416 return false; |
2472 } | 2417 } |
2473 | 2418 |
2474 bool default_channel_is_available = true; | 2419 bool default_channel_is_available = true; |
2475 for (ChannelMap::const_iterator iter = send_channels_.begin(); | 2420 for (const auto& ch : send_channels_) { |
2476 iter != send_channels_.end(); ++iter) { | 2421 if (IsDefaultChannel(ch.second->channel())) { |
2477 if (IsDefaultChannel(iter->second->channel())) { | |
2478 default_channel_is_available = false; | 2422 default_channel_is_available = false; |
2479 break; | 2423 break; |
2480 } | 2424 } |
2481 } | 2425 } |
2482 if (default_channel_is_available) { | 2426 if (default_channel_is_available) { |
2483 channel = voe_channel(); | 2427 channel = voe_channel(); |
2484 } else { | 2428 } else { |
2485 // Create a new channel for sending audio data. | 2429 // Create a new channel for sending audio data. |
2486 channel = engine()->CreateMediaVoiceChannel(); | 2430 channel = engine()->CreateMediaVoiceChannel(); |
2487 if (channel == -1) { | 2431 if (channel == -1) { |
(...skipping 19 matching lines...) Expand all Loading... |
2507 if (engine()->voe()->rtp()->SetLocalSSRC(channel, sp.first_ssrc()) == -1) { | 2451 if (engine()->voe()->rtp()->SetLocalSSRC(channel, sp.first_ssrc()) == -1) { |
2508 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); | 2452 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); |
2509 return false; | 2453 return false; |
2510 } | 2454 } |
2511 | 2455 |
2512 // At this point the channel's local SSRC has been updated. If the channel is | 2456 // At this point the channel's local SSRC has been updated. If the channel is |
2513 // the default channel make sure that all the receive channels are updated as | 2457 // the default channel make sure that all the receive channels are updated as |
2514 // well. Receive channels have to have the same SSRC as the default channel in | 2458 // well. Receive channels have to have the same SSRC as the default channel in |
2515 // order to send receiver reports with this SSRC. | 2459 // order to send receiver reports with this SSRC. |
2516 if (IsDefaultChannel(channel)) { | 2460 if (IsDefaultChannel(channel)) { |
2517 for (ChannelMap::const_iterator it = receive_channels_.begin(); | 2461 for (const auto& ch : receive_channels_) { |
2518 it != receive_channels_.end(); ++it) { | |
2519 // Only update the SSRC for non-default channels. | 2462 // Only update the SSRC for non-default channels. |
2520 if (!IsDefaultChannel(it->second->channel())) { | 2463 if (!IsDefaultChannel(ch.second->channel())) { |
2521 if (engine()->voe()->rtp()->SetLocalSSRC(it->second->channel(), | 2464 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), |
2522 sp.first_ssrc()) != 0) { | 2465 sp.first_ssrc()) != 0) { |
2523 LOG_RTCERR2(SetLocalSSRC, it->second->channel(), sp.first_ssrc()); | 2466 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc()); |
2524 return false; | 2467 return false; |
2525 } | 2468 } |
2526 } | 2469 } |
2527 } | 2470 } |
2528 } | 2471 } |
2529 | 2472 |
2530 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | 2473 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { |
2531 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | 2474 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); |
2532 return false; | 2475 return false; |
2533 } | 2476 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2655 // Associate receive channel to default channel (so the receive channel can | 2598 // Associate receive channel to default channel (so the receive channel can |
2656 // obtain RTT from the send channel) | 2599 // obtain RTT from the send channel) |
2657 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); | 2600 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); |
2658 LOG(LS_INFO) << "VoiceEngine channel #" | 2601 LOG(LS_INFO) << "VoiceEngine channel #" |
2659 << channel << " is associated with channel #" | 2602 << channel << " is associated with channel #" |
2660 << voe_channel() << "."; | 2603 << voe_channel() << "."; |
2661 | 2604 |
2662 // Use the same recv payload types as our default channel. | 2605 // Use the same recv payload types as our default channel. |
2663 ResetRecvCodecs(channel); | 2606 ResetRecvCodecs(channel); |
2664 if (!recv_codecs_.empty()) { | 2607 if (!recv_codecs_.empty()) { |
2665 for (std::vector<AudioCodec>::const_iterator it = recv_codecs_.begin(); | 2608 for (const auto& codec : recv_codecs_) { |
2666 it != recv_codecs_.end(); ++it) { | |
2667 webrtc::CodecInst voe_codec; | 2609 webrtc::CodecInst voe_codec; |
2668 if (engine()->FindWebRtcCodec(*it, &voe_codec)) { | 2610 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2669 voe_codec.pltype = it->id; | 2611 voe_codec.pltype = codec.id; |
2670 voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC | 2612 voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC |
2671 if (engine()->voe()->codec()->GetRecPayloadType( | 2613 if (engine()->voe()->codec()->GetRecPayloadType( |
2672 voe_channel(), voe_codec) != -1) { | 2614 voe_channel(), voe_codec) != -1) { |
2673 if (engine()->voe()->codec()->SetRecPayloadType( | 2615 if (engine()->voe()->codec()->SetRecPayloadType( |
2674 channel, voe_codec) == -1) { | 2616 channel, voe_codec) == -1) { |
2675 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2617 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
2676 return false; | 2618 return false; |
2677 } | 2619 } |
2678 } | 2620 } |
2679 } | 2621 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 it->second->Stop(); | 2746 it->second->Stop(); |
2805 | 2747 |
2806 return true; | 2748 return true; |
2807 } | 2749 } |
2808 | 2750 |
2809 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2751 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2810 AudioInfo::StreamList* actives) { | 2752 AudioInfo::StreamList* actives) { |
2811 // In conference mode, the default channel should not be in | 2753 // In conference mode, the default channel should not be in |
2812 // |receive_channels_|. | 2754 // |receive_channels_|. |
2813 actives->clear(); | 2755 actives->clear(); |
2814 for (ChannelMap::iterator it = receive_channels_.begin(); | 2756 for (const auto& ch : receive_channels_) { |
2815 it != receive_channels_.end(); ++it) { | 2757 int level = GetOutputLevel(ch.second->channel()); |
2816 int level = GetOutputLevel(it->second->channel()); | |
2817 if (level > 0) { | 2758 if (level > 0) { |
2818 actives->push_back(std::make_pair(it->first, level)); | 2759 actives->push_back(std::make_pair(ch.first, level)); |
2819 } | 2760 } |
2820 } | 2761 } |
2821 return true; | 2762 return true; |
2822 } | 2763 } |
2823 | 2764 |
2824 int WebRtcVoiceMediaChannel::GetOutputLevel() { | 2765 int WebRtcVoiceMediaChannel::GetOutputLevel() { |
2825 // return the highest output level of all streams | 2766 // return the highest output level of all streams |
2826 int highest = GetOutputLevel(voe_channel()); | 2767 int highest = GetOutputLevel(voe_channel()); |
2827 for (ChannelMap::iterator it = receive_channels_.begin(); | 2768 for (const auto& ch : receive_channels_) { |
2828 it != receive_channels_.end(); ++it) { | 2769 int level = GetOutputLevel(ch.second->channel()); |
2829 int level = GetOutputLevel(it->second->channel()); | |
2830 highest = std::max(level, highest); | 2770 highest = std::max(level, highest); |
2831 } | 2771 } |
2832 return highest; | 2772 return highest; |
2833 } | 2773 } |
2834 | 2774 |
2835 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { | 2775 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { |
2836 int ret; | 2776 int ret; |
2837 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { | 2777 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { |
2838 // In case of error, log the info and continue | 2778 // In case of error, log the info and continue |
2839 LOG_RTCERR0(TimeSinceLastTyping); | 2779 LOG_RTCERR0(TimeSinceLastTyping); |
(...skipping 20 matching lines...) Expand all Loading... |
2860 bool WebRtcVoiceMediaChannel::SetOutputScaling( | 2800 bool WebRtcVoiceMediaChannel::SetOutputScaling( |
2861 uint32 ssrc, double left, double right) { | 2801 uint32 ssrc, double left, double right) { |
2862 rtc::CritScope lock(&receive_channels_cs_); | 2802 rtc::CritScope lock(&receive_channels_cs_); |
2863 // Collect the channels to scale the output volume. | 2803 // Collect the channels to scale the output volume. |
2864 std::vector<int> channels; | 2804 std::vector<int> channels; |
2865 if (0 == ssrc) { // Collect all channels, including the default one. | 2805 if (0 == ssrc) { // Collect all channels, including the default one. |
2866 // Default channel is not in receive_channels_ if it is not being used for | 2806 // Default channel is not in receive_channels_ if it is not being used for |
2867 // playout. | 2807 // playout. |
2868 if (default_receive_ssrc_ == 0) | 2808 if (default_receive_ssrc_ == 0) |
2869 channels.push_back(voe_channel()); | 2809 channels.push_back(voe_channel()); |
2870 for (ChannelMap::const_iterator it = receive_channels_.begin(); | 2810 for (const auto& ch : receive_channels_) { |
2871 it != receive_channels_.end(); ++it) { | 2811 channels.push_back(ch.second->channel()); |
2872 channels.push_back(it->second->channel()); | |
2873 } | 2812 } |
2874 } else { // Collect only the channel of the specified ssrc. | 2813 } else { // Collect only the channel of the specified ssrc. |
2875 int channel = GetReceiveChannelNum(ssrc); | 2814 int channel = GetReceiveChannelNum(ssrc); |
2876 if (-1 == channel) { | 2815 if (-1 == channel) { |
2877 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; | 2816 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; |
2878 return false; | 2817 return false; |
2879 } | 2818 } |
2880 channels.push_back(channel); | 2819 channels.push_back(channel); |
2881 } | 2820 } |
2882 | 2821 |
2883 // Scale the output volume for the collected channels. We first normalize to | 2822 // Scale the output volume for the collected channels. We first normalize to |
2884 // scale the volume and then set the left and right pan. | 2823 // scale the volume and then set the left and right pan. |
2885 float scale = static_cast<float>(std::max(left, right)); | 2824 float scale = static_cast<float>(std::max(left, right)); |
2886 if (scale > 0.0001f) { | 2825 if (scale > 0.0001f) { |
2887 left /= scale; | 2826 left /= scale; |
2888 right /= scale; | 2827 right /= scale; |
2889 } | 2828 } |
2890 for (std::vector<int>::const_iterator it = channels.begin(); | 2829 for (int ch_id : channels) { |
2891 it != channels.end(); ++it) { | |
2892 if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling( | 2830 if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling( |
2893 *it, scale)) { | 2831 ch_id, scale)) { |
2894 LOG_RTCERR2(SetChannelOutputVolumeScaling, *it, scale); | 2832 LOG_RTCERR2(SetChannelOutputVolumeScaling, ch_id, scale); |
2895 return false; | 2833 return false; |
2896 } | 2834 } |
2897 if (-1 == engine()->voe()->volume()->SetOutputVolumePan( | 2835 if (-1 == engine()->voe()->volume()->SetOutputVolumePan( |
2898 *it, static_cast<float>(left), static_cast<float>(right))) { | 2836 ch_id, static_cast<float>(left), static_cast<float>(right))) { |
2899 LOG_RTCERR3(SetOutputVolumePan, *it, left, right); | 2837 LOG_RTCERR3(SetOutputVolumePan, ch_id, left, right); |
2900 // Do not return if fails. SetOutputVolumePan is not available for all | 2838 // Do not return if fails. SetOutputVolumePan is not available for all |
2901 // pltforms. | 2839 // pltforms. |
2902 } | 2840 } |
2903 LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale | 2841 LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale |
2904 << " right=" << right * scale | 2842 << " right=" << right * scale |
2905 << " for channel " << *it << " and ssrc " << ssrc; | 2843 << " for channel " << ch_id << " and ssrc " << ssrc; |
2906 } | 2844 } |
2907 return true; | 2845 return true; |
2908 } | 2846 } |
2909 | 2847 |
2910 bool WebRtcVoiceMediaChannel::GetOutputScaling( | 2848 bool WebRtcVoiceMediaChannel::GetOutputScaling( |
2911 uint32 ssrc, double* left, double* right) { | 2849 uint32 ssrc, double* left, double* right) { |
2912 if (!left || !right) return false; | 2850 if (!left || !right) return false; |
2913 | 2851 |
2914 rtc::CritScope lock(&receive_channels_cs_); | 2852 rtc::CritScope lock(&receive_channels_cs_); |
2915 // Determine which channel based on ssrc. | 2853 // Determine which channel based on ssrc. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2996 int duration, int flags) { | 2934 int duration, int flags) { |
2997 if (!dtmf_allowed_) { | 2935 if (!dtmf_allowed_) { |
2998 return false; | 2936 return false; |
2999 } | 2937 } |
3000 | 2938 |
3001 // Send the event. | 2939 // Send the event. |
3002 if (flags & cricket::DF_SEND) { | 2940 if (flags & cricket::DF_SEND) { |
3003 int channel = -1; | 2941 int channel = -1; |
3004 if (ssrc == 0) { | 2942 if (ssrc == 0) { |
3005 bool default_channel_is_inuse = false; | 2943 bool default_channel_is_inuse = false; |
3006 for (ChannelMap::const_iterator iter = send_channels_.begin(); | 2944 for (const auto& ch : send_channels_) { |
3007 iter != send_channels_.end(); ++iter) { | 2945 if (IsDefaultChannel(ch.second->channel())) { |
3008 if (IsDefaultChannel(iter->second->channel())) { | |
3009 default_channel_is_inuse = true; | 2946 default_channel_is_inuse = true; |
3010 break; | 2947 break; |
3011 } | 2948 } |
3012 } | 2949 } |
3013 if (default_channel_is_inuse) { | 2950 if (default_channel_is_inuse) { |
3014 channel = voe_channel(); | 2951 channel = voe_channel(); |
3015 } else if (!send_channels_.empty()) { | 2952 } else if (!send_channels_.empty()) { |
3016 channel = send_channels_.begin()->second->channel(); | 2953 channel = send_channels_.begin()->second->channel(); |
3017 } | 2954 } |
3018 } else { | 2955 } else { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3114 which_channel, packet->data(), packet->size()); | 3051 which_channel, packet->data(), packet->size()); |
3115 | 3052 |
3116 if (IsDefaultChannel(which_channel)) | 3053 if (IsDefaultChannel(which_channel)) |
3117 has_sent_to_default_channel = true; | 3054 has_sent_to_default_channel = true; |
3118 } | 3055 } |
3119 } | 3056 } |
3120 | 3057 |
3121 // SR may continue RR and any RR entry may correspond to any one of the send | 3058 // SR may continue RR and any RR entry may correspond to any one of the send |
3122 // channels. So all RTCP packets must be forwarded all send channels. VoE | 3059 // channels. So all RTCP packets must be forwarded all send channels. VoE |
3123 // will filter out RR internally. | 3060 // will filter out RR internally. |
3124 for (ChannelMap::iterator iter = send_channels_.begin(); | 3061 for (const auto& ch : send_channels_) { |
3125 iter != send_channels_.end(); ++iter) { | |
3126 // Make sure not sending the same packet to default channel more than once. | 3062 // Make sure not sending the same packet to default channel more than once. |
3127 if (IsDefaultChannel(iter->second->channel()) && | 3063 if (IsDefaultChannel(ch.second->channel()) && |
3128 has_sent_to_default_channel) | 3064 has_sent_to_default_channel) |
3129 continue; | 3065 continue; |
3130 | 3066 |
3131 engine()->voe()->network()->ReceivedRTCPPacket( | 3067 engine()->voe()->network()->ReceivedRTCPPacket( |
3132 iter->second->channel(), packet->data(), packet->size()); | 3068 ch.second->channel(), packet->data(), packet->size()); |
3133 } | 3069 } |
3134 } | 3070 } |
3135 | 3071 |
3136 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { | 3072 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { |
3137 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); | 3073 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); |
3138 if (channel == -1) { | 3074 if (channel == -1) { |
3139 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 3075 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
3140 return false; | 3076 return false; |
3141 } | 3077 } |
3142 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { | 3078 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { |
3143 LOG_RTCERR2(SetInputMute, channel, muted); | 3079 LOG_RTCERR2(SetInputMute, channel, muted); |
3144 return false; | 3080 return false; |
3145 } | 3081 } |
3146 // We set the AGC to mute state only when all the channels are muted. | 3082 // We set the AGC to mute state only when all the channels are muted. |
3147 // This implementation is not ideal, instead we should signal the AGC when | 3083 // This implementation is not ideal, instead we should signal the AGC when |
3148 // the mic channel is muted/unmuted. We can't do it today because there | 3084 // the mic channel is muted/unmuted. We can't do it today because there |
3149 // is no good way to know which stream is mapping to the mic channel. | 3085 // is no good way to know which stream is mapping to the mic channel. |
3150 bool all_muted = muted; | 3086 bool all_muted = muted; |
3151 for (ChannelMap::const_iterator iter = send_channels_.begin(); | 3087 for (const auto& ch : send_channels_) { |
3152 iter != send_channels_.end() && all_muted; ++iter) { | 3088 if (!all_muted) { |
3153 if (engine()->voe()->volume()->GetInputMute(iter->second->channel(), | 3089 break; |
| 3090 } |
| 3091 if (engine()->voe()->volume()->GetInputMute(ch.second->channel(), |
3154 all_muted)) { | 3092 all_muted)) { |
3155 LOG_RTCERR1(GetInputMute, iter->second->channel()); | 3093 LOG_RTCERR1(GetInputMute, ch.second->channel()); |
3156 return false; | 3094 return false; |
3157 } | 3095 } |
3158 } | 3096 } |
3159 | 3097 |
3160 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 3098 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
3161 if (ap) | 3099 if (ap) |
3162 ap->set_output_will_be_muted(all_muted); | 3100 ap->set_output_will_be_muted(all_muted); |
3163 return true; | 3101 return true; |
3164 } | 3102 } |
3165 | 3103 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 echo_delay_median_ms = median; | 3182 echo_delay_median_ms = median; |
3245 echo_delay_std_ms = std; | 3183 echo_delay_std_ms = std; |
3246 } | 3184 } |
3247 } | 3185 } |
3248 | 3186 |
3249 webrtc::CallStatistics cs; | 3187 webrtc::CallStatistics cs; |
3250 unsigned int ssrc; | 3188 unsigned int ssrc; |
3251 webrtc::CodecInst codec; | 3189 webrtc::CodecInst codec; |
3252 unsigned int level; | 3190 unsigned int level; |
3253 | 3191 |
3254 for (ChannelMap::const_iterator channel_iter = send_channels_.begin(); | 3192 for (const auto& ch : send_channels_) { |
3255 channel_iter != send_channels_.end(); ++channel_iter) { | 3193 const int channel = ch.second->channel(); |
3256 const int channel = channel_iter->second->channel(); | |
3257 | 3194 |
3258 // Fill in the sender info, based on what we know, and what the | 3195 // Fill in the sender info, based on what we know, and what the |
3259 // remote side told us it got from its RTCP report. | 3196 // remote side told us it got from its RTCP report. |
3260 VoiceSenderInfo sinfo; | 3197 VoiceSenderInfo sinfo; |
3261 | 3198 |
3262 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || | 3199 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || |
3263 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { | 3200 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { |
3264 continue; | 3201 continue; |
3265 } | 3202 } |
3266 | 3203 |
3267 sinfo.add_ssrc(ssrc); | 3204 sinfo.add_ssrc(ssrc); |
3268 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; | 3205 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; |
3269 sinfo.bytes_sent = cs.bytesSent; | 3206 sinfo.bytes_sent = cs.bytesSent; |
3270 sinfo.packets_sent = cs.packetsSent; | 3207 sinfo.packets_sent = cs.packetsSent; |
3271 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | 3208 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine |
3272 // returns 0 to indicate an error value. | 3209 // returns 0 to indicate an error value. |
3273 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; | 3210 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; |
3274 | 3211 |
3275 // Get data from the last remote RTCP report. Use default values if no data | 3212 // Get data from the last remote RTCP report. Use default values if no data |
3276 // available. | 3213 // available. |
3277 sinfo.fraction_lost = -1.0; | 3214 sinfo.fraction_lost = -1.0; |
3278 sinfo.jitter_ms = -1; | 3215 sinfo.jitter_ms = -1; |
3279 sinfo.packets_lost = -1; | 3216 sinfo.packets_lost = -1; |
3280 sinfo.ext_seqnum = -1; | 3217 sinfo.ext_seqnum = -1; |
3281 std::vector<webrtc::ReportBlock> receive_blocks; | 3218 std::vector<webrtc::ReportBlock> receive_blocks; |
3282 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( | 3219 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( |
3283 channel, &receive_blocks) != -1 && | 3220 channel, &receive_blocks) != -1 && |
3284 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { | 3221 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { |
3285 std::vector<webrtc::ReportBlock>::iterator iter; | 3222 for (const webrtc::ReportBlock& block : receive_blocks) { |
3286 for (iter = receive_blocks.begin(); iter != receive_blocks.end(); | |
3287 ++iter) { | |
3288 // Lookup report for send ssrc only. | 3223 // Lookup report for send ssrc only. |
3289 if (iter->source_SSRC == sinfo.ssrc()) { | 3224 if (block.source_SSRC == sinfo.ssrc()) { |
3290 // Convert Q8 to floating point. | 3225 // Convert Q8 to floating point. |
3291 sinfo.fraction_lost = static_cast<float>(iter->fraction_lost) / 256; | 3226 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; |
3292 // Convert samples to milliseconds. | 3227 // Convert samples to milliseconds. |
3293 if (codec.plfreq / 1000 > 0) { | 3228 if (codec.plfreq / 1000 > 0) { |
3294 sinfo.jitter_ms = iter->interarrival_jitter / (codec.plfreq / 1000); | 3229 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); |
3295 } | 3230 } |
3296 sinfo.packets_lost = iter->cumulative_num_packets_lost; | 3231 sinfo.packets_lost = block.cumulative_num_packets_lost; |
3297 sinfo.ext_seqnum = iter->extended_highest_sequence_number; | 3232 sinfo.ext_seqnum = block.extended_highest_sequence_number; |
3298 break; | 3233 break; |
3299 } | 3234 } |
3300 } | 3235 } |
3301 } | 3236 } |
3302 | 3237 |
3303 // Local speech level. | 3238 // Local speech level. |
3304 sinfo.audio_level = (engine()->voe()->volume()-> | 3239 sinfo.audio_level = (engine()->voe()->volume()-> |
3305 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; | 3240 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; |
3306 | 3241 |
3307 // TODO(xians): We are injecting the same APM logging to all the send | 3242 // TODO(xians): We are injecting the same APM logging to all the send |
3308 // channels here because there is no good way to know which send channel | 3243 // channels here because there is no good way to know which send channel |
3309 // is using the APM. The correct fix is to allow the send channels to have | 3244 // is using the APM. The correct fix is to allow the send channels to have |
3310 // their own APM so that we can feed the correct APM logging to different | 3245 // their own APM so that we can feed the correct APM logging to different |
3311 // send channels. See issue crbug/264611 . | 3246 // send channels. See issue crbug/264611 . |
3312 sinfo.echo_return_loss = echo_return_loss; | 3247 sinfo.echo_return_loss = echo_return_loss; |
3313 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; | 3248 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; |
3314 sinfo.echo_delay_median_ms = echo_delay_median_ms; | 3249 sinfo.echo_delay_median_ms = echo_delay_median_ms; |
3315 sinfo.echo_delay_std_ms = echo_delay_std_ms; | 3250 sinfo.echo_delay_std_ms = echo_delay_std_ms; |
3316 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | 3251 // TODO(ajm): Re-enable this metric once we have a reliable implementation. |
3317 sinfo.aec_quality_min = -1; | 3252 sinfo.aec_quality_min = -1; |
3318 sinfo.typing_noise_detected = typing_noise_detected_; | 3253 sinfo.typing_noise_detected = typing_noise_detected_; |
3319 | 3254 |
3320 info->senders.push_back(sinfo); | 3255 info->senders.push_back(sinfo); |
3321 } | 3256 } |
3322 | 3257 |
3323 // Build the list of receivers, one for each receiving channel, or 1 in | 3258 // Build the list of receivers, one for each receiving channel, or 1 in |
3324 // a 1:1 call. | 3259 // a 1:1 call. |
3325 std::vector<int> channels; | 3260 std::vector<int> channels; |
3326 for (ChannelMap::const_iterator it = receive_channels_.begin(); | 3261 for (const auto& ch : receive_channels_) { |
3327 it != receive_channels_.end(); ++it) { | 3262 channels.push_back(ch.second->channel()); |
3328 channels.push_back(it->second->channel()); | |
3329 } | 3263 } |
3330 if (channels.empty()) { | 3264 if (channels.empty()) { |
3331 channels.push_back(voe_channel()); | 3265 channels.push_back(voe_channel()); |
3332 } | 3266 } |
3333 | 3267 |
3334 // Get the SSRC and stats for each receiver, based on our own calculations. | 3268 // Get the SSRC and stats for each receiver, based on our own calculations. |
3335 for (std::vector<int>::const_iterator it = channels.begin(); | 3269 for (int ch_id : channels) { |
3336 it != channels.end(); ++it) { | |
3337 memset(&cs, 0, sizeof(cs)); | 3270 memset(&cs, 0, sizeof(cs)); |
3338 if (engine()->voe()->rtp()->GetRemoteSSRC(*it, ssrc) != -1 && | 3271 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && |
3339 engine()->voe()->rtp()->GetRTCPStatistics(*it, cs) != -1 && | 3272 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && |
3340 engine()->voe()->codec()->GetRecCodec(*it, codec) != -1) { | 3273 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { |
3341 VoiceReceiverInfo rinfo; | 3274 VoiceReceiverInfo rinfo; |
3342 rinfo.add_ssrc(ssrc); | 3275 rinfo.add_ssrc(ssrc); |
3343 rinfo.bytes_rcvd = cs.bytesReceived; | 3276 rinfo.bytes_rcvd = cs.bytesReceived; |
3344 rinfo.packets_rcvd = cs.packetsReceived; | 3277 rinfo.packets_rcvd = cs.packetsReceived; |
3345 // The next four fields are from the most recently sent RTCP report. | 3278 // The next four fields are from the most recently sent RTCP report. |
3346 // Convert Q8 to floating point. | 3279 // Convert Q8 to floating point. |
3347 rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); | 3280 rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); |
3348 rinfo.packets_lost = cs.cumulativeLost; | 3281 rinfo.packets_lost = cs.cumulativeLost; |
3349 rinfo.ext_seqnum = cs.extendedMax; | 3282 rinfo.ext_seqnum = cs.extendedMax; |
3350 rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; | 3283 rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; |
3351 if (codec.pltype != -1) { | 3284 if (codec.pltype != -1) { |
3352 rinfo.codec_name = codec.plname; | 3285 rinfo.codec_name = codec.plname; |
3353 } | 3286 } |
3354 // Convert samples to milliseconds. | 3287 // Convert samples to milliseconds. |
3355 if (codec.plfreq / 1000 > 0) { | 3288 if (codec.plfreq / 1000 > 0) { |
3356 rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); | 3289 rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); |
3357 } | 3290 } |
3358 | 3291 |
3359 // Get jitter buffer and total delay (alg + jitter + playout) stats. | 3292 // Get jitter buffer and total delay (alg + jitter + playout) stats. |
3360 webrtc::NetworkStatistics ns; | 3293 webrtc::NetworkStatistics ns; |
3361 if (engine()->voe()->neteq() && | 3294 if (engine()->voe()->neteq() && |
3362 engine()->voe()->neteq()->GetNetworkStatistics( | 3295 engine()->voe()->neteq()->GetNetworkStatistics( |
3363 *it, ns) != -1) { | 3296 ch_id, ns) != -1) { |
3364 rinfo.jitter_buffer_ms = ns.currentBufferSize; | 3297 rinfo.jitter_buffer_ms = ns.currentBufferSize; |
3365 rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; | 3298 rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; |
3366 rinfo.expand_rate = | 3299 rinfo.expand_rate = |
3367 static_cast<float>(ns.currentExpandRate) / (1 << 14); | 3300 static_cast<float>(ns.currentExpandRate) / (1 << 14); |
3368 rinfo.speech_expand_rate = | 3301 rinfo.speech_expand_rate = |
3369 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14); | 3302 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14); |
3370 rinfo.secondary_decoded_rate = | 3303 rinfo.secondary_decoded_rate = |
3371 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14); | 3304 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14); |
3372 rinfo.accelerate_rate = | 3305 rinfo.accelerate_rate = |
3373 static_cast<float>(ns.currentAccelerateRate) / (1 << 14); | 3306 static_cast<float>(ns.currentAccelerateRate) / (1 << 14); |
3374 rinfo.preemptive_expand_rate = | 3307 rinfo.preemptive_expand_rate = |
3375 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14); | 3308 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14); |
3376 } | 3309 } |
3377 | 3310 |
3378 webrtc::AudioDecodingCallStats ds; | 3311 webrtc::AudioDecodingCallStats ds; |
3379 if (engine()->voe()->neteq() && | 3312 if (engine()->voe()->neteq() && |
3380 engine()->voe()->neteq()->GetDecodingCallStatistics( | 3313 engine()->voe()->neteq()->GetDecodingCallStatistics( |
3381 *it, &ds) != -1) { | 3314 ch_id, &ds) != -1) { |
3382 rinfo.decoding_calls_to_silence_generator = | 3315 rinfo.decoding_calls_to_silence_generator = |
3383 ds.calls_to_silence_generator; | 3316 ds.calls_to_silence_generator; |
3384 rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; | 3317 rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; |
3385 rinfo.decoding_normal = ds.decoded_normal; | 3318 rinfo.decoding_normal = ds.decoded_normal; |
3386 rinfo.decoding_plc = ds.decoded_plc; | 3319 rinfo.decoding_plc = ds.decoded_plc; |
3387 rinfo.decoding_cng = ds.decoded_cng; | 3320 rinfo.decoding_cng = ds.decoded_cng; |
3388 rinfo.decoding_plc_cng = ds.decoded_plc_cng; | 3321 rinfo.decoding_plc_cng = ds.decoded_plc_cng; |
3389 } | 3322 } |
3390 | 3323 |
3391 if (engine()->voe()->sync()) { | 3324 if (engine()->voe()->sync()) { |
3392 int jitter_buffer_delay_ms = 0; | 3325 int jitter_buffer_delay_ms = 0; |
3393 int playout_buffer_delay_ms = 0; | 3326 int playout_buffer_delay_ms = 0; |
3394 engine()->voe()->sync()->GetDelayEstimate( | 3327 engine()->voe()->sync()->GetDelayEstimate( |
3395 *it, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); | 3328 ch_id, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); |
3396 rinfo.delay_estimate_ms = jitter_buffer_delay_ms + | 3329 rinfo.delay_estimate_ms = jitter_buffer_delay_ms + |
3397 playout_buffer_delay_ms; | 3330 playout_buffer_delay_ms; |
3398 } | 3331 } |
3399 | 3332 |
3400 // Get speech level. | 3333 // Get speech level. |
3401 rinfo.audio_level = (engine()->voe()->volume()-> | 3334 rinfo.audio_level = (engine()->voe()->volume()-> |
3402 GetSpeechOutputLevelFullRange(*it, level) != -1) ? level : -1; | 3335 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; |
3403 info->receivers.push_back(rinfo); | 3336 info->receivers.push_back(rinfo); |
3404 } | 3337 } |
3405 } | 3338 } |
3406 | 3339 |
3407 return true; | 3340 return true; |
3408 } | 3341 } |
3409 | 3342 |
3410 void WebRtcVoiceMediaChannel::GetLastMediaError( | 3343 void WebRtcVoiceMediaChannel::GetLastMediaError( |
3411 uint32* ssrc, VoiceMediaChannel::Error* error) { | 3344 uint32* ssrc, VoiceMediaChannel::Error* error) { |
3412 DCHECK(ssrc != NULL); | 3345 DCHECK(ssrc != NULL); |
3413 DCHECK(error != NULL); | 3346 DCHECK(error != NULL); |
3414 FindSsrc(voe_channel(), ssrc); | 3347 FindSsrc(voe_channel(), ssrc); |
3415 *error = WebRtcErrorToChannelError(GetLastEngineError()); | 3348 *error = WebRtcErrorToChannelError(GetLastEngineError()); |
3416 } | 3349 } |
3417 | 3350 |
3418 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { | 3351 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { |
3419 rtc::CritScope lock(&receive_channels_cs_); | 3352 rtc::CritScope lock(&receive_channels_cs_); |
3420 DCHECK(ssrc != NULL); | 3353 DCHECK(ssrc != NULL); |
3421 if (channel_num == -1 && send_ != SEND_NOTHING) { | 3354 if (channel_num == -1 && send_ != SEND_NOTHING) { |
3422 // Sometimes the VoiceEngine core will throw error with channel_num = -1. | 3355 // Sometimes the VoiceEngine core will throw error with channel_num = -1. |
3423 // This means the error is not limited to a specific channel. Signal the | 3356 // This means the error is not limited to a specific channel. Signal the |
3424 // message using ssrc=0. If the current channel is sending, use this | 3357 // message using ssrc=0. If the current channel is sending, use this |
3425 // channel for sending the message. | 3358 // channel for sending the message. |
3426 *ssrc = 0; | 3359 *ssrc = 0; |
3427 return true; | 3360 return true; |
3428 } else { | 3361 } else { |
3429 // Check whether this is a sending channel. | 3362 // Check whether this is a sending channel. |
3430 for (ChannelMap::const_iterator it = send_channels_.begin(); | 3363 for (const auto& ch : send_channels_) { |
3431 it != send_channels_.end(); ++it) { | 3364 if (ch.second->channel() == channel_num) { |
3432 if (it->second->channel() == channel_num) { | |
3433 // This is a sending channel. | 3365 // This is a sending channel. |
3434 uint32 local_ssrc = 0; | 3366 uint32 local_ssrc = 0; |
3435 if (engine()->voe()->rtp()->GetLocalSSRC( | 3367 if (engine()->voe()->rtp()->GetLocalSSRC( |
3436 channel_num, local_ssrc) != -1) { | 3368 channel_num, local_ssrc) != -1) { |
3437 *ssrc = local_ssrc; | 3369 *ssrc = local_ssrc; |
3438 } | 3370 } |
3439 return true; | 3371 return true; |
3440 } | 3372 } |
3441 } | 3373 } |
3442 | 3374 |
3443 // Check whether this is a receiving channel. | 3375 // Check whether this is a receiving channel. |
3444 for (ChannelMap::const_iterator it = receive_channels_.begin(); | 3376 for (const auto& ch : receive_channels_) { |
3445 it != receive_channels_.end(); ++it) { | 3377 if (ch.second->channel() == channel_num) { |
3446 if (it->second->channel() == channel_num) { | 3378 *ssrc = ch.first; |
3447 *ssrc = it->first; | |
3448 return true; | 3379 return true; |
3449 } | 3380 } |
3450 } | 3381 } |
3451 } | 3382 } |
3452 return false; | 3383 return false; |
3453 } | 3384 } |
3454 | 3385 |
3455 void WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) { | 3386 void WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) { |
3456 if (error == VE_TYPING_NOISE_WARNING) { | 3387 if (error == VE_TYPING_NOISE_WARNING) { |
3457 typing_noise_detected_ = true; | 3388 typing_noise_detected_ = true; |
3458 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { | 3389 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { |
3459 typing_noise_detected_ = false; | 3390 typing_noise_detected_ = false; |
3460 } | 3391 } |
3461 SignalMediaError(ssrc, WebRtcErrorToChannelError(error)); | 3392 SignalMediaError(ssrc, WebRtcErrorToChannelError(error)); |
3462 } | 3393 } |
3463 | 3394 |
3464 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 3395 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
3465 unsigned int ulevel; | 3396 unsigned int ulevel; |
3466 int ret = | 3397 int ret = |
3467 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 3398 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
3468 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 3399 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
3469 } | 3400 } |
3470 | 3401 |
3471 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) { | 3402 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { |
3472 ChannelMap::iterator it = receive_channels_.find(ssrc); | 3403 ChannelMap::const_iterator it = receive_channels_.find(ssrc); |
3473 if (it != receive_channels_.end()) | 3404 if (it != receive_channels_.end()) |
3474 return it->second->channel(); | 3405 return it->second->channel(); |
3475 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; | 3406 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; |
3476 } | 3407 } |
3477 | 3408 |
3478 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) { | 3409 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { |
3479 ChannelMap::iterator it = send_channels_.find(ssrc); | 3410 ChannelMap::const_iterator it = send_channels_.find(ssrc); |
3480 if (it != send_channels_.end()) | 3411 if (it != send_channels_.end()) |
3481 return it->second->channel(); | 3412 return it->second->channel(); |
3482 | 3413 |
3483 return -1; | 3414 return -1; |
3484 } | 3415 } |
3485 | 3416 |
3486 void WebRtcVoiceMediaChannel::SetCall(webrtc::Call* call) { | 3417 void WebRtcVoiceMediaChannel::SetCall(webrtc::Call* call) { |
3487 DCHECK(thread_checker_.CalledOnValidThread()); | 3418 DCHECK(thread_checker_.CalledOnValidThread()); |
3488 for (const auto& it : receive_channels_) { | 3419 for (const auto& it : receive_channels_) { |
3489 TryRemoveAudioRecvStream(it.first); | 3420 TryRemoveAudioRecvStream(it.first); |
(...skipping 26 matching lines...) Expand all Loading... |
3516 return false; | 3447 return false; |
3517 } | 3448 } |
3518 } else if (red_codec.params.empty()) { | 3449 } else if (red_codec.params.empty()) { |
3519 LOG(LS_WARNING) << "RED params not present, using defaults"; | 3450 LOG(LS_WARNING) << "RED params not present, using defaults"; |
3520 if (all_codecs.size() > 1) { | 3451 if (all_codecs.size() > 1) { |
3521 red_pt = all_codecs[1].id; | 3452 red_pt = all_codecs[1].id; |
3522 } | 3453 } |
3523 } | 3454 } |
3524 | 3455 |
3525 // Try to find red_pt in |codecs|. | 3456 // Try to find red_pt in |codecs|. |
3526 std::vector<AudioCodec>::const_iterator codec; | 3457 for (const AudioCodec& codec : all_codecs) { |
3527 for (codec = all_codecs.begin(); codec != all_codecs.end(); ++codec) { | 3458 if (codec.id == red_pt) { |
3528 if (codec->id == red_pt) | 3459 // If we find the right codec, that will be the codec we pass to |
3529 break; | 3460 // SetSendCodec, with the desired payload type. |
| 3461 if (engine()->FindWebRtcCodec(codec, send_codec)) { |
| 3462 return true; |
| 3463 } else { |
| 3464 break; |
| 3465 } |
| 3466 } |
3530 } | 3467 } |
3531 | 3468 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; |
3532 // If we find the right codec, that will be the codec we pass to | 3469 return false; |
3533 // SetSendCodec, with the desired payload type. | |
3534 if (codec != all_codecs.end() && | |
3535 engine()->FindWebRtcCodec(*codec, send_codec)) { | |
3536 } else { | |
3537 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; | |
3538 return false; | |
3539 } | |
3540 | |
3541 return true; | |
3542 } | 3470 } |
3543 | 3471 |
3544 bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { | 3472 bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { |
3545 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { | 3473 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { |
3546 LOG_RTCERR2(SetRTCPStatus, channel, 1); | 3474 LOG_RTCERR2(SetRTCPStatus, channel, 1); |
3547 return false; | 3475 return false; |
3548 } | 3476 } |
3549 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what | 3477 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what |
3550 // what we want to do with them. | 3478 // what we want to do with them. |
3551 // engine()->voe().EnableVQMon(voe_channel(), true); | 3479 // engine()->voe().EnableVQMon(voe_channel(), true); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3670 // AudioReceiveStream to destroy too. | 3598 // AudioReceiveStream to destroy too. |
3671 if (call_) { | 3599 if (call_) { |
3672 auto stream_it = receive_streams_.find(ssrc); | 3600 auto stream_it = receive_streams_.find(ssrc); |
3673 if (stream_it != receive_streams_.end()) { | 3601 if (stream_it != receive_streams_.end()) { |
3674 call_->DestroyAudioReceiveStream(stream_it->second); | 3602 call_->DestroyAudioReceiveStream(stream_it->second); |
3675 receive_streams_.erase(stream_it); | 3603 receive_streams_.erase(stream_it); |
3676 } | 3604 } |
3677 } | 3605 } |
3678 } | 3606 } |
3679 | 3607 |
| 3608 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( |
| 3609 const std::vector<AudioCodec>& new_codecs) { |
| 3610 for (const AudioCodec& codec : new_codecs) { |
| 3611 webrtc::CodecInst voe_codec; |
| 3612 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
| 3613 LOG(LS_INFO) << ToString(codec); |
| 3614 voe_codec.pltype = codec.id; |
| 3615 if (default_receive_ssrc_ == 0) { |
| 3616 // Set the receive codecs on the default channel explicitly if the |
| 3617 // default channel is not used by |receive_channels_|, this happens in |
| 3618 // conference mode or in non-conference mode when there is no playout |
| 3619 // channel. |
| 3620 // TODO(xians): Figure out how we use the default channel in conference |
| 3621 // mode. |
| 3622 if (engine()->voe()->codec()->SetRecPayloadType( |
| 3623 voe_channel(), voe_codec) == -1) { |
| 3624 LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec)); |
| 3625 return false; |
| 3626 } |
| 3627 } |
| 3628 |
| 3629 // Set the receive codecs on all receiving channels. |
| 3630 for (const auto& ch : receive_channels_) { |
| 3631 if (engine()->voe()->codec()->SetRecPayloadType( |
| 3632 ch.second->channel(), voe_codec) == -1) { |
| 3633 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), |
| 3634 ToString(voe_codec)); |
| 3635 return false; |
| 3636 } |
| 3637 } |
| 3638 } else { |
| 3639 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 3640 return false; |
| 3641 } |
| 3642 } |
| 3643 return true; |
| 3644 } |
| 3645 |
3680 int WebRtcSoundclipStream::Read(void *buf, size_t len) { | 3646 int WebRtcSoundclipStream::Read(void *buf, size_t len) { |
3681 size_t res = 0; | 3647 size_t res = 0; |
3682 mem_.Read(buf, len, &res, NULL); | 3648 mem_.Read(buf, len, &res, NULL); |
3683 return static_cast<int>(res); | 3649 return static_cast<int>(res); |
3684 } | 3650 } |
3685 | 3651 |
3686 int WebRtcSoundclipStream::Rewind() { | 3652 int WebRtcSoundclipStream::Rewind() { |
3687 mem_.Rewind(); | 3653 mem_.Rewind(); |
3688 // Return -1 to keep VoiceEngine from looping. | 3654 // Return -1 to keep VoiceEngine from looping. |
3689 return (loop_) ? 0 : -1; | 3655 return (loop_) ? 0 : -1; |
3690 } | 3656 } |
3691 | 3657 |
3692 } // namespace cricket | 3658 } // namespace cricket |
3693 | 3659 |
3694 #endif // HAVE_WEBRTC_VOICE | 3660 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |