Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 1741933002: Prevent a voice channel from sending data before a renderer is set. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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) {
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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 if (send_ == send) { 1828 if (send_ == send) {
1824 return true; 1829 return true;
1825 } 1830 }
1826 1831
1827 // Apply channel specific options when channel is enabled for sending. 1832 // Apply channel specific options when channel is enabled for sending.
1828 if (send == SEND_MICROPHONE) { 1833 if (send == SEND_MICROPHONE) {
1829 engine()->ApplyOptions(options_); 1834 engine()->ApplyOptions(options_);
1830 } 1835 }
1831 1836
1832 // Change the settings on each send channel. 1837 // Change the settings on each send channel.
1833 for (const auto& ch : send_streams_) { 1838 for (const auto& kv : send_streams_) {
1834 if (!ChangeSend(ch.second->channel(), send)) { 1839 if (!UpdateChannelSendState(kv.first, send)) {
1835 return false; 1840 return false;
1836 } 1841 }
1837 } 1842 }
1838 1843
1839 send_ = send; 1844 send_ = send;
1840 return true; 1845 return true;
1841 } 1846 }
1842 1847
1843 bool WebRtcVoiceMediaChannel::ChangeSend(int channel, SendFlags send) { 1848 bool WebRtcVoiceMediaChannel::UpdateChannelSendState(uint32_t ssrc,
1844 if (send == SEND_MICROPHONE) { 1849 SendFlags send) {
1850 RTC_DCHECK(send == SEND_NOTHING || send == SEND_MICROPHONE);
1851
1852 auto it = send_streams_.find(ssrc);
1853 if (it == send_streams_.end()) {
1854 RTC_DCHECK(false && "UpdateChannelSendState called with invalid SSRC.");
1855 return false;
1856 }
1857
1858 int channel = it->second->channel();
1859 if (send == SEND_MICROPHONE && it->second->IsRendering()) {
1845 if (engine()->voe()->base()->StartSend(channel) == -1) { 1860 if (engine()->voe()->base()->StartSend(channel) == -1) {
1846 LOG_RTCERR1(StartSend, channel); 1861 LOG_RTCERR1(StartSend, channel);
1847 return false; 1862 return false;
1848 } 1863 }
1849 } else { // SEND_NOTHING 1864 } else { // SEND_NOTHING || !it->second->IsRendering()
1850 RTC_DCHECK(send == SEND_NOTHING);
1851 if (engine()->voe()->base()->StopSend(channel) == -1) { 1865 if (engine()->voe()->base()->StopSend(channel) == -1) {
1852 LOG_RTCERR1(StopSend, channel); 1866 LOG_RTCERR1(StopSend, channel);
1853 return false; 1867 return false;
1854 } 1868 }
1855 } 1869 }
1856 1870
1857 return true; 1871 return true;
1858 } 1872 }
1859 1873
1860 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc, 1874 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc,
1861 bool enable, 1875 bool enable,
1862 const AudioOptions* options, 1876 const AudioOptions* options,
1863 AudioRenderer* renderer) { 1877 AudioRenderer* renderer) {
1864 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1878 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1865 // TODO(solenberg): The state change should be fully rolled back if any one of 1879 // TODO(solenberg): The state change should be fully rolled back if any one of
1866 // these calls fail. 1880 // these calls fail.
1867 if (!SetLocalRenderer(ssrc, renderer)) { 1881 if (!SetLocalRenderer(ssrc, renderer)) {
1868 return false; 1882 return false;
1869 } 1883 }
1870 if (!MuteStream(ssrc, !enable)) { 1884 if (!MuteStream(ssrc, !enable)) {
1871 return false; 1885 return false;
1872 } 1886 }
1887 // If the renderer was set or unset we may need to update the sending
1888 // state of the voe::Channel.
1889 if (!UpdateChannelSendState(ssrc, send_)) {
1890 return false;
1891 }
1873 if (enable && options) { 1892 if (enable && options) {
1874 return SetOptions(*options); 1893 return SetOptions(*options);
1875 } 1894 }
1876 return true; 1895 return true;
1877 } 1896 }
1878 1897
1879 int WebRtcVoiceMediaChannel::CreateVoEChannel() { 1898 int WebRtcVoiceMediaChannel::CreateVoEChannel() {
1880 int id = engine()->CreateVoEChannel(); 1899 int id = engine()->CreateVoEChannel();
1881 if (id == -1) { 1900 if (id == -1) {
1882 LOG_RTCERR0(CreateVoEChannel); 1901 LOG_RTCERR0(CreateVoEChannel);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { 1963 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) {
1945 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc); 1964 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc);
1946 return false; 1965 return false;
1947 } 1966 }
1948 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); 1967 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel);
1949 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel 1968 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel
1950 << " is associated with channel #" << channel << "."; 1969 << " is associated with channel #" << channel << ".";
1951 } 1970 }
1952 } 1971 }
1953 1972
1954 return ChangeSend(channel, desired_send_); 1973 return UpdateChannelSendState(ssrc, send_);
Taylor Brandstetter 2016/03/02 21:53:53 I changed this from desired_send_ to send_, becaus
1955 } 1974 }
1956 1975
1957 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { 1976 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) {
1958 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1977 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1959 LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 1978 LOG(LS_INFO) << "RemoveSendStream: " << ssrc;
1960 1979
1961 auto it = send_streams_.find(ssrc); 1980 auto it = send_streams_.find(ssrc);
1962 if (it == send_streams_.end()) { 1981 if (it == send_streams_.end()) {
1963 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc 1982 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc
1964 << " which doesn't exist."; 1983 << " which doesn't exist.";
1965 return false; 1984 return false;
1966 } 1985 }
1967 1986
1968 int channel = it->second->channel(); 1987 UpdateChannelSendState(ssrc, SEND_NOTHING);
1969 ChangeSend(channel, SEND_NOTHING);
1970 1988
1971 // Clean up and delete the send stream+channel. 1989 // Clean up and delete the send stream+channel.
1990 int channel = it->second->channel();
1972 LOG(LS_INFO) << "Removing audio send stream " << ssrc 1991 LOG(LS_INFO) << "Removing audio send stream " << ssrc
1973 << " with VoiceEngine channel #" << channel << "."; 1992 << " with VoiceEngine channel #" << channel << ".";
1974 delete it->second; 1993 delete it->second;
1975 send_streams_.erase(it); 1994 send_streams_.erase(it);
1976 if (!DeleteVoEChannel(channel)) { 1995 if (!DeleteVoEChannel(channel)) {
1977 return false; 1996 return false;
1978 } 1997 }
1979 if (send_streams_.empty()) { 1998 if (send_streams_.empty()) {
1980 ChangeSend(SEND_NOTHING); 1999 ChangeSend(SEND_NOTHING);
1981 } 2000 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 // Return an error if trying to set a valid renderer with an invalid ssrc. 2115 // Return an error if trying to set a valid renderer with an invalid ssrc.
2097 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; 2116 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc;
2098 return false; 2117 return false;
2099 } 2118 }
2100 2119
2101 // The channel likely has gone away, do nothing. 2120 // The channel likely has gone away, do nothing.
2102 return true; 2121 return true;
2103 } 2122 }
2104 2123
2105 if (renderer) { 2124 if (renderer) {
2106 it->second->Start(renderer); 2125 it->second->StartRendering(renderer);
2107 } else { 2126 } else {
2108 it->second->Stop(); 2127 it->second->StopRendering();
2109 } 2128 }
2110 2129
2111 return true; 2130 return true;
2112 } 2131 }
2113 2132
2114 bool WebRtcVoiceMediaChannel::GetActiveStreams( 2133 bool WebRtcVoiceMediaChannel::GetActiveStreams(
2115 AudioInfo::StreamList* actives) { 2134 AudioInfo::StreamList* actives) {
2116 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 2135 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2117 actives->clear(); 2136 actives->clear();
2118 for (const auto& ch : recv_streams_) { 2137 for (const auto& ch : recv_streams_) {
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 } 2539 }
2521 } else { 2540 } else {
2522 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 2541 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
2523 engine()->voe()->base()->StopPlayout(channel); 2542 engine()->voe()->base()->StopPlayout(channel);
2524 } 2543 }
2525 return true; 2544 return true;
2526 } 2545 }
2527 } // namespace cricket 2546 } // namespace cricket
2528 2547
2529 #endif // HAVE_WEBRTC_VOICE 2548 #endif // HAVE_WEBRTC_VOICE
OLDNEW
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698