OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1151 RTC_DCHECK(call); | 1151 RTC_DCHECK(call); |
1152 audio_capture_thread_checker_.DetachFromThread(); | 1152 audio_capture_thread_checker_.DetachFromThread(); |
1153 config_.rtp.ssrc = ssrc; | 1153 config_.rtp.ssrc = ssrc; |
1154 config_.rtp.c_name = c_name; | 1154 config_.rtp.c_name = c_name; |
1155 config_.voe_channel_id = ch; | 1155 config_.voe_channel_id = ch; |
1156 RecreateAudioSendStream(extensions); | 1156 RecreateAudioSendStream(extensions); |
1157 } | 1157 } |
1158 | 1158 |
1159 ~WebRtcAudioSendStream() override { | 1159 ~WebRtcAudioSendStream() override { |
1160 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1160 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1161 Stop(); | 1161 StopRendering(); |
1162 call_->DestroyAudioSendStream(stream_); | 1162 call_->DestroyAudioSendStream(stream_); |
1163 } | 1163 } |
1164 | 1164 |
1165 void RecreateAudioSendStream( | 1165 void RecreateAudioSendStream( |
1166 const std::vector<webrtc::RtpExtension>& extensions) { | 1166 const std::vector<webrtc::RtpExtension>& extensions) { |
1167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1168 if (stream_) { | 1168 if (stream_) { |
1169 call_->DestroyAudioSendStream(stream_); | 1169 call_->DestroyAudioSendStream(stream_); |
1170 stream_ = nullptr; | 1170 stream_ = nullptr; |
1171 } | 1171 } |
1172 config_.rtp.extensions = extensions; | 1172 config_.rtp.extensions = extensions; |
1173 RTC_DCHECK(!stream_); | 1173 RTC_DCHECK(!stream_); |
1174 stream_ = call_->CreateAudioSendStream(config_); | 1174 stream_ = call_->CreateAudioSendStream(config_); |
1175 RTC_CHECK(stream_); | 1175 RTC_CHECK(stream_); |
1176 } | 1176 } |
1177 | 1177 |
1178 bool SendTelephoneEvent(int payload_type, uint8_t event, | 1178 bool SendTelephoneEvent(int payload_type, uint8_t event, |
1179 uint32_t duration_ms) { | 1179 uint32_t duration_ms) { |
1180 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1180 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1181 RTC_DCHECK(stream_); | 1181 RTC_DCHECK(stream_); |
1182 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); | 1182 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); |
1183 } | 1183 } |
1184 | 1184 |
1185 webrtc::AudioSendStream::Stats GetStats() const { | 1185 webrtc::AudioSendStream::Stats GetStats() const { |
1186 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1186 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1187 RTC_DCHECK(stream_); | 1187 RTC_DCHECK(stream_); |
1188 return stream_->GetStats(); | 1188 return stream_->GetStats(); |
1189 } | 1189 } |
1190 | 1190 |
1191 bool IsRendering() const { | |
1192 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1193 return renderer_ != nullptr; | |
1194 } | |
1195 | |
1191 // Starts the rendering by setting a sink to the renderer to get data | 1196 // Starts the rendering by setting a sink to the renderer to get data |
1192 // callback. | 1197 // callback. |
1193 // This method is called on the libjingle worker thread. | 1198 // This method is called on the libjingle worker thread. |
1194 // TODO(xians): Make sure Start() is called only once. | 1199 // TODO(xians): Make sure Start() is called only once. |
1195 void Start(AudioRenderer* renderer) { | 1200 void StartRendering(AudioRenderer* renderer) { |
pthatcher1
2016/03/02 22:18:40
Since the AudioRenderer is really acting as a sour
Taylor Brandstetter
2016/03/03 00:45:03
I agree. I renamed it in a new patch, though it do
| |
1196 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1201 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1197 RTC_DCHECK(renderer); | 1202 RTC_DCHECK(renderer); |
1198 if (renderer_) { | 1203 if (renderer_) { |
1199 RTC_DCHECK(renderer_ == renderer); | 1204 RTC_DCHECK(renderer_ == renderer); |
1200 return; | 1205 return; |
1201 } | 1206 } |
1202 renderer->SetSink(this); | 1207 renderer->SetSink(this); |
1203 renderer_ = renderer; | 1208 renderer_ = renderer; |
1204 } | 1209 } |
1205 | 1210 |
1206 // Stops rendering by setting the sink of the renderer to nullptr. No data | 1211 // Stops rendering by setting the sink of the renderer to nullptr. No data |
1207 // callback will be received after this method. | 1212 // callback will be received after this method. |
1208 // This method is called on the libjingle worker thread. | 1213 // This method is called on the libjingle worker thread. |
1209 void Stop() { | 1214 void StopRendering() { |
1210 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1215 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1211 if (renderer_) { | 1216 if (renderer_) { |
1212 renderer_->SetSink(nullptr); | 1217 renderer_->SetSink(nullptr); |
1213 renderer_ = nullptr; | 1218 renderer_ = nullptr; |
1214 } | 1219 } |
1215 } | 1220 } |
1216 | 1221 |
1217 // AudioRenderer::Sink implementation. | 1222 // AudioRenderer::Sink implementation. |
1218 // This method is called on the audio thread. | 1223 // This method is called on the audio thread. |
1219 void OnData(const void* audio_data, | 1224 void OnData(const void* audio_data, |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1798 << ch.second->channel() << " failed"; | 1803 << ch.second->channel() << " failed"; |
1799 return false; | 1804 return false; |
1800 } | 1805 } |
1801 } | 1806 } |
1802 playout_ = playout; | 1807 playout_ = playout; |
1803 return true; | 1808 return true; |
1804 } | 1809 } |
1805 | 1810 |
1806 bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) { | 1811 bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) { |
1807 desired_send_ = send; | 1812 desired_send_ = send; |
1808 if (!send_streams_.empty()) { | 1813 if (send_streams_.empty()) { |
1814 send_ = send; | |
pthatcher1
2016/03/02 22:18:40
Why do we have desired_send_ and send_? Can't we
Taylor Brandstetter
2016/03/03 00:45:03
For PauseSend/ResumeSend below. Though if Hangouts
| |
1815 } else { | |
1809 return ChangeSend(desired_send_); | 1816 return ChangeSend(desired_send_); |
1810 } | 1817 } |
1811 return true; | 1818 return true; |
1812 } | 1819 } |
1813 | 1820 |
1814 bool WebRtcVoiceMediaChannel::PauseSend() { | 1821 bool WebRtcVoiceMediaChannel::PauseSend() { |
1815 return ChangeSend(SEND_NOTHING); | 1822 return ChangeSend(SEND_NOTHING); |
1816 } | 1823 } |
1817 | 1824 |
1818 bool WebRtcVoiceMediaChannel::ResumeSend() { | 1825 bool WebRtcVoiceMediaChannel::ResumeSend() { |
1819 return ChangeSend(desired_send_); | 1826 return ChangeSend(desired_send_); |
1820 } | 1827 } |
1821 | 1828 |
1822 bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) { | 1829 bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) { |
1823 if (send_ == send) { | 1830 if (send_ == send) { |
1824 return true; | 1831 return true; |
1825 } | 1832 } |
1826 | 1833 |
1827 // Apply channel specific options when channel is enabled for sending. | 1834 // Apply channel specific options when channel is enabled for sending. |
1828 if (send == SEND_MICROPHONE) { | 1835 if (send == SEND_MICROPHONE) { |
1829 engine()->ApplyOptions(options_); | 1836 engine()->ApplyOptions(options_); |
1830 } | 1837 } |
1831 | 1838 |
1832 // Change the settings on each send channel. | 1839 // Change the settings on each send channel. |
1833 for (const auto& ch : send_streams_) { | 1840 for (const auto& kv : send_streams_) { |
1834 if (!ChangeSend(ch.second->channel(), send)) { | 1841 if (!UpdateChannelSendState(kv.first, send)) { |
pthatcher1
2016/03/02 22:18:39
This requires a lookup for every entry while we're
Taylor Brandstetter
2016/03/03 00:45:03
Just as an optimization, you mean? I really don't
| |
1835 return false; | 1842 return false; |
1836 } | 1843 } |
1837 } | 1844 } |
1838 | 1845 |
1839 send_ = send; | 1846 send_ = send; |
1840 return true; | 1847 return true; |
1841 } | 1848 } |
1842 | 1849 |
1843 bool WebRtcVoiceMediaChannel::ChangeSend(int channel, SendFlags send) { | 1850 bool WebRtcVoiceMediaChannel::UpdateChannelSendState(uint32_t ssrc, |
1844 if (send == SEND_MICROPHONE) { | 1851 SendFlags send) { |
1852 RTC_DCHECK(send == SEND_NOTHING || send == SEND_MICROPHONE); | |
1853 | |
1854 auto it = send_streams_.find(ssrc); | |
1855 if (it == send_streams_.end()) { | |
1856 RTC_DCHECK(false && "UpdateChannelSendState called with invalid SSRC."); | |
1857 return false; | |
1858 } | |
1859 | |
1860 int channel = it->second->channel(); | |
1861 if (send == SEND_MICROPHONE && it->second->IsRendering()) { | |
pthatcher1
2016/03/02 22:18:39
Yeah, this would be a lot easier to read:
send ==
Taylor Brandstetter
2016/03/03 00:45:03
Done.
| |
1845 if (engine()->voe()->base()->StartSend(channel) == -1) { | 1862 if (engine()->voe()->base()->StartSend(channel) == -1) { |
1846 LOG_RTCERR1(StartSend, channel); | 1863 LOG_RTCERR1(StartSend, channel); |
1847 return false; | 1864 return false; |
1848 } | 1865 } |
1849 } else { // SEND_NOTHING | 1866 } else { // SEND_NOTHING || !it->second->IsRendering() |
1850 RTC_DCHECK(send == SEND_NOTHING); | |
1851 if (engine()->voe()->base()->StopSend(channel) == -1) { | 1867 if (engine()->voe()->base()->StopSend(channel) == -1) { |
1852 LOG_RTCERR1(StopSend, channel); | 1868 LOG_RTCERR1(StopSend, channel); |
1853 return false; | 1869 return false; |
1854 } | 1870 } |
1855 } | 1871 } |
1856 | 1872 |
1857 return true; | 1873 return true; |
1858 } | 1874 } |
1859 | 1875 |
1860 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc, | 1876 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc, |
1861 bool enable, | 1877 bool enable, |
1862 const AudioOptions* options, | 1878 const AudioOptions* options, |
1863 AudioRenderer* renderer) { | 1879 AudioRenderer* renderer) { |
1864 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1880 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1865 // TODO(solenberg): The state change should be fully rolled back if any one of | 1881 // TODO(solenberg): The state change should be fully rolled back if any one of |
1866 // these calls fail. | 1882 // these calls fail. |
1867 if (!SetLocalRenderer(ssrc, renderer)) { | 1883 if (!SetLocalRenderer(ssrc, renderer)) { |
1868 return false; | 1884 return false; |
1869 } | 1885 } |
1870 if (!MuteStream(ssrc, !enable)) { | 1886 if (!MuteStream(ssrc, !enable)) { |
1871 return false; | 1887 return false; |
1872 } | 1888 } |
1889 // If the renderer was set or unset we may need to update the sending | |
1890 // state of the voe::Channel. | |
pthatcher1
2016/03/02 22:18:40
And this would be a lot more clear as well:
"If
Taylor Brandstetter
2016/03/03 00:45:03
Done.
| |
1891 if (!UpdateChannelSendState(ssrc, send_)) { | |
1892 return false; | |
1893 } | |
1873 if (enable && options) { | 1894 if (enable && options) { |
1874 return SetOptions(*options); | 1895 return SetOptions(*options); |
1875 } | 1896 } |
1876 return true; | 1897 return true; |
1877 } | 1898 } |
1878 | 1899 |
1879 int WebRtcVoiceMediaChannel::CreateVoEChannel() { | 1900 int WebRtcVoiceMediaChannel::CreateVoEChannel() { |
1880 int id = engine()->CreateVoEChannel(); | 1901 int id = engine()->CreateVoEChannel(); |
1881 if (id == -1) { | 1902 if (id == -1) { |
1882 LOG_RTCERR0(CreateVoEChannel); | 1903 LOG_RTCERR0(CreateVoEChannel); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1944 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { | 1965 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { |
1945 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc); | 1966 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc); |
1946 return false; | 1967 return false; |
1947 } | 1968 } |
1948 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); | 1969 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); |
1949 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel | 1970 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel |
1950 << " is associated with channel #" << channel << "."; | 1971 << " is associated with channel #" << channel << "."; |
1951 } | 1972 } |
1952 } | 1973 } |
1953 | 1974 |
1954 return ChangeSend(channel, desired_send_); | 1975 return UpdateChannelSendState(ssrc, send_); |
1955 } | 1976 } |
1956 | 1977 |
1957 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { | 1978 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { |
1958 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1979 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1959 LOG(LS_INFO) << "RemoveSendStream: " << ssrc; | 1980 LOG(LS_INFO) << "RemoveSendStream: " << ssrc; |
1960 | 1981 |
1961 auto it = send_streams_.find(ssrc); | 1982 auto it = send_streams_.find(ssrc); |
1962 if (it == send_streams_.end()) { | 1983 if (it == send_streams_.end()) { |
1963 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 1984 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
1964 << " which doesn't exist."; | 1985 << " which doesn't exist."; |
1965 return false; | 1986 return false; |
1966 } | 1987 } |
1967 | 1988 |
1968 int channel = it->second->channel(); | 1989 UpdateChannelSendState(ssrc, SEND_NOTHING); |
1969 ChangeSend(channel, SEND_NOTHING); | |
1970 | 1990 |
1971 // Clean up and delete the send stream+channel. | 1991 // Clean up and delete the send stream+channel. |
1992 int channel = it->second->channel(); | |
1972 LOG(LS_INFO) << "Removing audio send stream " << ssrc | 1993 LOG(LS_INFO) << "Removing audio send stream " << ssrc |
1973 << " with VoiceEngine channel #" << channel << "."; | 1994 << " with VoiceEngine channel #" << channel << "."; |
1974 delete it->second; | 1995 delete it->second; |
1975 send_streams_.erase(it); | 1996 send_streams_.erase(it); |
1976 if (!DeleteVoEChannel(channel)) { | 1997 if (!DeleteVoEChannel(channel)) { |
1977 return false; | 1998 return false; |
1978 } | 1999 } |
1979 if (send_streams_.empty()) { | 2000 if (send_streams_.empty()) { |
1980 ChangeSend(SEND_NOTHING); | 2001 ChangeSend(SEND_NOTHING); |
1981 } | 2002 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2082 // Clean up and delete the receive stream+channel. | 2103 // Clean up and delete the receive stream+channel. |
2083 LOG(LS_INFO) << "Removing audio receive stream " << ssrc | 2104 LOG(LS_INFO) << "Removing audio receive stream " << ssrc |
2084 << " with VoiceEngine channel #" << channel << "."; | 2105 << " with VoiceEngine channel #" << channel << "."; |
2085 it->second->SetRawAudioSink(nullptr); | 2106 it->second->SetRawAudioSink(nullptr); |
2086 delete it->second; | 2107 delete it->second; |
2087 recv_streams_.erase(it); | 2108 recv_streams_.erase(it); |
2088 return DeleteVoEChannel(channel); | 2109 return DeleteVoEChannel(channel); |
2089 } | 2110 } |
2090 | 2111 |
2091 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, | 2112 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, |
2092 AudioRenderer* renderer) { | 2113 AudioRenderer* renderer) { |
pthatcher1
2016/03/02 22:18:39
Here, too, calling it SetSource, would be a lot ni
Taylor Brandstetter
2016/03/03 00:45:03
Done.
| |
2093 auto it = send_streams_.find(ssrc); | 2114 auto it = send_streams_.find(ssrc); |
2094 if (it == send_streams_.end()) { | 2115 if (it == send_streams_.end()) { |
2095 if (renderer) { | 2116 if (renderer) { |
2096 // Return an error if trying to set a valid renderer with an invalid ssrc. | 2117 // Return an error if trying to set a valid renderer with an invalid ssrc. |
2097 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; | 2118 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; |
2098 return false; | 2119 return false; |
2099 } | 2120 } |
2100 | 2121 |
2101 // The channel likely has gone away, do nothing. | 2122 // The channel likely has gone away, do nothing. |
2102 return true; | 2123 return true; |
2103 } | 2124 } |
2104 | 2125 |
2105 if (renderer) { | 2126 if (renderer) { |
2106 it->second->Start(renderer); | 2127 it->second->StartRendering(renderer); |
2107 } else { | 2128 } else { |
2108 it->second->Stop(); | 2129 it->second->StopRendering(); |
2109 } | 2130 } |
2110 | 2131 |
2111 return true; | 2132 return true; |
2112 } | 2133 } |
2113 | 2134 |
2114 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2135 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2115 AudioInfo::StreamList* actives) { | 2136 AudioInfo::StreamList* actives) { |
2116 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2137 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2117 actives->clear(); | 2138 actives->clear(); |
2118 for (const auto& ch : recv_streams_) { | 2139 for (const auto& ch : recv_streams_) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2520 } | 2541 } |
2521 } else { | 2542 } else { |
2522 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2543 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2523 engine()->voe()->base()->StopPlayout(channel); | 2544 engine()->voe()->base()->StopPlayout(channel); |
2524 } | 2545 } |
2525 return true; | 2546 return true; |
2526 } | 2547 } |
2527 } // namespace cricket | 2548 } // namespace cricket |
2528 | 2549 |
2529 #endif // HAVE_WEBRTC_VOICE | 2550 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |